-
Notifications
You must be signed in to change notification settings - Fork 40
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
Use safe-stable-stringify for perf and to support circular refs #104
Comments
@lancegliser Thanks for your work here. I'm just coming back to this after ages. I understand if you don't want to engage again. So Winston switched to I am leaning towards changing away from |
@trentm I'll admit to being way out of the loop. A quick look over the history doesn't ring a bell for me. I'm going to need to devote a bit of time... Booked some hours on Tuesday. Hope to get you an answer on if it's easy enough to just switch and merge. |
I'll try to clarify what I said above. There are so many
|
Not sure where to post the updates, but we'll continue here. I created a repo you can use (with a little effort) to reproduce for testing: lancegliser/winston-ecs-redaction. To test things out, you can const logger = winston.createLogger({
// Uncomment to cause
// { errors: [{ "message": "Converting circular structure to JSON\n --> starting at object with constructor 'Socket'\n | property 'parser' -> object with constructor 'HTTPParser'\n --- property 'socket' closes the circle", }} }
format: format.combine(
ecsFields({ convertReqRes: true }),
new WinstonRedactFormatter({
paths: ["http.request.headers.authorization"],
}),
// Keep uncommented to cause the error
ecsStringify(),
// Bypass the ecsStringify using winston standard json formatter to get success
// format.json(),
),
}); To run api, use You can fire the following GraphQL query to hit the required code: query SystemConfig {
system {
config {
timestamp
}
}
} You'll want to provide a header: "Authorization: FooBar" to test redaction as well. That will fire the Example of message with {
"@timestamp": "2023-10-11T02:23:08.331Z",
"log.level": "error",
"message": "Apollo.didEncounterErrors: :query SystemConfig {\n system {\n config {\n ...",
"ecs": {
"version": "1.6.0"
},
"event.kind": "event",
"event.category": [
"network",
"web"
],
"error.type": "GraphQLError",
"error.message": "Converting circular structure to JSON\n --> starting at object with constructor 'Socket'\n | property 'parser' -> object with constructor 'HTTPParser'\n --- property 'socket' closes the circle",
"error.stack_trace": "TypeError: Converting circular structure to JSON\n --> starting at object with constructor 'Socket'\n | property 'parser' -> object with constructor 'HTTPParser'\n --- property 'socket' closes the circle\n at JSON.stringify (<anonymous>)\n ...",
"event.type": [
"end",
"allowed",
"error"
],
"event.reason": "Apollo.didEncounterErrors",
"event.extras": {
"request": {
"query": "query SystemConfig {\n system {\n config {\n timestamp\n }\n }\n}",
"variables": [],
"headers": {
"host": "localhost:5000",
"connection": "keep-alive",
"content-length": "136",
"sec-ch-ua": "\"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"",
"content-type": "application/json",
"sec-ch-ua-mobile": "?0",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
"sec-ch-ua-platform": "\"macOS\"",
"accept": "*/*",
"origin": "http://localhost:5000",
"sec-fetch-site": "same-origin",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "http://localhost:5000/",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9,ru;q=0.8"
}
},
"response": {
"errors": [
{
"message": "Converting circular structure to JSON\n --> starting at object with constructor 'Socket'\n | property 'parser' -> object with constructor 'HTTPParser'\n --- property 'socket' closes the circle",
"locations": [
{
"line": 3,
"column": 5
}
],
"path": [
"system",
"config"
]
}
]
}
},
"event.duration": 2337285
} Example using {
"@timestamp": "2023-10-11T02:23:44.681Z",
"client": {
"address": "::1",
"ip": "::1",
"port": 58656
},
"ecs": {
"version": "1.6.0"
},
"http": {
"request": {
"body": {
"bytes": 136
},
"headers": {
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9,ru;q=0.8",
"authorization": "[REDACTED]",
"connection": "keep-alive",
"content-length": "136",
"content-type": "application/json",
"host": "localhost:5000",
"origin": "http://localhost:5000",
"referer": "http://localhost:5000/",
"sec-ch-ua": "\"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
},
"method": "POST"
},
"response": {
"headers": {
"access-control-allow-credentials": "true",
"vary": "Origin",
"x-powered-by": "Express"
},
"status_code": 200
},
"version": "1.1"
},
"log.level": "info",
"message": "Reference objects",
"object": {
"value": {
"value": {
"_body": true,
"_consuming": true,
"_dumped": false,
...
}
}
} The ability to get successful logging and output bypassing
Seeing the issue here with Feel free to test out my repo to help confirm! |
This drops the schema-based fast-json-stringify usage, which could potentially be faster, but will throw on circular references. The safer serialization is more appropriate for logging libs. Note that currently both pino and winston themselves use safe-stable-stringify. Add explicit dep for triple-beam, rather than getting lucky. Use a Format class to avoid needing a dep on winston or logform for the 'winston.format(...)' call. Document subtle diffs with our stringifier and winston.format.json(). Closes: #104 Closes: #144 Closes: #145 Closes: #108
The winston package updated it's stringification tool to
fast-safe-stringify
a while back at Jun 11, 2018.I introduced here: #57. In it's PR I raised a this as a separate issue in one comment with notes. Pulling those in here for easy read:
When I attempt to use req and res as part of the formatting meta data I get a new error:
Sample express controller method:
Result:
I tracked the cause down to:
Where info contains
Symbol(splat)
which is{req: IncomingMessage, res: ServerResponse, labels: Object}
, but there's a circular piece inside the req at several places because that's just Express. A little research showed me Use fast-safe-stringify for perf and to support circular refs #35 in winstonjs/winston changed their internal serialization agent to handle circular structure by moving to fast-safe-stringify. I checked the common helpers in this package and it looks like you're still using fast-json-stringify. Maybe that's somehow responsible for the difference?A quick test swapping:
Did indeed serial manage to output the correct format to the transporter:
The text was updated successfully, but these errors were encountered: