-
Notifications
You must be signed in to change notification settings - Fork 212
Adds structured logging API. #665
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
Conversation
@laurenzlong for code review |
@@ -0,0 +1,135 @@ | |||
// Determine if structured logs are supported (node >= 10). If something goes wrong, | |||
import { format } from 'util'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this import got in the middle of two lines of comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, fixed.
|
||
// Map LogSeverity types to their equivalent `console.*` method. | ||
const CONSOLE_SEVERITY: { | ||
[severity: string]: 'debug' | 'info' | 'warn' | 'error'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I'm not sure if TS would let you do this, but if it does). This would be clearer as:
[severity: LogSeverity]: 'debug' | 'info' | 'warn' | 'error';
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TS doesn't let you do this 😢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😢
CHANGELOG.md
Outdated
@@ -0,0 +1,16 @@ | |||
- Adds `functions.logger` SDK to enabled structured logging in the Node.js 10 runtime. Example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add that in Node.js versions < 10, the method still is supported but the data is displayed in a single line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
import { format } from 'util'; | ||
|
||
// safely preserve unpatched console.* methods in case of compat require | ||
const unpatchedConsole = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this still won't work if somebody did this:
require('firebase-functions/logger/compat');
// Already overwrote console.* methods before requiring "firebase-functions"
const functions = require('firebase-functions');
// unpatchedConsole is actually the patched console
functions.logger.info('something') // will probably do weird things
I think there's many opportunities for there to be weird bugs and edge cases with 'compat', and I'm not sure it's worth the incremental convenience of providing this functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does work, because the first thing compat
does is require logger
which preserves the unpatched console methods. Added a comment to clarify.
This wasn't in my original proposal but Kato asked if it was possible and it turned out to be easier than expected. I do worry about the chance for bugs here but this is just one way to use the SDK and provides a convenience. Anyone who encounters bugs we can just tell to use the other ways of using the SDK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, compat does import logger first, this is really subtle behavior, it's good you added a comment to clarify.
I'm still not a fan of compat
and I think it's just making this SDK harder to maintain (it's already way too complicated and has too many subtle behaviors) But if you feel like the risk is worth the user experience benefit, we can keep it in.
import { format } from 'util'; | ||
|
||
// safely preserve unpatched console.* methods in case of compat require | ||
const unpatchedConsole = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, compat does import logger first, this is really subtle behavior, it's good you added a comment to clarify.
I'm still not a fan of compat
and I think it's just making this SDK harder to maintain (it's already way too complicated and has too many subtle behaviors) But if you feel like the risk is worth the user experience benefit, we can keep it in.
|
||
// Map LogSeverity types to their equivalent `console.*` method. | ||
const CONSOLE_SEVERITY: { | ||
[severity: string]: 'debug' | 'info' | 'warn' | 'error'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Michael! Some style things for you to look at.
CHANGELOG.md
Outdated
@@ -0,0 +1,18 @@ | |||
- Adds `functions.logger` SDK to enabled structured logging in the Node.js 10 runtime. Example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo, should be "to enable"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -0,0 +1,18 @@ | |||
- Adds `functions.logger` SDK to enabled structured logging in the Node.js 10 runtime. Example: | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A nit, but in a text flow we prefer "For example:"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -0,0 +1,18 @@ | |||
- Adds `functions.logger` SDK to enabled structured logging in the Node.js 10 runtime. Example: | |||
|
|||
```js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, does this work? In the d.ts files we use ```javascript, but a shorter form would be nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup 😄
CHANGELOG.md
Outdated
require('firebase-functions/logger/compat'); | ||
``` | ||
|
||
In older runtimes, the logger will print to console, no structured data is saved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest "logger prints to the console, and no..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -0,0 +1,135 @@ | |||
import { format } from 'util'; | |||
|
|||
// safely preserve unpatched console.* methods in case of compat require |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will these be parsed into the reference by our TypeDoc script? If so, suggest "//Safely . . . require." with init cap and period.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope.
const SUPPORTS_STRUCTURED_LOGS = | ||
parseInt(process.versions?.node?.split('.')?.[0] || '8', 10) >= 10; | ||
|
||
// Map LogSeverity types to their equivalent `console.*` method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this goes to public docs, let's backtick LogSeverity
or just say "log severity" in the text flow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't be in public docs.
src/logger.ts
Outdated
}; | ||
|
||
/** | ||
* LogSeverity indicates the detailed severity of the log entry. See [Cloud Logging docs](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity) for more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest backticks for LogSeverity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/logger.ts
Outdated
}; | ||
|
||
/** | ||
* LogSeverity indicates the detailed severity of the log entry. See [Cloud Logging docs](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity) for more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest the actual doc section title, LogSeverity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/logger.ts
Outdated
| 'EMERGENCY'; | ||
|
||
/** | ||
* LogEntry represents a structured Cloud Logging entry. All keys aside from `severity` and `message` are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest backticks for LogEntry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/logger.ts
Outdated
} | ||
|
||
/** | ||
* Writes a LogEntry to `stdout`/`stderr` (depending on severity). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest backticks for LogEntry
(and every other literal that appears in the HTML output for the reference docs).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Any ideas when this is due to be merged/released? |
@mbleigh Will this PR correctly display the log severity when using |
@sk- yes, although I'm waiting for some corresponding changes to land in the Firebase console before merging and releasing this as we need to adjust for some changes to the way logs are structured in Node 10. |
@mbleigh I can confirm that the severity is respected, at least on Cloud Logging (I don't see it on Firebase yet). However there are some issues:
|
Hmm...interesting. Will try to dig into this a bit more before release. The way this works is using the container logs contract from Cloud Run (newer Cloud Functions runtimes are built on the same infra). It seems like it should be populating |
@mbleigh You are right, if there is no structured data (meaning no extra fields other than By reading the logs contract docs, it only says about the message field that it is used as the display text, but mentions nothing of the special case when only these two fields are populated. It'd be great if |
Let's continue this conversation on #697 since this PR is closed and merged. |
Node 10 runtime will soon support structured logging by emitting single-line JSON-encoded data to
STDOUT
/STDERR
. This adds a newfirebase-functions/logger
export that provides structured logging in easy-to-use methods as well asfirebase-functions/logger/compat
that patches systemconsole
methods to output structured logs, solving the "multi-line log" problem for Node 10.TODO