- Create new @link-stack/logger package wrapping Pino for structured logging - Replace all console.log/error/warn statements across the monorepo - Configure environment-aware logging (pretty-print in dev, JSON in prod) - Add automatic redaction of sensitive fields (passwords, tokens, etc.) - Remove dead commented-out logger file from bridge-worker - Follow Pino's standard argument order (context object first, message second) - Support log levels via LOG_LEVEL environment variable - Export TypeScript types for better IDE support This provides consistent, structured logging across all applications and packages, making debugging easier and production logs more parseable.
72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
import { db } from "@link-stack/bridge-common";
|
|
import { createLogger } from "@link-stack/logger";
|
|
|
|
const logger = createLogger('notify-webhooks');
|
|
|
|
export interface NotifyWebhooksOptions {
|
|
backendId: string;
|
|
payload: any;
|
|
}
|
|
|
|
const notifyWebhooksTask = async (
|
|
options: NotifyWebhooksOptions,
|
|
): Promise<void> => {
|
|
const { backendId, payload } = options;
|
|
|
|
logger.debug({
|
|
backendId,
|
|
payloadKeys: Object.keys(payload),
|
|
}, 'Processing webhook notification');
|
|
|
|
const webhooks = await db
|
|
.selectFrom("Webhook")
|
|
.selectAll()
|
|
.where("backendId", "=", backendId)
|
|
.execute();
|
|
|
|
logger.debug({ count: webhooks.length, backendId }, 'Found webhooks');
|
|
|
|
for (const webhook of webhooks) {
|
|
const { endpointUrl, httpMethod, headers } = webhook;
|
|
const finalHeaders = { "Content-Type": "application/json", ...headers };
|
|
const body = JSON.stringify(payload);
|
|
|
|
logger.debug({
|
|
url: endpointUrl,
|
|
method: httpMethod,
|
|
bodyLength: body.length,
|
|
headerKeys: Object.keys(finalHeaders),
|
|
}, 'Sending webhook');
|
|
|
|
try {
|
|
const result = await fetch(endpointUrl, {
|
|
method: httpMethod,
|
|
headers: finalHeaders,
|
|
body,
|
|
});
|
|
|
|
logger.debug({
|
|
url: endpointUrl,
|
|
status: result.status,
|
|
statusText: result.statusText,
|
|
ok: result.ok,
|
|
}, 'Webhook response');
|
|
|
|
if (!result.ok) {
|
|
const responseText = await result.text();
|
|
logger.error({
|
|
url: endpointUrl,
|
|
status: result.status,
|
|
responseSample: responseText.substring(0, 500),
|
|
}, 'Webhook error response');
|
|
}
|
|
} catch (error) {
|
|
logger.error({
|
|
url: endpointUrl,
|
|
error: error instanceof Error ? error.message : error,
|
|
}, 'Webhook request failed');
|
|
}
|
|
}
|
|
};
|
|
|
|
export default notifyWebhooksTask;
|