-
Notifications
You must be signed in to change notification settings - Fork 518
Expand file tree
/
Copy pathlogger.ts
More file actions
108 lines (96 loc) · 2.8 KB
/
logger.ts
File metadata and controls
108 lines (96 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { mkdirSync } from 'fs'
import path from 'path'
import { format } from 'util'
import { splitData } from '@codebuff/common/util/split-data'
import { env } from '@codebuff/internal/env'
import pino from 'pino'
import {
getLoggerContext,
withAppContext,
type LoggerContext,
} from '../context/app-context'
// --- Constants ---
const MAX_LENGTH = 65535 // Max total log size is sometimes 100k (sometimes 65535?)
const BUFFER = 1000 // Buffer for context, etc.
export const withLoggerContext = <T>(
additionalContext: Partial<LoggerContext>,
fn: () => Promise<T>,
) => {
// Use the new combined context, preserving any existing request context
return withAppContext(additionalContext, {}, fn)
}
// Ensure debug directory exists for local environment
const debugDir = path.join(__dirname, '../../../debug')
if (
env.NEXT_PUBLIC_CB_ENVIRONMENT === 'dev' &&
process.env['CODEBUFF_GITHUB_ACTIONS'] !== 'true'
) {
try {
mkdirSync(debugDir, { recursive: true })
} catch (err) {
console.error('Failed to create debug directory:', err)
}
}
const pinoLogger = pino(
{
level: 'debug',
mixin() {
// Use the new combined context
return { logTrace: getLoggerContext() }
},
formatters: {
level: (label) => {
return { level: label.toUpperCase() }
},
},
timestamp: () => `,"timestamp":"${new Date(Date.now()).toISOString()}"`,
},
env.NEXT_PUBLIC_CB_ENVIRONMENT === 'dev' &&
process.env['CODEBUFF_GITHUB_ACTIONS'] !== 'true'
? pino.transport({
target: 'pino/file',
options: {
destination: path.join(debugDir, 'backend.log'),
},
level: 'debug',
})
: undefined,
)
const loggingLevels = ['info', 'debug', 'warn', 'error', 'fatal'] as const
type LogLevel = (typeof loggingLevels)[number]
function splitAndLog(
level: LogLevel,
data: any,
msg?: string,
...args: any[]
): void {
const formattedMsg = format(msg ?? '', ...args)
const availableDataLimit = MAX_LENGTH - BUFFER - formattedMsg.length
// split data recursively into chunks small enough to log
const processedData: any[] = splitData({
data,
maxChunkSize: availableDataLimit,
})
if (processedData.length === 1) {
pinoLogger[level](processedData[0], msg, ...args)
return
}
processedData.forEach((chunk, index) => {
pinoLogger[level](
chunk,
`${formattedMsg} (chunk ${index + 1}/${processedData.length})`,
)
})
}
export const logger: Record<LogLevel, pino.LogFn> =
env.NEXT_PUBLIC_CB_ENVIRONMENT === 'dev'
? pinoLogger
: (Object.fromEntries(
loggingLevels.map((level) => {
return [
level,
(data: any, msg?: string, ...args: any[]) =>
splitAndLog(level, data, msg, ...args),
]
}),
) as Record<LogLevel, pino.LogFn>)