sourcebot/packages/logger/src/index.ts
Brendan Kellam 4ebe4e0475
Some checks failed
Publish to ghcr / build (linux/amd64, blacksmith-4vcpu-ubuntu-2404) (push) Has been cancelled
Publish to ghcr / build (linux/arm64, blacksmith-8vcpu-ubuntu-2204-arm) (push) Has been cancelled
Publish to ghcr / merge (push) Has been cancelled
chore(worker,web): Repo indexing stability improvements + perf improvements to web (#563)
2025-10-18 16:31:22 -07:00

91 lines
No EOL
2.8 KiB
TypeScript

import winston, { format, Logger } from 'winston';
import { Logtail } from '@logtail/node';
import { LogtailTransport } from '@logtail/winston';
import { MESSAGE } from 'triple-beam';
import { env } from './env.js';
/**
* Logger configuration with support for structured JSON logging.
*
* When SOURCEBOT_STRUCTURED_LOGGING_ENABLED=true:
* - Console output will be in JSON format suitable for Datadog ingestion
* - Logs will include structured fields: timestamp, level, message, label, stack (if error)
*
* When SOURCEBOT_STRUCTURED_LOGGING_ENABLED=false (default):
* - Console output will be human-readable with colors
* - Logs will be formatted as: "timestamp level: [label] message"
*/
const { combine, colorize, timestamp, prettyPrint, errors, printf, label: labelFn, json } = format;
const datadogFormat = format((info) => {
info.status = info.level.toLowerCase();
info.service = info.label;
info.label = undefined;
const msg = info[MESSAGE as unknown as string] as string | undefined;
if (msg) {
info.message = msg;
info[MESSAGE as unknown as string] = undefined;
}
return info;
});
const humanReadableFormat = printf(({ level, message, timestamp, stack, label: _label }) => {
const label = `[${_label}] `;
if (stack) {
return `${timestamp} ${level}: ${label}${message}\n${stack}`;
}
return `${timestamp} ${level}: ${label}${message}`;
});
const createLogger = (label: string) => {
const isStructuredLoggingEnabled = env.SOURCEBOT_STRUCTURED_LOGGING_ENABLED === 'true';
return winston.createLogger({
level: env.SOURCEBOT_LOG_LEVEL,
format: combine(
errors({ stack: true }),
timestamp(),
labelFn({ label: label }),
),
transports: [
new winston.transports.Console({
format: isStructuredLoggingEnabled
? combine(
datadogFormat(),
json()
)
: combine(
colorize(),
humanReadableFormat
),
}),
...(env.SOURCEBOT_STRUCTURED_LOGGING_FILE && isStructuredLoggingEnabled ? [
new winston.transports.File({
filename: env.SOURCEBOT_STRUCTURED_LOGGING_FILE,
format: combine(
datadogFormat(),
json()
),
}),
] : []),
...(env.LOGTAIL_TOKEN && env.LOGTAIL_HOST ? [
new LogtailTransport(
new Logtail(env.LOGTAIL_TOKEN, {
endpoint: env.LOGTAIL_HOST,
})
)
] : []),
]
});
}
export {
createLogger
};
export type {
Logger,
}