@@ -16,12 +16,12 @@ try {
16
16
// thread (0).
17
17
}
18
18
19
- const bunyan = require ( 'bunyan' ) ;
20
- const { logger } = require ( '@instana/core' ) ;
19
+ const uninstrumentedLogger = require ( './uninstrumentedLogger' ) ;
21
20
22
- const bunyanToAgentStream = require ( './agent/bunyanToAgentStream' ) ;
21
+ const { logger } = require ( '@instana/core' ) ;
22
+ const loggerToAgentStream = require ( './agent/loggerToAgentStream' ) ;
23
23
24
- /** @type {bunyan | import('@instana/core/src/core').GenericLogger } */
24
+ /** @type {import('@instana/core/src/core').GenericLogger } */
25
25
let parentLogger = null ;
26
26
/** @type {Object.<string, (logger: import('@instana/core/src/core').GenericLogger) => *> } */
27
27
const registry = { } ;
@@ -35,37 +35,63 @@ exports.init = function init(config, isReInit) {
35
35
// A bunyan or pino logger has been provided via config. In either case we create a child logger directly under the
36
36
// given logger which serves as the parent for all loggers we create later on.
37
37
parentLogger = config . logger . child ( {
38
- module : 'instana-nodejs-logger-parent' ,
39
- __in : 1
38
+ module : 'instana-nodejs-logger-parent'
40
39
} ) ;
41
40
} else if ( config . logger && hasLoggingFunctions ( config . logger ) ) {
42
- // A custom non-bunyan logger has been provided via config. We use it as is.
41
+ // A custom non-bunyan/non-pino logger has been provided via config. We use it as is.
43
42
parentLogger = config . logger ;
44
43
} else {
45
- // No custom logger has been provided via config, we create a new bunyan logger as the parent logger for all loggers
44
+ // No custom logger has been provided via config, we create a new pino logger as the parent logger for all loggers
46
45
// we create later on.
47
- parentLogger = bunyan . createLogger ( {
46
+ parentLogger = uninstrumentedLogger ( {
48
47
name : '@instana/collector' ,
49
- thread : threadId ,
50
- __in : 1
48
+ level : 'info'
51
49
} ) ;
52
50
}
53
- if ( isBunyan ( parentLogger ) ) {
51
+
52
+ // Passing the log stream to agentStream for Debugging purposes
53
+ // TODO: consider adding winston and other major loggers also for this
54
+ if ( isPinoLogger ( parentLogger ) ) {
55
+ // This consoleStream creates a destination stream for the logger that writes log data to the standard output.
56
+ // Since we are using multistream here, this needs to be specified explicitly
57
+
58
+ const consoleStream = uninstrumentedLogger . destination ( parentLogger . destination ) ;
59
+
60
+ const multiStream = {
61
+ /**
62
+ * Custom write method to send logs to multiple destinations
63
+ * @param {string } chunk
64
+ */
65
+ write ( chunk ) {
66
+ consoleStream . write ( chunk ) ;
67
+
68
+ loggerToAgentStream . write ( chunk ) ;
69
+ }
70
+ } ;
71
+
72
+ parentLogger = uninstrumentedLogger (
73
+ {
74
+ ...parentLogger . levels ,
75
+ level : parentLogger . level || 'info' ,
76
+ base : parentLogger . bindings ( )
77
+ } ,
78
+ multiStream
79
+ ) ;
80
+ } else if ( parentLogger && parentLogger . addStream ) {
54
81
// in case we are using a bunyan logger we also forward logs to the agent
55
- /** @type { bunyan } */ ( parentLogger ) . addStream ( {
82
+ parentLogger . addStream ( {
56
83
type : 'raw' ,
57
- stream : bunyanToAgentStream ,
84
+ stream : loggerToAgentStream ,
58
85
level : 'info'
59
86
} ) ;
60
- if ( process . env [ 'INSTANA_DEBUG' ] ) {
61
- /** @type {bunyan } */ ( parentLogger ) . level ( 'debug' ) ;
62
- } else if ( config . level ) {
63
- /** @type {bunyan } */ ( parentLogger ) . level ( /** @type {import('bunyan').LogLevel } */ ( config . level ) ) ;
64
- } else if ( process . env [ 'INSTANA_LOG_LEVEL' ] ) {
65
- /** @type {bunyan } */ ( parentLogger ) . level (
66
- /** @type {import('bunyan').LogLevel } */ ( process . env [ 'INSTANA_LOG_LEVEL' ] . toLowerCase ( ) )
67
- ) ;
68
- }
87
+ }
88
+
89
+ if ( process . env [ 'INSTANA_DEBUG' ] ) {
90
+ setLoggerLevel ( parentLogger , 'debug' ) ;
91
+ } else if ( config . level ) {
92
+ setLoggerLevel ( parentLogger , config . level ) ;
93
+ } else if ( process . env [ 'INSTANA_LOG_LEVEL' ] ) {
94
+ setLoggerLevel ( parentLogger , process . env [ 'INSTANA_LOG_LEVEL' ] . toLowerCase ( ) ) ;
69
95
}
70
96
71
97
if ( isReInit ) {
@@ -81,18 +107,21 @@ exports.init = function init(config, isReInit) {
81
107
/**
82
108
* @param {string } loggerName
83
109
* @param {(logger: import('@instana/core/src/core').GenericLogger) => * } [reInitFn]
110
+ * @param {string|null } [level] - Optional log level
84
111
* @returns {import('@instana/core/src/core').GenericLogger }
85
112
*/
86
- exports . getLogger = function getLogger ( loggerName , reInitFn ) {
113
+ exports . getLogger = function getLogger ( loggerName , reInitFn , level ) {
87
114
if ( ! parentLogger ) {
88
115
exports . init ( { } ) ;
89
116
}
117
+
90
118
let _logger ;
91
119
92
120
if ( typeof parentLogger . child === 'function' ) {
93
121
// Either bunyan or pino, both support parent-child relationships between loggers.
94
122
_logger = parentLogger . child ( {
95
- module : loggerName
123
+ module : loggerName ,
124
+ threadId
96
125
} ) ;
97
126
} else {
98
127
// Unknown logger type (neither bunyan nor pino), we simply return the user provided custom logger as-is.
@@ -106,17 +135,13 @@ exports.getLogger = function getLogger(loggerName, reInitFn) {
106
135
registry [ loggerName ] = reInitFn ;
107
136
}
108
137
138
+ if ( level ) {
139
+ setLoggerLevel ( _logger , level ) ;
140
+ }
141
+
109
142
return /** @type {import('@instana/core/src/core').GenericLogger } */ ( _logger ) ;
110
143
} ;
111
144
112
- /**
113
- * @param {import('bunyan') | * } _logger
114
- * @returns {boolean }
115
- */
116
- function isBunyan ( _logger ) {
117
- return _logger instanceof bunyan ;
118
- }
119
-
120
145
/**
121
146
* @param {import('@instana/core/src/core').GenericLogger | * } _logger
122
147
* @returns {boolean }
@@ -129,3 +154,25 @@ function hasLoggingFunctions(_logger) {
129
154
typeof _logger . error === 'function'
130
155
) ;
131
156
}
157
+
158
+ /**
159
+ * @param {import("@instana/core/src/core").GenericLogger } _logger
160
+ * @param {string|number } level
161
+ */
162
+ function setLoggerLevel ( _logger , level ) {
163
+ if ( typeof _logger . setLevel === 'function' ) {
164
+ _logger . setLevel ( level ) ;
165
+ } else {
166
+ _logger . level = level ;
167
+ }
168
+ }
169
+
170
+ /**
171
+ * @param {* } _logger
172
+ * @returns {boolean }
173
+ */
174
+ function isPinoLogger ( _logger ) {
175
+ return (
176
+ _logger && typeof _logger === 'object' && typeof _logger . child === 'function' && typeof _logger . level === 'string'
177
+ ) ;
178
+ }
0 commit comments