@webpieces/bunyan 0.4.444 → 0.4.446

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/bunyan",
3
- "version": "0.4.444",
3
+ "version": "0.4.446",
4
4
  "description": "Node-only bunyan LoggerFactory backends for webpieces: Console (local pretty) + GCP (@google-cloud/logging-bunyan), auto-enriched with HeaderRegistry context keys",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -23,8 +23,8 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@webpieces/core-util": "0.4.444",
27
- "@webpieces/core-context": "0.4.444",
26
+ "@webpieces/core-util": "0.4.446",
27
+ "@webpieces/core-context": "0.4.446",
28
28
  "bunyan": "1.8.15",
29
29
  "@google-cloud/logging-bunyan": "5.1.0",
30
30
  "@types/bunyan": "1.8.11"
@@ -50,17 +50,13 @@ class BunyanLogger {
50
50
  }
51
51
  buildFields(err) {
52
52
  const fields = {};
53
- // No active RequestContext (startup, a background job, or an in-process call the caller did
54
- // not wrap) simply logs with no context fieldsan empty context is normal, not an error.
55
- // The in-process client's ApiClientFactory.requireActiveContext() throws precisely when a
56
- // request-path wrap is genuinely missing.
57
- if (!core_context_1.RequestContext.isActive()) {
58
- return fields;
59
- }
60
- // ONE loop, in HeaderRegistry.buildStructuredLogFields — the registry owns the keys and each
61
- // ContextKey masks its own value. Values may be OBJECTS (the `api` tag), so an object-valued key
62
- // nests into the structured payload (bunyan's GCP stream serializes fields) rather than being
63
- // dropped by the string-only buildLogFields.
53
+ // Called UNCONDITIONALLY (no active-context short-circuit): buildStructuredLogFields returns the
54
+ // build `version` even with NO active RequestContextplus the logged context keys when one IS
55
+ // active. Startup, background-job, and unwrapped-call lines are thus stamped with `version` too;
56
+ // an empty context is normal, not an error. (The in-process client's
57
+ // ApiClientFactory.requireActiveContext() still throws precisely when a request-path wrap is
58
+ // genuinely missing.) Values may be OBJECTS (the `api` tag), so an object-valued key nests into
59
+ // the structured payload rather than being dropped by the string-only buildLogFields.
64
60
  core_context_1.RequestContext.buildStructuredLogFields().forEach((value, name) => {
65
61
  fields[name] = value;
66
62
  });
@@ -1 +1 @@
1
- {"version":3,"file":"BunyanLogger.js","sourceRoot":"","sources":["../../../../../packages/logging/bunyan/src/BunyanLogger.ts"],"names":[],"mappings":";;;AAEA,0DAAyD;AACzD,+CAA4C;AAE5C;;;;;;;;;GASG;AACH,SAAS,cAAc,CAAC,GAAU;IAC9B,OAAO,IAAI,yBAAW,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAa,YAAY;IACQ;IAA7B,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAE/C,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAEO,WAAW,CAAC,GAAW;QAC3B,MAAM,MAAM,GAAkD,EAAE,CAAC;QACjE,4FAA4F;QAC5F,2FAA2F;QAC3F,0FAA0F;QAC1F,0CAA0C;QAC1C,IAAI,CAAC,6BAAc,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC7B,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,6FAA6F;QAC7F,iGAAiG;QACjG,8FAA8F;QAC9F,6CAA6C;QAC7C,6BAAc,CAAC,wBAAwB,EAAE,CAAC,OAAO,CAAC,CAAC,KAAsB,EAAE,IAAY,EAAE,EAAE;YACvF,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,IAAI,GAAG,EAAE,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AA7CD,oCA6CC","sourcesContent":["import type Logger from 'bunyan';\nimport type { Logger as WpLogger } from '@webpieces/core-util';\nimport { RequestContext } from '@webpieces/core-context';\nimport { LoggedError } from './LoggedError';\n\n/**\n * The error, whole. There is deliberately NO size guard here any more.\n *\n * This used to truncate an error over 100KB down to 5 stack frames and a 100-character message, to\n * keep one giant stack from blowing past Cloud Logging's per-entry limit. That traded the wrong\n * thing away: a stack trace big enough to trip the limit is precisely the one worth reading, and it\n * arrived pre-shredded. The GCP stream now SPLITS an oversized record across several complete\n * records instead (see ChunkingRawStream), so the whole stack survives and nothing is lost — which\n * makes truncating here strictly harmful.\n */\nfunction normalizeError(err: Error): LoggedError {\n return new LoggedError(err.name, err.message, err.stack);\n}\n\n/**\n * BunyanLogger - a webpieces {@link WpLogger} backed by a bunyan logger (one per\n * name, created as a bunyan child carrying `loggerName`). On every call it reads\n * the logged HeaderRegistry keys DIRECTLY from the active {@link RequestContext}\n * (secured values masked) into the bunyan fields object, and normalizes an optional\n * Error into `err: { name, message, stack }` — matching the tested trytami AppLogger.\n * The GCP stream then serializes those fields into the structured log payload.\n *\n * This context-reading is INLINED here (and duplicated in the winston logger) on\n * purpose: it must run ONLY when a bunyan/winston backend is installed, never for\n * the plain ConsoleLogger — so it does not belong on RequestContext.\n */\nexport class BunyanLogger implements WpLogger {\n constructor(private readonly bunyan: Logger) {}\n\n trace(message: string, err?: Error): void {\n this.bunyan.trace(this.buildFields(err), message);\n }\n\n debug(message: string, err?: Error): void {\n this.bunyan.debug(this.buildFields(err), message);\n }\n\n info(message: string, err?: Error): void {\n this.bunyan.info(this.buildFields(err), message);\n }\n\n warn(message: string, err?: Error): void {\n this.bunyan.warn(this.buildFields(err), message);\n }\n\n error(message: string, err?: Error): void {\n this.bunyan.error(this.buildFields(err), message);\n }\n\n private buildFields(err?: Error): Record<string, string | object | LoggedError> {\n const fields: Record<string, string | object | LoggedError> = {};\n // No active RequestContext (startup, a background job, or an in-process call the caller did\n // not wrap) simply logs with no context fields an empty context is normal, not an error.\n // The in-process client's ApiClientFactory.requireActiveContext() throws precisely when a\n // request-path wrap is genuinely missing.\n if (!RequestContext.isActive()) {\n return fields;\n }\n\n // ONE loop, in HeaderRegistry.buildStructuredLogFields — the registry owns the keys and each\n // ContextKey masks its own value. Values may be OBJECTS (the `api` tag), so an object-valued key\n // nests into the structured payload (bunyan's GCP stream serializes fields) rather than being\n // dropped by the string-only buildLogFields.\n RequestContext.buildStructuredLogFields().forEach((value: string | object, name: string) => {\n fields[name] = value;\n });\n if (err) {\n fields['err'] = normalizeError(err);\n }\n return fields;\n }\n}\n"]}
1
+ {"version":3,"file":"BunyanLogger.js","sourceRoot":"","sources":["../../../../../packages/logging/bunyan/src/BunyanLogger.ts"],"names":[],"mappings":";;;AAEA,0DAAyD;AACzD,+CAA4C;AAE5C;;;;;;;;;GASG;AACH,SAAS,cAAc,CAAC,GAAU;IAC9B,OAAO,IAAI,yBAAW,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAa,YAAY;IACQ;IAA7B,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAE/C,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAEO,WAAW,CAAC,GAAW;QAC3B,MAAM,MAAM,GAAkD,EAAE,CAAC;QACjE,iGAAiG;QACjG,gGAAgG;QAChG,iGAAiG;QACjG,qEAAqE;QACrE,6FAA6F;QAC7F,gGAAgG;QAChG,sFAAsF;QACtF,6BAAc,CAAC,wBAAwB,EAAE,CAAC,OAAO,CAAC,CAAC,KAAsB,EAAE,IAAY,EAAE,EAAE;YACvF,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,IAAI,GAAG,EAAE,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAxCD,oCAwCC","sourcesContent":["import type Logger from 'bunyan';\nimport type { Logger as WpLogger } from '@webpieces/core-util';\nimport { RequestContext } from '@webpieces/core-context';\nimport { LoggedError } from './LoggedError';\n\n/**\n * The error, whole. There is deliberately NO size guard here any more.\n *\n * This used to truncate an error over 100KB down to 5 stack frames and a 100-character message, to\n * keep one giant stack from blowing past Cloud Logging's per-entry limit. That traded the wrong\n * thing away: a stack trace big enough to trip the limit is precisely the one worth reading, and it\n * arrived pre-shredded. The GCP stream now SPLITS an oversized record across several complete\n * records instead (see ChunkingRawStream), so the whole stack survives and nothing is lost — which\n * makes truncating here strictly harmful.\n */\nfunction normalizeError(err: Error): LoggedError {\n return new LoggedError(err.name, err.message, err.stack);\n}\n\n/**\n * BunyanLogger - a webpieces {@link WpLogger} backed by a bunyan logger (one per\n * name, created as a bunyan child carrying `loggerName`). On every call it reads\n * the logged HeaderRegistry keys DIRECTLY from the active {@link RequestContext}\n * (secured values masked) into the bunyan fields object, and normalizes an optional\n * Error into `err: { name, message, stack }` — matching the tested trytami AppLogger.\n * The GCP stream then serializes those fields into the structured log payload.\n *\n * This context-reading is INLINED here (and duplicated in the winston logger) on\n * purpose: it must run ONLY when a bunyan/winston backend is installed, never for\n * the plain ConsoleLogger — so it does not belong on RequestContext.\n */\nexport class BunyanLogger implements WpLogger {\n constructor(private readonly bunyan: Logger) {}\n\n trace(message: string, err?: Error): void {\n this.bunyan.trace(this.buildFields(err), message);\n }\n\n debug(message: string, err?: Error): void {\n this.bunyan.debug(this.buildFields(err), message);\n }\n\n info(message: string, err?: Error): void {\n this.bunyan.info(this.buildFields(err), message);\n }\n\n warn(message: string, err?: Error): void {\n this.bunyan.warn(this.buildFields(err), message);\n }\n\n error(message: string, err?: Error): void {\n this.bunyan.error(this.buildFields(err), message);\n }\n\n private buildFields(err?: Error): Record<string, string | object | LoggedError> {\n const fields: Record<string, string | object | LoggedError> = {};\n // Called UNCONDITIONALLY (no active-context short-circuit): buildStructuredLogFields returns the\n // build `version` even with NO active RequestContext — plus the logged context keys when one IS\n // active. Startup, background-job, and unwrapped-call lines are thus stamped with `version` too;\n // an empty context is normal, not an error. (The in-process client's\n // ApiClientFactory.requireActiveContext() still throws precisely when a request-path wrap is\n // genuinely missing.) Values may be OBJECTS (the `api` tag), so an object-valued key nests into\n // the structured payload rather than being dropped by the string-only buildLogFields.\n RequestContext.buildStructuredLogFields().forEach((value: string | object, name: string) => {\n fields[name] = value;\n });\n if (err) {\n fields['err'] = normalizeError(err);\n }\n return fields;\n }\n}\n"]}