newrelic 8.13.0 → 8.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/NEWS.md CHANGED
@@ -1,31 +1,50 @@
1
- ### v8.13.0 (2022-05-26)
1
+ ### v8.14.0 (2022-06-06)
2
2
 
3
- * Moved log forwarding logic to a transport so customer transports are not polluted with NR linking metadata and timestamp and error manipulations.
3
+ * Fixed issue with `api.getBrowserTimingHeader` optional script unwrapping issue with util.format.
4
+ Thanks for your contribution @github-dd-nicolas 🎉
4
5
 
5
- * Prevented transmitting logs when application level logging has been disabled.
6
+ * Fixed winston instrumentation to not exit early when `winston.createLogger` is created without options.
6
7
 
7
- ### v8.12.0 (2022-05-24)
8
+ * Updated pino instrumentation to not override user log configurations.
8
9
 
9
- * Added instrumentation to pino to support application logging use cases: forwarding, local decorating, and metrics.
10
+ ### v8.13.2 (2022-05-31)
10
11
 
11
- * Added supportability metrics about the data usage bytes of harvested data to the collector endpoints.
12
-
13
- * Added an optional way to avoid wrapping browser agent script with <script> tag when using `api.getBrowserTimingHeader`. This will ease usage with Component based libraries like React.
14
-
15
- Thanks to @github-dd-nicolas for the contribution. 🎉
16
-
17
- * Upgraded `@grpc/proto-loader` to fix a [CVE](https://security.snyk.io/vuln/SNYK-JS-PROTOBUFJS-2441248) with `protobufjs`.
18
-
19
- * Upgraded `@newrelic/test-utilities` to resolve a dev-only audit warning.
20
-
21
- ### v8.11.2 (2022-05-23)
22
-
23
- * Fixed winston instrumentation to no longer coerce every log line to be json.
24
-
25
- ### v8.11.1 (2022-05-13)
26
-
27
- * Fixed an issue with winston instrumentation that caused agent to crash when creating a winston logger from an existing instantiated logger.
12
+ * Upgraded `protobufjs` to resolve CVE-2022-25878
28
13
 
14
+ ### v8.13.1 (2022-05-27)
15
+
16
+ * Fixed passing undefined as a formatter options to `winston.format.combine`
17
+
18
+ Thanks to Rana Mohammad (@rjmohammad) for the contribution. 🎉
19
+
20
+ ### v8.13.0 (2022-05-26)
21
+
22
+ * Moved log forwarding logic to a transport so customer transports are not polluted with NR linking metadata and timestamp and error manipulations.
23
+
24
+ * Prevented transmitting logs when application level logging has been disabled.
25
+
26
+ ### v8.12.0 (2022-05-24)
27
+
28
+ * Added instrumentation to pino to support application logging use cases: forwarding, local decorating, and metrics.
29
+
30
+ * Added supportability metrics about the data usage bytes of harvested data to the collector endpoints.
31
+
32
+ * Added an optional way to avoid wrapping browser agent script with <script> tag when using `api.getBrowserTimingHeader`. This will ease usage with Component based libraries like React.
33
+
34
+ Thanks to @github-dd-nicolas for the contribution. 🎉
35
+
36
+ * Upgraded `@grpc/proto-loader` to fix a [CVE](https://security.snyk.io/vuln/SNYK-JS-PROTOBUFJS-2441248) with `protobufjs`.
37
+
38
+ * Upgraded `@newrelic/test-utilities` to resolve a dev-only audit warning.
39
+
40
+ ### v8.11.2 (2022-05-23)
41
+
42
+ * Fixed winston instrumentation to no longer coerce every log line to be json.
43
+
44
+ ### v8.11.1 (2022-05-13)
45
+
46
+ * Fixed an issue with winston instrumentation that caused agent to crash when creating a winston logger from an existing instantiated logger.
47
+
29
48
  ### v8.11.0 (2022-05-11)
30
49
 
31
50
  * Added application logging for Winston in the Node.js agent
@@ -1801,7 +1801,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
1801
1801
 
1802
1802
  ### @newrelic/test-utilities
1803
1803
 
1804
- This product includes source derived from [@newrelic/test-utilities](https://github.com/newrelic/node-test-utilities) ([v6.5.3](https://github.com/newrelic/node-test-utilities/tree/v6.5.3)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-test-utilities/blob/v6.5.3/LICENSE):
1804
+ This product includes source derived from [@newrelic/test-utilities](https://github.com/newrelic/node-test-utilities) ([v6.5.5](https://github.com/newrelic/node-test-utilities/tree/v6.5.5)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-test-utilities/blob/v6.5.5/LICENSE):
1805
1805
 
1806
1806
  ```
1807
1807
  Apache License
package/api.js CHANGED
@@ -27,8 +27,9 @@ const NAMES = require('./lib/metrics/names')
27
27
  * CONSTANTS
28
28
  *
29
29
  */
30
- const RUM_STUB = 'window.NREUM||(NREUM={});NREUM.info = %s;'
31
- const RUM_STUB_SHELL = `<script type='text/javascript' %s>${RUM_STUB} %s</script>`
30
+ const RUM_STUB = 'window.NREUM||(NREUM={});NREUM.info = %s; %s'
31
+ const RUM_STUB_SHELL = `<script type='text/javascript'>${RUM_STUB}</script>`
32
+ const RUM_STUB_SHELL_WITH_NONCE_PARAM = `<script type='text/javascript' %s>${RUM_STUB}</script>`
32
33
 
33
34
  // these messages are used in the _gracefail() method below in getBrowserTimingHeader
34
35
  const RUM_ISSUES = [
@@ -653,12 +654,18 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
653
654
  const tabs = config.browser_monitoring.debug ? 2 : 0
654
655
  const json = JSON.stringify(rumHash, null, tabs)
655
656
 
656
- // set nonce attribute if passed in options
657
- const nonce = options && options.nonce ? 'nonce="' + options.nonce + '"' : ''
658
- const script = options && options.hasToRemoveScriptWrapper ? RUM_STUB : RUM_STUB_SHELL
659
-
660
657
  // the complete header to be written to the browser
661
- const out = util.format(script, nonce, json, jsAgentLoader)
658
+ const out =
659
+ options && options.hasToRemoveScriptWrapper
660
+ ? util.format(RUM_STUB, json, jsAgentLoader)
661
+ : options && options.nonce
662
+ ? util.format(
663
+ RUM_STUB_SHELL_WITH_NONCE_PARAM,
664
+ 'nonce="' + options.nonce + '"',
665
+ json,
666
+ jsAgentLoader
667
+ )
668
+ : util.format(RUM_STUB_SHELL, json, jsAgentLoader)
662
669
 
663
670
  logger.trace('generating RUM header', out)
664
671
 
@@ -38,12 +38,12 @@ class LogAggregator extends EventAggregator {
38
38
 
39
39
  /**
40
40
  * Due to logging library implementation details
41
- * some log lines are already JSON. We must de-serialize
42
- * so it can be serialized in RemoteMethod. I know, this sucks.
41
+ * some "log lines" are a function that formats the
42
+ * data accordingly into an Object, I know, this sucks.
43
43
  */
44
44
  const formattedLogs = logs.map((logLine) => {
45
- if (typeof logLine === 'string') {
46
- return JSON.parse(logLine)
45
+ if (typeof logLine === 'function') {
46
+ return logLine()
47
47
  }
48
48
 
49
49
  return logLine
@@ -49,20 +49,6 @@ module.exports = function instrument(shim) {
49
49
 
50
50
  const symbols = shim.require('./lib/symbols')
51
51
 
52
- /**
53
- * Wraps the level cache so we can properly set a formatter to return the
54
- * label as level in log line instead of number
55
- */
56
- shim.wrap(levelUtils, 'genLsCache', function genLsCache(shim, genLevelsCache) {
57
- return function wrappedGenLsCache() {
58
- const args = shim.argsToArray.apply(shim, arguments)
59
- args[0][symbols.formattersSym].level = function nrLevelMapping(label) {
60
- return { level: label }
61
- }
62
- return genLevelsCache.apply(this, args)
63
- }
64
- })
65
-
66
52
  shim.wrap(tools, 'asJson', function wrapJson(shim, asJson) {
67
53
  /**
68
54
  * Wraps function in pino that is used to construct/serialize a log
@@ -75,27 +61,14 @@ module.exports = function instrument(shim) {
75
61
  * @returns {string} serialized log line
76
62
  */
77
63
  return function wrappedAsJson() {
78
- // overriding the symbol that defines the key for message(pino defaults this to `msg`)
79
- this[symbols.messageKeySym] = 'message'
80
-
81
64
  const args = shim.argsToArray.apply(shim, arguments)
82
65
 
83
- /**
84
- * changing the label from time to timestamp
85
- * and assign unix timestamp to match our specification
86
- */
87
- args[3] = `,"timestamp":${Date.now()}`
88
-
89
66
  if (isMetricsEnabled(config)) {
90
67
  const level = args[2]
91
68
  incrementLoggingLinesMetrics(levelMap[level], metrics)
92
69
  }
93
70
 
94
- if (isLogForwardingEnabled(config, agent)) {
95
- const metadata = agent.getLinkingMetadata()
96
- const chindings = this[symbols.chindingsSym]
97
- reformatLogLine(args[0], metadata, chindings)
98
- } else if (isLocalDecoratingEnabled(config)) {
71
+ if (isLocalDecoratingEnabled(config)) {
99
72
  args[1] += agent.getNRLinkingMetadata()
100
73
  }
101
74
 
@@ -107,7 +80,10 @@ module.exports = function instrument(shim) {
107
80
  const logLine = asJson.apply(this, args)
108
81
 
109
82
  if (isLogForwardingEnabled(config, agent)) {
110
- agent.logs.add(logLine)
83
+ const chindings = this[symbols.chindingsSym]
84
+ const formatLogLine = reformatLogLine({ msg: args[1], logLine, agent, chindings, levelMap })
85
+
86
+ agent.logs.add(formatLogLine)
111
87
  }
112
88
 
113
89
  return logLine
@@ -119,14 +95,18 @@ module.exports = function instrument(shim) {
119
95
  * reformats error and assigns NR context data
120
96
  * to log line
121
97
  *
98
+ * @param logLine.logLine
122
99
  * @param {object} logLine log line
123
100
  * @param {object} metadata NR context data
124
101
  * @param {string} chindings serialized string of all common log line data
102
+ * @param logLine.args
103
+ * @param logLine.agent
104
+ * @param logLine.chindings
105
+ * @param logLine.msg
106
+ * @param logLine.levelMap
125
107
  */
126
- function reformatLogLine(logLine, metadata, chindings = '') {
127
- if (logLine.err) {
128
- reformatError(logLine)
129
- }
108
+ function reformatLogLine({ logLine, msg, agent, chindings = '', levelMap }) {
109
+ const metadata = agent.getLinkingMetadata()
130
110
 
131
111
  /**
132
112
  * pino adds this already for us at times
@@ -137,7 +117,24 @@ function reformatLogLine(logLine, metadata, chindings = '') {
137
117
  delete metadata.hostname
138
118
  }
139
119
 
140
- Object.assign(logLine, metadata)
120
+ const agentMeta = Object.assign({}, { timestamp: Date.now(), message: msg }, metadata)
121
+
122
+ /**
123
+ * A function that gets executed in `_toPayloadSync` of log aggregator.
124
+ * This will parse the serialized log line and then add the relevant NR
125
+ * context metadata and rename the time/msg keys to timestamp/message
126
+ */
127
+ return function formatLogLine() {
128
+ const formattedLog = JSON.parse(logLine)
129
+ if (formattedLog.err) {
130
+ reformatError(formattedLog)
131
+ }
132
+ Object.assign(formattedLog, agentMeta)
133
+ formattedLog.level = levelMap[formattedLog.level]
134
+ delete formattedLog.time
135
+ delete formattedLog.msg
136
+ return formattedLog
137
+ }
141
138
  }
142
139
 
143
140
  /**
@@ -150,7 +147,6 @@ function reformatLogLine(logLine, metadata, chindings = '') {
150
147
  function reformatError(logLine) {
151
148
  logLine['error.message'] = truncate(logLine.err.message)
152
149
  logLine['error.stack'] = truncate(logLine.err.stack)
153
- logLine['error.class'] =
154
- logLine.err.name === 'Error' ? logLine.err.constructor.name : logLine.err.name
150
+ logLine['error.class'] = logLine.err.type
155
151
  delete logLine.err
156
152
  }
@@ -29,8 +29,8 @@ module.exports = function instrument(agent, winston, _, shim) {
29
29
  shim.wrap(winston, 'createLogger', function wrapCreate(shim, createLogger) {
30
30
  return function createWrappedLogger() {
31
31
  const args = shim.argsToArray.apply(shim, arguments)
32
- const opts = args[0]
33
- if (!shim.isObject(opts) || isStream(opts)) {
32
+ const opts = args[0] || {}
33
+ if (isStream(opts)) {
34
34
  return createLogger.apply(this, args)
35
35
  }
36
36
 
@@ -64,7 +64,7 @@ module.exports = function instrument(agent, winston, _, shim) {
64
64
  function registerFormatter({ opts, agent, winston }) {
65
65
  const instrumentedFormatter = nrWinstonFormatter(agent, winston)
66
66
 
67
- if ('format' in opts) {
67
+ if (opts.format) {
68
68
  opts.format = winston.format.combine(instrumentedFormatter(), opts.format)
69
69
  } else {
70
70
  opts.format = instrumentedFormatter()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "8.13.0",
3
+ "version": "8.14.0",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [
@@ -180,7 +180,7 @@
180
180
  "@newrelic/eslint-config": "^0.0.3",
181
181
  "@newrelic/newrelic-oss-cli": "^0.1.2",
182
182
  "@newrelic/proxy": "^2.0.0",
183
- "@newrelic/test-utilities": "^6.5.3",
183
+ "@newrelic/test-utilities": "^6.5.5",
184
184
  "@octokit/rest": "^18.0.15",
185
185
  "@slack/bolt": "^3.7.0",
186
186
  "ajv": "^6.12.6",