-
-
Notifications
You must be signed in to change notification settings - Fork 11.4k
Converted initial outbox logs to structured logging #26599
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
8f1e437
2b21e72
3e728f8
0c2a36e
5b7e974
d3e585d
38f3e70
8ee484a
b4b9bb5
ddc0e54
f93a915
97545a9
79ee3a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| const bunyan = require('bunyan'); | ||
| const {PassThrough} = require('stream'); | ||
| const logging = require('@tryghost/logging'); | ||
|
|
||
| /** | ||
| * Parse newline-delimited JSON log records from a buffered string. | ||
| * | ||
| * @param {string} buffer - Buffered log text that may contain multiple records. | ||
| * @param {Array<object>} output - Collected parsed log records. | ||
| * @returns {string} Remaining partial record that did not end with a newline. | ||
| */ | ||
| function parseBufferedJsonLogs(buffer, output) { | ||
| const lines = buffer.split('\n'); | ||
| const remaining = lines.pop(); | ||
|
|
||
| for (const line of lines) { | ||
| if (!line.trim()) { | ||
| continue; | ||
| } | ||
|
|
||
| output.push(JSON.parse(line)); | ||
| } | ||
|
|
||
| return remaining; | ||
| } | ||
|
|
||
| /** | ||
| * Temporarily redirects Ghost logger streams to an in-memory Bunyan stream. | ||
| * | ||
| * This allows tests to assert on real serialized JSON output from | ||
| * `@tryghost/logging` without stubbing logger methods. | ||
| * | ||
| * @returns {{output: Array<object>, restore: () => void}} Capture handle. | ||
| */ | ||
| function captureLoggerOutput() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. captureLoggerOutput doesn't preserve serializers The replacement bunyan logger in the capture utility doesn't use the same serializers as the original Ghost logger. This means the captured JSON may differ from production output for objects that have custom serialization (like err objects). For the current test cases this doesn't matter, but as this utility gets used more broadly it could cause subtle differences between test and production log output. Worth a comment or future enhancement. |
||
| const output = []; | ||
| const stream = new PassThrough(); | ||
| let buffered = ''; | ||
|
|
||
| stream.on('data', (chunk) => { | ||
| buffered += chunk.toString(); | ||
| buffered = parseBufferedJsonLogs(buffered, output); | ||
| }); | ||
|
|
||
| const originalStreams = logging.streams; | ||
| logging.streams = { | ||
| capture: { | ||
| name: 'capture', | ||
| log: bunyan.createLogger({ | ||
| name: 'test-logger', | ||
| streams: [{ | ||
| type: 'stream', | ||
| stream, | ||
| level: 'trace' | ||
| }] | ||
| }) | ||
| } | ||
| }; | ||
|
|
||
| return { | ||
| output, | ||
| restore() { | ||
| buffered = parseBufferedJsonLogs(buffered, output); | ||
| logging.streams = originalStreams; | ||
| stream.destroy(); | ||
cmraible marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * Find the first structured log record matching a system event. | ||
| * | ||
| * @param {Array<object>} output - Captured log records. | ||
| * @param {string} event - Structured event name to match. | ||
| * @returns {object|undefined} First matching log record. | ||
| */ | ||
| function findByEvent(output, event) { | ||
cmraible marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return output.find(log => log.system?.event === event); | ||
| } | ||
|
|
||
| module.exports = { | ||
| captureLoggerOutput, | ||
| findByEvent | ||
| }; | ||
Uh oh!
There was an error while loading. Please reload this page.