增加feifei 日志

This commit is contained in:
yml2213
2026-07-07 16:04:54 +08:00
parent affba7e924
commit 59f6f5ee1e
4 changed files with 347 additions and 97 deletions
+79 -55
View File
@@ -28,7 +28,10 @@ test('shouldWriteLog respects configured minimum log level', () => {
test('resolveLogFilePath uses daily log file names by channel', () => {
assert.match(resolveLogFilePath('app', '2026-05-28T00:00:19.194+08:00'), /app-2026-05-28\.log$/)
assert.match(resolveLogFilePath('integration', '2026-05-28T00:00:19.194+08:00'), /integration-2026-05-28\.log$/)
assert.match(
resolveLogFilePath('integration', '2026-05-28T00:00:19.194+08:00'),
/integration-2026-05-28\.log$/,
)
})
test('resolveLogFilePath uses local date for utc timestamps', () => {
@@ -36,15 +39,18 @@ test('resolveLogFilePath uses local date for utc timestamps', () => {
})
test('resolveExpiredLogFilenames keeps latest thirty days by default and ignores unknown files', () => {
const expired = resolveExpiredLogFilenames([
'app-2026-05-30.log',
'app-2026-05-01.log',
'app-2026-04-30.log',
'integration-2026-04-29.log',
'app.log',
'integration.log',
'random.txt',
], '2026-05-30')
const expired = resolveExpiredLogFilenames(
[
'app-2026-05-30.log',
'app-2026-05-01.log',
'app-2026-04-30.log',
'integration-2026-04-29.log',
'app.log',
'integration.log',
'random.txt',
],
'2026-05-30',
)
assert.deepEqual(expired, [
'app-2026-04-30.log',
@@ -55,15 +61,13 @@ test('resolveExpiredLogFilenames keeps latest thirty days by default and ignores
})
test('resolveExpiredLogFilenames supports explicit retention days', () => {
const expired = resolveExpiredLogFilenames([
'app-2026-04-14.log',
'app-2026-04-08.log',
'app-2026-04-07.log',
], '2026-04-14', 7)
const expired = resolveExpiredLogFilenames(
['app-2026-04-14.log', 'app-2026-04-08.log', 'app-2026-04-07.log'],
'2026-04-14',
7,
)
assert.deepEqual(expired, [
'app-2026-04-07.log',
])
assert.deepEqual(expired, ['app-2026-04-07.log'])
})
test('formatLogTimestamp renders readable local timestamp with timezone offset', () => {
@@ -72,18 +76,21 @@ test('formatLogTimestamp renders readable local timestamp with timezone offset',
})
test('formatLogEntry prints readable one-line output for flat details', () => {
const text = formatLogEntry({
time: '2026-04-14T10:36:24.974Z',
level: 'info',
scope: '[http/access]',
message: 'request completed',
pid: 4671,
detail: {
requestId: 'req-123',
method: 'GET',
statusCode: 401,
const text = formatLogEntry(
{
time: '2026-04-14T10:36:24.974Z',
level: 'info',
scope: '[http/access]',
message: 'request completed',
pid: 4671,
detail: {
requestId: 'req-123',
method: 'GET',
statusCode: 401,
},
},
}, { color: false })
{ color: false },
)
assert.match(text, /INFO\s+\[http\/access\] request completed/)
assert.match(text, /pid=4671/)
@@ -94,21 +101,24 @@ test('formatLogEntry prints readable one-line output for flat details', () => {
})
test('formatLogEntry prints nested detail blocks without ansi colors in file mode', () => {
const text = formatLogEntry({
time: '2026-04-14T10:36:24.974Z',
level: 'warn',
scope: '[admin/auth]',
message: '后台鉴权失败',
pid: 4671,
detail: {
statusCode: 401,
errorCode: 'admin_auth_required',
error: {
message: '未登录或登录已失效',
stack: 'Error: test',
const text = formatLogEntry(
{
time: '2026-04-14T10:36:24.974Z',
level: 'warn',
scope: '[admin/auth]',
message: '后台鉴权失败',
pid: 4671,
detail: {
statusCode: 401,
errorCode: 'admin_auth_required',
error: {
message: '未登录或登录已失效',
stack: 'Error: test',
},
},
},
}, { color: false })
{ color: false },
)
assert.match(text, /WARN\s+\[admin\/auth\] 后台鉴权失败/)
assert.match(text, /statusCode=401/)
@@ -119,24 +129,38 @@ test('formatLogEntry prints nested detail blocks without ansi colors in file mod
})
test('formatLogEntry masks sensitive fields in inline and nested details', () => {
const text = formatLogEntry({
time: '2026-04-14T10:36:24.974Z',
level: 'info',
scope: '[security]',
message: 'masked',
pid: 4671,
detail: {
token: 'abcdef1234567890',
authorization: 'Bearer abcdef1234567890',
nested: {
cookie: 'sessionid=abcdef1234567890',
note: 'password=super-secret-value',
const text = formatLogEntry(
{
time: '2026-04-14T10:36:24.974Z',
level: 'info',
scope: '[security]',
message: 'masked',
pid: 4671,
detail: {
token: 'abcdef1234567890',
authorization: 'Bearer abcdef1234567890',
sign: '0123456789abcdef',
jumpLink:
'https://feifei.example.com/h5/bind?code=very-secret-code&token=very-secret-token',
rawText:
'{"token":"raw-json-token","sign":"raw-json-sign","h5":{"recharge_url":"https://feifei.example.com/h5/bind?code=raw-secret-code"}}',
nested: {
cookie: 'sessionid=abcdef1234567890',
note: 'password=super-secret-value',
},
},
},
}, { color: false })
{ color: false },
)
assert.doesNotMatch(text, /abcdef1234567890/)
assert.doesNotMatch(text, /super-secret-value/)
assert.doesNotMatch(text, /0123456789abcdef/)
assert.doesNotMatch(text, /very-secret-code/)
assert.doesNotMatch(text, /very-secret-token/)
assert.doesNotMatch(text, /raw-json-token/)
assert.doesNotMatch(text, /raw-json-sign/)
assert.doesNotMatch(text, /raw-secret-code/)
assert.match(text, /abcdef\*\*\*\*567890/)
assert.match(text, /Bearer\*\*\*\*567890/)
assert.match(text, /password=super-\*\*\*\*-value/)