-
Notifications
You must be signed in to change notification settings - Fork 36
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
fix: replace bunyan logger #1447
base: main
Are you sure you want to change the base?
Conversation
a34cab4
to
5e5f845
Compare
c756449
to
accb4aa
Compare
@@ -267,9 +267,11 @@ exports.sendSpans = function sendSpans(spans, cb) { | |||
if (err && !maxContentErrorHasBeenLogged && err instanceof PayloadTooLargeError) { | |||
logLargeSpans(spans); | |||
} else if (err) { | |||
logger.debug('Failed to send: %s', getSpanLengthInfo(spans)); | |||
const obj = getSpanLengthInfo(spans); |
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.
Pino does not support concatenated strings using %s
if an object is passed instead of a string.
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.
issue: Please use
logger.debug('Failed to send: %o', getSpanLengthInfo(spans));
There is more occurrences in the codebase.
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.
logger.debug('Failed to send: %o', getSpanLengthInfo(spans));
Correction: This won't work for custom bunyan logger or winston.
Lets not use %s and no %o at all. Only normal strings.
If that works for all logger types, we can use this:
logger.debug('Failed to send spans", getSpanLengthInfo(spans))
If that does not work, you can use:
blabla = getSpanLengthInfo()
logger.debug(Failed to send spans ${blabla}
);
This is what you did already. Its probably better to raise a small PR to just remove this from our codebase. That would be good and makes the review easier.
* Custom write method to send logs to multiple destinations | ||
* @param {string} chunk | ||
*/ | ||
write(chunk) { |
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.
custom write method which writes the log to stdout and agent stream function (pinoToAgentStream)
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 tried implementing this use case using pino.transport, pino.destination and pino.multistream etc. And finally ended up with the current implementation which is working as expected like previous bunyan stream
packages/collector/src/logger.js
Outdated
@@ -31,40 +31,57 @@ const registry = {}; | |||
* @param {boolean} [isReInit] | |||
*/ | |||
exports.init = function init(config, isReInit) { | |||
const consoleStream = pino.destination(1); |
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 multistream is used, we need to specify the log streams where it is going. Here this is defined for logging into the process.stdout
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 can't follow why we define this here.
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.
While using multistream, our logger did not write to the console(stdout) by default.
We explicitly need to specify wherever this logs should go.
So added stdout
and the agentStream
as two attributes
packages/collector/src/logger.js
Outdated
parentLogger = pino( | ||
{ | ||
...parentLogger.levels, | ||
base: parentLogger.bindings() |
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 we want to change something in pino logger after it is initialized, we need to create a new logger and assign initial logger bindings to it
bd47728
to
6bcd53d
Compare
@@ -8,18 +8,18 @@ const graphQL = require('graphql'); | |||
const graphqlSubscriptions = require('graphql-subscriptions'); | |||
const data = require('./data'); | |||
// Pino log spans are used to verify that follow up calls are traced correctly in a GraphQL entry. | |||
const pinoLogger = require('pino')(); | |||
const bunyanLogger = require('bunyan').createLogger({ name: 'test-logger' }); |
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.
The reason for not using Winston here is that it is added to the list of packages allowed to load before the core module. In these situations, we might lose some spans that can cause the test to fail. We don't want to re-run the tests suppose this situation occurs
@@ -16,7 +16,7 @@ const instana = require('../../../..')(); | |||
const bodyParser = require('body-parser'); | |||
const express = require('express'); | |||
const morgan = require('morgan'); | |||
const pino = require('pino')(); | |||
const bunyan = require('bunyan').createLogger({ name: 'test-app' }); |
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.
qs: Why can't we keep pino logger in all the apps? 🤔
@@ -32,7 +32,7 @@ const TeeLogger = require('../../../../../test_util/TeeLogger'); | |||
const { sqs } = require('./sqsUtil'); | |||
|
|||
const instanaLogger = require('../../../../../../src/logger').getLogger('SQS receiver'); | |||
instanaLogger.level('warn'); | |||
instanaLogger.level = 'warn'; |
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.
suggestion: Please use an interface method e.g. setInstanaLogLevel
or simply setLevel
. Otherwise we always need to update the whole codebase if we want to switch a logger.
@@ -267,9 +267,11 @@ exports.sendSpans = function sendSpans(spans, cb) { | |||
if (err && !maxContentErrorHasBeenLogged && err instanceof PayloadTooLargeError) { | |||
logLargeSpans(spans); | |||
} else if (err) { | |||
logger.debug('Failed to send: %s', getSpanLengthInfo(spans)); | |||
const obj = getSpanLengthInfo(spans); |
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.
issue: Please use
logger.debug('Failed to send: %o', getSpanLengthInfo(spans));
There is more occurrences in the codebase.
packages/collector/src/logger.js
Outdated
if (config.logger && typeof config.logger.child === 'function') { | ||
// A bunyan or pino logger has been provided via config. In either case we create a child logger directly under the | ||
// given logger which serves as the parent for all loggers we create later on. | ||
// A pino logger has been provided via config; create a child logger directly under it. |
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.
issue: Why did you change the comment when the condition was not changed? Is config.logger.child === function
not valid for Bunyan? Was this wrong in the first place?
packages/collector/src/logger.js
Outdated
level: 'info' | ||
}); | ||
|
||
if (isPino(parentLogger)) { |
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.
qs: It seems this condition is only for the internal logger, is that right? Because if yes, we can simplify the logic a lot.
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.
yes, this is for the internal logger only.
packages/collector/src/logger.js
Outdated
@@ -31,40 +31,57 @@ const registry = {}; | |||
* @param {boolean} [isReInit] | |||
*/ | |||
exports.init = function init(config, isReInit) { | |||
const consoleStream = pino.destination(1); |
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 can't follow why we define this here.
* @param {*} _logger | ||
* @returns {boolean} | ||
*/ | ||
function isPinoLogger(_logger) { |
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.
qs: Can we expose this helper function from the logger interface?
forceTransmissionStartingAt: 1 | ||
} | ||
}); | ||
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.
qs: Can you please explain this removal?
const globalAgent = require('../../../globalAgent'); | ||
const appControls = require('./controls'); |
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.
issue: Please do not touch this test. Add a new internal logging integration test.
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.
Why can't we use the native console instead of Pino?
|
||
'use strict'; | ||
|
||
// instana/no-unsafe-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.
// instana/no-unsafe-require |
const logger = require('pino'); | ||
|
||
function createCustomLogger() { | ||
const customPino = Object.assign(function (/** @type {any} */ ...args) { |
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.
const customPino = Object.assign(function (/** @type {any} */ ...args) { | |
const customLogger = Object.assign(function (/** @type {any} */ ...args) { |
@@ -29,13 +29,6 @@ function instrument(Logger) { | |||
function shimLog(markAsError) { | |||
return originalLog => | |||
function () { | |||
if (arguments.length === 0 || (this.fields && !!this.fields.__in)) { |
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.
qs: Why was the arguments.length === 0 check removed? This check prevents tracing unnecessary log calls like logger.warn() without arguments, which don’t produce useful data. How are we handling these cases now?
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.
That was removed by mistake. Added it back
@@ -267,9 +267,11 @@ exports.sendSpans = function sendSpans(spans, cb) { | |||
if (err && !maxContentErrorHasBeenLogged && err instanceof PayloadTooLargeError) { | |||
logLargeSpans(spans); | |||
} else if (err) { | |||
logger.debug('Failed to send: %s', getSpanLengthInfo(spans)); | |||
const obj = getSpanLengthInfo(spans); |
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.
suggestion: Consider renaming obj
to spanInfo
or a similar name to improve clarity and provide better context.
@@ -267,9 +267,11 @@ exports.sendSpans = function sendSpans(spans, cb) { | |||
if (err && !maxContentErrorHasBeenLogged && err instanceof PayloadTooLargeError) { | |||
logLargeSpans(spans); | |||
} else if (err) { | |||
logger.debug('Failed to send: %s', getSpanLengthInfo(spans)); | |||
const obj = getSpanLengthInfo(spans); | |||
logger.debug({ obj }, 'Failed to transmit.'); |
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.
logger.debug({ obj }, 'Failed to transmit.'); | |
logger.debug('Failed to send', { obj }); |
Is this format works?
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.
No this does not work with pino
packages/collector/src/logger.js
Outdated
@@ -16,12 +16,14 @@ try { | |||
// thread (0). | |||
} | |||
|
|||
const bunyan = require('bunyan'); | |||
const { logger } = require('@instana/core'); | |||
const { uninstrumentedLogger: pinoCopy } = require('@instana/core'); |
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.
const { uninstrumentedLogger: pinoCopy } = require('@instana/core'); | |
const { uninstrumentedLogger: pinoCopy } = require('@instana/core'); |
const { uninstrumentedLogger: pinoCopy } = require('@instana/core'); | |
const { uninstrumentedLogger: pino } = require('@instana/core'); |
packages/collector/src/logger.js
Outdated
consoleStream.write(chunk); | ||
|
||
const logRecord = JSON.parse(chunk); | ||
pinoToAgentStream.write(logRecord); |
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.
pinoToAgentStream.write(logRecord); | |
pinoToAgentStream.write(JSON.parse(chunk)); |
packages/collector/src/logger.js
Outdated
* @returns {boolean} | ||
*/ | ||
function isBunyan(_logger) { | ||
return _logger instanceof bunyan; | ||
function isPino(_logger) { |
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.
concern: Relying on internal symbols (e.g., pino.symbols.streamSym
)
may introduce risks if Pino's internal structure changes in future versions.
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.
We can't check instanceof of pino. We need to rely on some internal functions to check this.
We don't need this check for the new logic. removing the function
@@ -42,7 +42,7 @@ if (process.env.SCREW_AROUND_WITH_UP_ARRAY_FIND) { | |||
const instana = require('../../..')(config); | |||
|
|||
const http = require('http'); | |||
const pino = require('pino')(); | |||
const bunyan = require('bunyan').createLogger({ name: 'test-common' }); |
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.
In tests, consider using Winston or any other logger instead of Bunyan, as Bunyan is no longer actively maintained. If we need to drop support for Bunyan in the future, it could become difficult.
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.
Planning to get it back to pino itself, that way we can be sure that our internal pino logs are not traced
2b00699
to
5e80c7b
Compare
3bb0226
to
30a2a75
Compare
…the unintsurmentedLogger module
%s
and correct it