mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 12:25:22 +00:00
* wip on refactoring docs * wip * initial structured logs impl * structured log docs * create logger package * add news entry for structured logging * add logger package to dockerfile and cleanup * add gh workflow for catching broken links * further wip * fix * further wip on docs * review feedback * remove logger dep from mcp package * fix build errors * add back auth_url warning * fix sidebar title consistency --------- Co-authored-by: bkellam <bshizzle1234@gmail.com>
87 lines
No EOL
2.8 KiB
TypeScript
87 lines
No EOL
2.8 KiB
TypeScript
import winston, { format } 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
|
|
};
|