feat: add logger package to improve observability (#437)
* feat: add logger package to improve observability * chore: add LOG_LEVEL to docker compose and readme
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import { env } from "next-runtime-env";
|
||||
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import { createLogger } from "@kan/logger";
|
||||
|
||||
const log = createLogger("notifications");
|
||||
import * as cardRepo from "@kan/db/repository/card.repo";
|
||||
import * as memberRepo from "@kan/db/repository/member.repo";
|
||||
import * as notificationRepo from "@kan/db/repository/notification.repo";
|
||||
@@ -72,6 +75,7 @@ export async function sendMentionEmails({
|
||||
const baseUrl = env("NEXT_PUBLIC_BASE_URL");
|
||||
const cardUrl = `${baseUrl}/cards/${cardPublicId}`;
|
||||
|
||||
log.info({ cardPublicId, mentionCount: membersToNotify.length, commenterUserId }, "Sending mention emails");
|
||||
// Send emails to all mentioned members (only if notification doesn't exist)
|
||||
await Promise.all(
|
||||
membersToNotify.map(async (member) => {
|
||||
@@ -91,6 +95,7 @@ export async function sendMentionEmails({
|
||||
|
||||
// If notification already exists, skip sending email
|
||||
if (notificationExists) {
|
||||
log.debug({ email, cardPublicId }, "Skipping duplicate mention email");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -114,20 +119,14 @@ export async function sendMentionEmails({
|
||||
cardUrl,
|
||||
},
|
||||
);
|
||||
log.info({ email, cardPublicId }, "Mention email sent");
|
||||
} catch (error) {
|
||||
console.error("Failed to send mention email:", {
|
||||
email,
|
||||
cardPublicId,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
log.error({ err: error, email, cardPublicId }, "Failed to send mention email");
|
||||
}
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error sending mention emails:", {
|
||||
cardPublicId,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
log.error({ err: error, cardPublicId }, "Error sending mention emails");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ import {
|
||||
} from "rate-limiter-flexible";
|
||||
|
||||
import { getRedisClient } from "@kan/db/redis";
|
||||
import { createLogger } from "@kan/logger";
|
||||
|
||||
const log = createLogger("rateLimit");
|
||||
|
||||
export interface RateLimitOptions {
|
||||
points?: number;
|
||||
@@ -45,7 +48,7 @@ function createRateLimiter(options: RateLimitOptions = {}) {
|
||||
|
||||
// Use Redis if available, otherwise fall back to in-memory storage
|
||||
if (redis) {
|
||||
console.log("Using Redis for rate limiting");
|
||||
log.debug("Using Redis for rate limiting");
|
||||
return new RateLimiterRedis({
|
||||
storeClient: redis,
|
||||
points,
|
||||
@@ -53,7 +56,7 @@ function createRateLimiter(options: RateLimitOptions = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Using in-memory for rate limiting");
|
||||
log.debug("Redis unavailable, falling back to in-memory rate limiting");
|
||||
return new RateLimiterMemory({
|
||||
points,
|
||||
duration,
|
||||
|
||||
@@ -4,6 +4,9 @@ import { z } from "zod";
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import type { WebhookEvent } from "@kan/db/schema";
|
||||
import * as webhookRepo from "@kan/db/repository/webhook.repo";
|
||||
import { createLogger } from "@kan/logger";
|
||||
|
||||
const log = createLogger("webhook");
|
||||
|
||||
export type WebhookEventType = WebhookEvent;
|
||||
|
||||
@@ -199,9 +202,9 @@ export async function sendWebhooksForWorkspace(
|
||||
sendWebhookToUrl(webhook.url, webhook.secret ?? undefined, payload).then(
|
||||
(result) => {
|
||||
if (!result.success) {
|
||||
console.error(
|
||||
`Webhook delivery failed to ${webhook.url}: ${result.error}`,
|
||||
);
|
||||
log.error({ url: webhook.url, event: payload.event, error: result.error, statusCode: result.statusCode }, "Webhook delivery failed");
|
||||
} else {
|
||||
log.info({ url: webhook.url, event: payload.event, statusCode: result.statusCode }, "Webhook delivered");
|
||||
}
|
||||
},
|
||||
),
|
||||
@@ -210,7 +213,7 @@ export async function sendWebhooksForWorkspace(
|
||||
// Wait for all to complete but don't block on failures
|
||||
await Promise.allSettled(promises);
|
||||
} catch (error) {
|
||||
console.error("Failed to send webhooks for workspace:", error);
|
||||
log.error({ err: error, workspaceId }, "Failed to send webhooks for workspace");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user