@webpieces/winston 0.4.396 → 0.4.397
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 +3 -3
- package/src/ChunkingConsoleTransport.d.ts +48 -0
- package/src/ChunkingConsoleTransport.js +109 -0
- package/src/ChunkingConsoleTransport.js.map +1 -0
- package/src/WinstonFactoryBase.d.ts +8 -1
- package/src/WinstonFactoryBase.js +8 -2
- package/src/WinstonFactoryBase.js.map +1 -1
- package/src/WinstonGcpFactory.d.ts +6 -0
- package/src/WinstonGcpFactory.js +8 -1
- package/src/WinstonGcpFactory.js.map +1 -1
- package/src/index.d.ts +1 -0
- package/src/index.js +3 -1
- package/src/index.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/winston",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.397",
|
|
4
4
|
"description": "Node-only winston LoggerFactory backends for webpieces: Console (local pretty) + GCP (Cloud Run stdout JSON), 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.
|
|
27
|
-
"@webpieces/core-context": "0.4.
|
|
26
|
+
"@webpieces/core-util": "0.4.397",
|
|
27
|
+
"@webpieces/core-context": "0.4.397",
|
|
28
28
|
"winston": "3.11.0",
|
|
29
29
|
"logform": "2.7.0",
|
|
30
30
|
"safe-stable-stringify": "2.5.0"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { transports } from 'winston';
|
|
2
|
+
import type { TransformableInfo } from 'logform';
|
|
3
|
+
/**
|
|
4
|
+
* ChunkingConsoleTransport - a winston Console transport that SPLITS an oversized record into
|
|
5
|
+
* several complete records instead of letting GCP silently drop it.
|
|
6
|
+
*
|
|
7
|
+
* WHY A TRANSPORT, not the WinstonLogger wrapper — two reasons, both decisive:
|
|
8
|
+
*
|
|
9
|
+
* 1. COVERAGE. WinstonFactoryBase sets `handleExceptions: true` / `handleRejections: true`, and
|
|
10
|
+
* those lines are emitted by winston itself, bypassing WinstonLogger entirely. An uncaught
|
|
11
|
+
* exception carrying a huge stack trace is exactly the log you cannot afford to lose, so the
|
|
12
|
+
* guard has to sit below the wrapper.
|
|
13
|
+
* 2. EXACT MEASUREMENT. A transport runs AFTER the format chain, so `info[MESSAGE]` is the fully
|
|
14
|
+
* rendered line — envelope and all (severity, svcName, requestId, tenantId, the `api` tag). We
|
|
15
|
+
* measure the real thing rather than estimating the caller's contribution and hoping.
|
|
16
|
+
*
|
|
17
|
+
* WHY IT RE-SERIALIZES rather than slicing `info[MESSAGE]`: a fragment of a JSON line is not valid
|
|
18
|
+
* JSON, so the logging agent would file each piece as an unparsed `textPayload` and every structured
|
|
19
|
+
* field would be lost. Each emitted piece must be a COMPLETE, parseable record — so we chunk the
|
|
20
|
+
* oversized FIELDS and rebuild N records, each tagged with a shared {@link LogChunkInfo}.
|
|
21
|
+
*
|
|
22
|
+
* GCP-ONLY: wired in by WinstonGcpFactory. WinstonConsoleFactory keeps a plain Console transport —
|
|
23
|
+
* a dev terminal has no size limit and splitting there would only hurt readability.
|
|
24
|
+
*
|
|
25
|
+
* The common case is untouched: a record within budget goes straight to `super.log` and is
|
|
26
|
+
* byte-identical to what it was before this class existed.
|
|
27
|
+
*/
|
|
28
|
+
export declare class ChunkingConsoleTransport extends transports.Console {
|
|
29
|
+
private readonly budgetBytes;
|
|
30
|
+
constructor(budgetBytes?: number);
|
|
31
|
+
log(info: TransformableInfo, callback: () => void): void;
|
|
32
|
+
/**
|
|
33
|
+
* Hand one finished record to the real Console transport. winston types `log` as optional on the
|
|
34
|
+
* base, so we resolve it once here rather than sprinkling `?.` at the call sites — and if it were
|
|
35
|
+
* ever truly absent we still fire the callback, because swallowing it would hang the logger.
|
|
36
|
+
*/
|
|
37
|
+
private writeThrough;
|
|
38
|
+
/** Split the oversized record's fields and emit one complete record per piece. */
|
|
39
|
+
private logChunked;
|
|
40
|
+
/**
|
|
41
|
+
* Rebuild one complete record: every original field, with `message`/`errStack` replaced by this
|
|
42
|
+
* piece and a `logChunk` tag added, re-serialized exactly the way format.json() would (same
|
|
43
|
+
* safe-stable-stringify, so circular refs stay "[Circular]").
|
|
44
|
+
*/
|
|
45
|
+
private buildRecord;
|
|
46
|
+
/** The fully-rendered line the format chain produced (what a transport writes). */
|
|
47
|
+
private rendered;
|
|
48
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChunkingConsoleTransport = void 0;
|
|
4
|
+
const winston_1 = require("winston");
|
|
5
|
+
const safe_stable_stringify_1 = require("safe-stable-stringify");
|
|
6
|
+
const core_util_1 = require("@webpieces/core-util");
|
|
7
|
+
// winston's own symbol (not a DI token): it holds the FINAL rendered line — what format.json()
|
|
8
|
+
// produced and what a transport actually writes — as distinct from the `message` string PROPERTY,
|
|
9
|
+
// which is the caller's text. We need both: the symbol to measure, the property to re-chunk.
|
|
10
|
+
// webpieces-disable no-symbol-di-tokens -- winston's documented internal record key (Symbol.for('message')), not a DI token
|
|
11
|
+
const MESSAGE = Symbol.for('message');
|
|
12
|
+
/**
|
|
13
|
+
* ChunkingConsoleTransport - a winston Console transport that SPLITS an oversized record into
|
|
14
|
+
* several complete records instead of letting GCP silently drop it.
|
|
15
|
+
*
|
|
16
|
+
* WHY A TRANSPORT, not the WinstonLogger wrapper — two reasons, both decisive:
|
|
17
|
+
*
|
|
18
|
+
* 1. COVERAGE. WinstonFactoryBase sets `handleExceptions: true` / `handleRejections: true`, and
|
|
19
|
+
* those lines are emitted by winston itself, bypassing WinstonLogger entirely. An uncaught
|
|
20
|
+
* exception carrying a huge stack trace is exactly the log you cannot afford to lose, so the
|
|
21
|
+
* guard has to sit below the wrapper.
|
|
22
|
+
* 2. EXACT MEASUREMENT. A transport runs AFTER the format chain, so `info[MESSAGE]` is the fully
|
|
23
|
+
* rendered line — envelope and all (severity, svcName, requestId, tenantId, the `api` tag). We
|
|
24
|
+
* measure the real thing rather than estimating the caller's contribution and hoping.
|
|
25
|
+
*
|
|
26
|
+
* WHY IT RE-SERIALIZES rather than slicing `info[MESSAGE]`: a fragment of a JSON line is not valid
|
|
27
|
+
* JSON, so the logging agent would file each piece as an unparsed `textPayload` and every structured
|
|
28
|
+
* field would be lost. Each emitted piece must be a COMPLETE, parseable record — so we chunk the
|
|
29
|
+
* oversized FIELDS and rebuild N records, each tagged with a shared {@link LogChunkInfo}.
|
|
30
|
+
*
|
|
31
|
+
* GCP-ONLY: wired in by WinstonGcpFactory. WinstonConsoleFactory keeps a plain Console transport —
|
|
32
|
+
* a dev terminal has no size limit and splitting there would only hurt readability.
|
|
33
|
+
*
|
|
34
|
+
* The common case is untouched: a record within budget goes straight to `super.log` and is
|
|
35
|
+
* byte-identical to what it was before this class existed.
|
|
36
|
+
*/
|
|
37
|
+
class ChunkingConsoleTransport extends winston_1.transports.Console {
|
|
38
|
+
budgetBytes;
|
|
39
|
+
constructor(budgetBytes = core_util_1.GCP_LOG_BUDGET_BYTES) {
|
|
40
|
+
super();
|
|
41
|
+
this.budgetBytes = budgetBytes;
|
|
42
|
+
}
|
|
43
|
+
log(info, callback) {
|
|
44
|
+
const rendered = this.rendered(info);
|
|
45
|
+
if (core_util_1.LogChunker.byteLength(rendered) <= this.budgetBytes) {
|
|
46
|
+
// The overwhelmingly common path — unchanged behaviour, no extra work beyond one measure.
|
|
47
|
+
this.writeThrough(info, callback);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.logChunked(info, rendered, callback);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Hand one finished record to the real Console transport. winston types `log` as optional on the
|
|
54
|
+
* base, so we resolve it once here rather than sprinkling `?.` at the call sites — and if it were
|
|
55
|
+
* ever truly absent we still fire the callback, because swallowing it would hang the logger.
|
|
56
|
+
*/
|
|
57
|
+
writeThrough(info, callback) {
|
|
58
|
+
const parentLog = super.log;
|
|
59
|
+
if (!parentLog) {
|
|
60
|
+
callback();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
parentLog.call(this, info, callback);
|
|
64
|
+
}
|
|
65
|
+
/** Split the oversized record's fields and emit one complete record per piece. */
|
|
66
|
+
logChunked(info, rendered, callback) {
|
|
67
|
+
const message = typeof info.message === 'string' ? info.message : String(info.message ?? '');
|
|
68
|
+
const stack = typeof info['errStack'] === 'string' ? info['errStack'] : undefined;
|
|
69
|
+
const budgets = core_util_1.LogChunker.chunkBudgets(core_util_1.LogChunker.byteLength(rendered), this.budgetBytes, message, stack ?? '');
|
|
70
|
+
const messageChunks = core_util_1.LogChunker.chunk(message, budgets.firstBudget);
|
|
71
|
+
const stackChunks = core_util_1.LogChunker.chunk(stack ?? '', budgets.secondBudget);
|
|
72
|
+
const uid = core_util_1.LogChunker.newUid();
|
|
73
|
+
const total = Math.max(messageChunks.length, stackChunks.length);
|
|
74
|
+
for (let index = 0; index < total; index++) {
|
|
75
|
+
const piece = this.buildRecord(info, messageChunks[index] ?? '', stack === undefined ? undefined : (stackChunks[index] ?? ''), new core_util_1.LogChunkInfo(uid, index, total));
|
|
76
|
+
// Only the LAST piece completes the write; winston expects exactly one callback per log().
|
|
77
|
+
this.writeThrough(piece, index === total - 1 ? callback : () => undefined);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Rebuild one complete record: every original field, with `message`/`errStack` replaced by this
|
|
82
|
+
* piece and a `logChunk` tag added, re-serialized exactly the way format.json() would (same
|
|
83
|
+
* safe-stable-stringify, so circular refs stay "[Circular]").
|
|
84
|
+
*/
|
|
85
|
+
buildRecord(info, messageChunk, stackChunk, chunkInfo) {
|
|
86
|
+
const fields = {};
|
|
87
|
+
// Object.keys skips winston's symbol keys, so this is exactly the set format.json() serializes.
|
|
88
|
+
for (const key of Object.keys(info)) {
|
|
89
|
+
fields[key] = info[key];
|
|
90
|
+
}
|
|
91
|
+
fields['message'] = messageChunk;
|
|
92
|
+
if (stackChunk !== undefined) {
|
|
93
|
+
fields['errStack'] = stackChunk;
|
|
94
|
+
}
|
|
95
|
+
fields['logChunk'] = chunkInfo;
|
|
96
|
+
// Object.assign copies own enumerable SYMBOL keys too, so winston's LEVEL symbol (which the
|
|
97
|
+
// Console transport reads) survives; then we overwrite the rendered line with this piece's.
|
|
98
|
+
const piece = Object.assign({}, info, fields);
|
|
99
|
+
piece[MESSAGE] = (0, safe_stable_stringify_1.stringify)(fields) ?? '';
|
|
100
|
+
return piece;
|
|
101
|
+
}
|
|
102
|
+
/** The fully-rendered line the format chain produced (what a transport writes). */
|
|
103
|
+
rendered(info) {
|
|
104
|
+
const message = info[MESSAGE];
|
|
105
|
+
return typeof message === 'string' ? message : String(message ?? '');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.ChunkingConsoleTransport = ChunkingConsoleTransport;
|
|
109
|
+
//# sourceMappingURL=ChunkingConsoleTransport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChunkingConsoleTransport.js","sourceRoot":"","sources":["../../../../../packages/logging/winston/src/ChunkingConsoleTransport.ts"],"names":[],"mappings":"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","sourcesContent":["import { transports } from 'winston';\nimport type { TransformableInfo } from 'logform';\nimport { stringify as safeStringify } from 'safe-stable-stringify';\nimport { GCP_LOG_BUDGET_BYTES, LogChunker, LogChunkInfo } from '@webpieces/core-util';\n\n// winston's own symbol (not a DI token): it holds the FINAL rendered line — what format.json()\n// produced and what a transport actually writes — as distinct from the `message` string PROPERTY,\n// which is the caller's text. We need both: the symbol to measure, the property to re-chunk.\n// webpieces-disable no-symbol-di-tokens -- winston's documented internal record key (Symbol.for('message')), not a DI token\nconst MESSAGE = Symbol.for('message');\n\n// JSON-shaped value (the widest thing a winston record field can hold), used instead of\n// `any`/`unknown` which the code rules disallow. Mirrors the JsonValue in format.ts.\ntype JsonValue = string | number | boolean | bigint | object | null | undefined;\n\n/**\n * ChunkingConsoleTransport - a winston Console transport that SPLITS an oversized record into\n * several complete records instead of letting GCP silently drop it.\n *\n * WHY A TRANSPORT, not the WinstonLogger wrapper — two reasons, both decisive:\n *\n * 1. COVERAGE. WinstonFactoryBase sets `handleExceptions: true` / `handleRejections: true`, and\n * those lines are emitted by winston itself, bypassing WinstonLogger entirely. An uncaught\n * exception carrying a huge stack trace is exactly the log you cannot afford to lose, so the\n * guard has to sit below the wrapper.\n * 2. EXACT MEASUREMENT. A transport runs AFTER the format chain, so `info[MESSAGE]` is the fully\n * rendered line — envelope and all (severity, svcName, requestId, tenantId, the `api` tag). We\n * measure the real thing rather than estimating the caller's contribution and hoping.\n *\n * WHY IT RE-SERIALIZES rather than slicing `info[MESSAGE]`: a fragment of a JSON line is not valid\n * JSON, so the logging agent would file each piece as an unparsed `textPayload` and every structured\n * field would be lost. Each emitted piece must be a COMPLETE, parseable record — so we chunk the\n * oversized FIELDS and rebuild N records, each tagged with a shared {@link LogChunkInfo}.\n *\n * GCP-ONLY: wired in by WinstonGcpFactory. WinstonConsoleFactory keeps a plain Console transport —\n * a dev terminal has no size limit and splitting there would only hurt readability.\n *\n * The common case is untouched: a record within budget goes straight to `super.log` and is\n * byte-identical to what it was before this class existed.\n */\nexport class ChunkingConsoleTransport extends transports.Console {\n private readonly budgetBytes: number;\n\n constructor(budgetBytes: number = GCP_LOG_BUDGET_BYTES) {\n super();\n this.budgetBytes = budgetBytes;\n }\n\n override log(info: TransformableInfo, callback: () => void): void {\n const rendered = this.rendered(info);\n if (LogChunker.byteLength(rendered) <= this.budgetBytes) {\n // The overwhelmingly common path — unchanged behaviour, no extra work beyond one measure.\n this.writeThrough(info, callback);\n return;\n }\n this.logChunked(info, rendered, callback);\n }\n\n /**\n * Hand one finished record to the real Console transport. winston types `log` as optional on the\n * base, so we resolve it once here rather than sprinkling `?.` at the call sites — and if it were\n * ever truly absent we still fire the callback, because swallowing it would hang the logger.\n */\n private writeThrough(info: TransformableInfo, callback: () => void): void {\n const parentLog = super.log;\n if (!parentLog) {\n callback();\n return;\n }\n parentLog.call(this, info, callback);\n }\n\n /** Split the oversized record's fields and emit one complete record per piece. */\n private logChunked(info: TransformableInfo, rendered: string, callback: () => void): void {\n const message = typeof info.message === 'string' ? info.message : String(info.message ?? '');\n const stack = typeof info['errStack'] === 'string' ? info['errStack'] : undefined;\n\n const budgets = LogChunker.chunkBudgets(\n LogChunker.byteLength(rendered), this.budgetBytes, message, stack ?? '',\n );\n const messageChunks = LogChunker.chunk(message, budgets.firstBudget);\n const stackChunks = LogChunker.chunk(stack ?? '', budgets.secondBudget);\n\n const uid = LogChunker.newUid();\n const total = Math.max(messageChunks.length, stackChunks.length);\n for (let index = 0; index < total; index++) {\n const piece = this.buildRecord(\n info,\n messageChunks[index] ?? '',\n stack === undefined ? undefined : (stackChunks[index] ?? ''),\n new LogChunkInfo(uid, index, total),\n );\n // Only the LAST piece completes the write; winston expects exactly one callback per log().\n this.writeThrough(piece, index === total - 1 ? callback : (): void => undefined);\n }\n }\n\n /**\n * Rebuild one complete record: every original field, with `message`/`errStack` replaced by this\n * piece and a `logChunk` tag added, re-serialized exactly the way format.json() would (same\n * safe-stable-stringify, so circular refs stay \"[Circular]\").\n */\n private buildRecord(\n info: TransformableInfo,\n messageChunk: string,\n stackChunk: string | undefined,\n chunkInfo: LogChunkInfo,\n ): TransformableInfo {\n const fields: Record<string, JsonValue> = {};\n // Object.keys skips winston's symbol keys, so this is exactly the set format.json() serializes.\n for (const key of Object.keys(info)) {\n fields[key] = (info as Record<string, JsonValue>)[key];\n }\n fields['message'] = messageChunk;\n if (stackChunk !== undefined) {\n fields['errStack'] = stackChunk;\n }\n fields['logChunk'] = chunkInfo;\n\n // Object.assign copies own enumerable SYMBOL keys too, so winston's LEVEL symbol (which the\n // Console transport reads) survives; then we overwrite the rendered line with this piece's.\n const piece = Object.assign({}, info, fields) as TransformableInfo;\n (piece as Record<symbol, JsonValue>)[MESSAGE] = safeStringify(fields) ?? '';\n return piece;\n }\n\n /** The fully-rendered line the format chain produced (what a transport writes). */\n private rendered(info: TransformableInfo): string {\n const message = (info as Record<symbol, JsonValue>)[MESSAGE];\n return typeof message === 'string' ? message : String(message ?? '');\n }\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type Transport from 'winston-transport';
|
|
1
2
|
import type { Format } from 'logform';
|
|
2
3
|
import type { Logger, LoggerFactory } from '@webpieces/core-util';
|
|
3
4
|
/**
|
|
@@ -17,6 +18,12 @@ import type { Logger, LoggerFactory } from '@webpieces/core-util';
|
|
|
17
18
|
export declare abstract class WinstonFactoryBase implements LoggerFactory {
|
|
18
19
|
private readonly base;
|
|
19
20
|
private readonly loggers;
|
|
20
|
-
|
|
21
|
+
/**
|
|
22
|
+
* @param transport - the sink to write through. Defaults to a plain Console; the GCP subclass
|
|
23
|
+
* passes a {@link ChunkingConsoleTransport} instead, because only there does a per-entry size
|
|
24
|
+
* limit exist. Taking the whole transport (rather than a size knob) keeps the size limit a fact
|
|
25
|
+
* about the SINK, which is where it actually lives — a dev terminal has no such limit.
|
|
26
|
+
*/
|
|
27
|
+
protected constructor(finalFormat: Format, transport?: Transport);
|
|
21
28
|
getLogger(name: string): Logger;
|
|
22
29
|
}
|
|
@@ -21,7 +21,13 @@ const WinstonLogger_1 = require("./WinstonLogger");
|
|
|
21
21
|
class WinstonFactoryBase {
|
|
22
22
|
base;
|
|
23
23
|
loggers = new Map();
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* @param transport - the sink to write through. Defaults to a plain Console; the GCP subclass
|
|
26
|
+
* passes a {@link ChunkingConsoleTransport} instead, because only there does a per-entry size
|
|
27
|
+
* limit exist. Taking the whole transport (rather than a size knob) keeps the size limit a fact
|
|
28
|
+
* about the SINK, which is where it actually lives — a dev terminal has no such limit.
|
|
29
|
+
*/
|
|
30
|
+
constructor(finalFormat, transport) {
|
|
25
31
|
// Read at STARTUP (this ctor runs while booting), so a forgotten ServiceInfo.setInfo(...)
|
|
26
32
|
// fails the deploy rather than shipping logs that cannot say which build emitted them.
|
|
27
33
|
const defaultMeta = {
|
|
@@ -32,7 +38,7 @@ class WinstonFactoryBase {
|
|
|
32
38
|
this.base = (0, winston_1.createLogger)({
|
|
33
39
|
format: finalFormat,
|
|
34
40
|
defaultMeta: defaultMeta,
|
|
35
|
-
transports: [new winston_1.transports.Console()],
|
|
41
|
+
transports: [transport ?? new winston_1.transports.Console()],
|
|
36
42
|
handleExceptions: true,
|
|
37
43
|
handleRejections: true,
|
|
38
44
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WinstonFactoryBase.js","sourceRoot":"","sources":["../../../../../packages/logging/winston/src/WinstonFactoryBase.ts"],"names":[],"mappings":";;;AAAA,qCAAmD;
|
|
1
|
+
{"version":3,"file":"WinstonFactoryBase.js","sourceRoot":"","sources":["../../../../../packages/logging/winston/src/WinstonFactoryBase.ts"],"names":[],"mappings":";;;AAAA,qCAAmD;AAKnD,oDAAmD;AACnD,mDAAgD;AAEhD;;;;;;;;;;;;;GAaG;AACH,MAAsB,kBAAkB;IACnB,IAAI,CAAc;IAClB,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAErD;;;;;OAKG;IACH,YAAsB,WAAmB,EAAE,SAAqB;QAC5D,0FAA0F;QAC1F,uFAAuF;QACvF,MAAM,WAAW,GAA2B;YACxC,OAAO,EAAE,uBAAW,CAAC,OAAO,EAAE;YAC9B,OAAO,EAAE,uBAAW,CAAC,UAAU,EAAE;SACpC,CAAC;QAEF,+EAA+E;QAC/E,IAAI,CAAC,IAAI,GAAG,IAAA,sBAAY,EAAC;YACrB,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,WAAW;YACxB,UAAU,EAAE,CAAC,SAAS,IAAI,IAAI,oBAAU,CAAC,OAAO,EAAE,CAAC;YACnD,gBAAgB,EAAE,IAAI;YACtB,gBAAgB,EAAE,IAAI;SACzB,CAAC,CAAC;IACP,CAAC;IAED,SAAS,CAAC,IAAY;QAClB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,GAAG,IAAI,6BAAa,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAClE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AApCD,gDAoCC","sourcesContent":["import { createLogger, transports } from 'winston';\nimport type { Logger as WinstonBase } from 'winston';\nimport type Transport from 'winston-transport';\nimport type { Format } from 'logform';\nimport type { Logger, LoggerFactory } from '@webpieces/core-util';\nimport { ServiceInfo } from '@webpieces/core-util';\nimport { WinstonLogger } from './WinstonLogger';\n\n/**\n * WinstonFactoryBase - shared plumbing for the winston {@link LoggerFactory}\n * backends. Builds ONE underlying winston logger (a single `Console` transport,\n * handleExceptions/Rejections on) with the caller-chosen format stack, then hands\n * out a cached {@link WinstonLogger} per name (each a winston child carrying\n * `loggerName`). Subclasses differ only in the format stack they pass up.\n *\n * Every line carries `svcName` + `version` from {@link ServiceInfo}. Neither used to be a property\n * of the SERVICE: winston has no mandatory logger name (so this backend emitted none — a winston\n * service was distinguishable only by GCP's own resource labels), and the version lived here as an\n * optional `svcGitHash` factory option that bunyan had no counterpart for. Both now come from the\n * ONE {@link ServiceInfo}, so the fields on your logs no longer depend on which logging library the\n * app happened to pick. `version` is opaque — whatever string the app used to identify its build.\n */\nexport abstract class WinstonFactoryBase implements LoggerFactory {\n private readonly base: WinstonBase;\n private readonly loggers = new Map<string, Logger>();\n\n /**\n * @param transport - the sink to write through. Defaults to a plain Console; the GCP subclass\n * passes a {@link ChunkingConsoleTransport} instead, because only there does a per-entry size\n * limit exist. Taking the whole transport (rather than a size knob) keeps the size limit a fact\n * about the SINK, which is where it actually lives — a dev terminal has no such limit.\n */\n protected constructor(finalFormat: Format, transport?: Transport) {\n // Read at STARTUP (this ctor runs while booting), so a forgotten ServiceInfo.setInfo(...)\n // fails the deploy rather than shipping logs that cannot say which build emitted them.\n const defaultMeta: Record<string, string> = {\n svcName: ServiceInfo.getName(),\n version: ServiceInfo.getVersion(),\n };\n\n // No level set — we do NOT filter; that is winston's job (defaults to 'info').\n this.base = createLogger({\n format: finalFormat,\n defaultMeta: defaultMeta,\n transports: [transport ?? new transports.Console()],\n handleExceptions: true,\n handleRejections: true,\n });\n }\n\n getLogger(name: string): Logger {\n let logger = this.loggers.get(name);\n if (!logger) {\n logger = new WinstonLogger(this.base.child({ loggerName: name }));\n this.loggers.set(name, logger);\n }\n return logger;\n }\n}\n"]}
|
|
@@ -10,6 +10,12 @@ import { WinstonFactoryBase } from './WinstonFactoryBase';
|
|
|
10
10
|
*
|
|
11
11
|
* The service name + version come from {@link ServiceInfo}, which startup must have populated
|
|
12
12
|
* (this constructor reads them); they are NOT factory options.
|
|
13
|
+
*
|
|
14
|
+
* Writes through a {@link ChunkingConsoleTransport} rather than a plain Console, because THIS is the
|
|
15
|
+
* backend with a size limit: Cloud Logging caps a LogEntry at 256 KiB and — critically — an
|
|
16
|
+
* oversized jsonPayload entry is DROPPED, not truncated, with no error raised anywhere. A big
|
|
17
|
+
* response body or stack trace would simply never appear. The transport splits such a record into
|
|
18
|
+
* several complete, parseable records sharing a `jsonPayload.logChunk.uid`.
|
|
13
19
|
*/
|
|
14
20
|
export declare class WinstonGcpFactory extends WinstonFactoryBase {
|
|
15
21
|
constructor();
|
package/src/WinstonGcpFactory.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.WinstonGcpFactory = void 0;
|
|
4
4
|
const winston_1 = require("winston");
|
|
5
5
|
const WinstonFactoryBase_1 = require("./WinstonFactoryBase");
|
|
6
|
+
const ChunkingConsoleTransport_1 = require("./ChunkingConsoleTransport");
|
|
6
7
|
const format_1 = require("./format");
|
|
7
8
|
/**
|
|
8
9
|
* WinstonGcpFactory - the GCP/Cloud Run backend. Emits flat JSON to stdout; the
|
|
@@ -15,10 +16,16 @@ const format_1 = require("./format");
|
|
|
15
16
|
*
|
|
16
17
|
* The service name + version come from {@link ServiceInfo}, which startup must have populated
|
|
17
18
|
* (this constructor reads them); they are NOT factory options.
|
|
19
|
+
*
|
|
20
|
+
* Writes through a {@link ChunkingConsoleTransport} rather than a plain Console, because THIS is the
|
|
21
|
+
* backend with a size limit: Cloud Logging caps a LogEntry at 256 KiB and — critically — an
|
|
22
|
+
* oversized jsonPayload entry is DROPPED, not truncated, with no error raised anywhere. A big
|
|
23
|
+
* response body or stack trace would simply never appear. The transport splits such a record into
|
|
24
|
+
* several complete, parseable records sharing a `jsonPayload.logChunk.uid`.
|
|
18
25
|
*/
|
|
19
26
|
class WinstonGcpFactory extends WinstonFactoryBase_1.WinstonFactoryBase {
|
|
20
27
|
constructor() {
|
|
21
|
-
super(winston_1.format.combine((0, format_1.bigIntSafeFormat)(), (0, format_1.injectContextFormat)(), (0, format_1.severityFormat)(), winston_1.format.json()));
|
|
28
|
+
super(winston_1.format.combine((0, format_1.bigIntSafeFormat)(), (0, format_1.injectContextFormat)(), (0, format_1.severityFormat)(), winston_1.format.json()), new ChunkingConsoleTransport_1.ChunkingConsoleTransport());
|
|
22
29
|
}
|
|
23
30
|
}
|
|
24
31
|
exports.WinstonGcpFactory = WinstonGcpFactory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WinstonGcpFactory.js","sourceRoot":"","sources":["../../../../../packages/logging/winston/src/WinstonGcpFactory.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AACjC,6DAA0D;AAC1D,qCAAiF;AAEjF
|
|
1
|
+
{"version":3,"file":"WinstonGcpFactory.js","sourceRoot":"","sources":["../../../../../packages/logging/winston/src/WinstonGcpFactory.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AACjC,6DAA0D;AAC1D,yEAAsE;AACtE,qCAAiF;AAEjF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAa,iBAAkB,SAAQ,uCAAkB;IACrD;QACI,KAAK,CACD,gBAAM,CAAC,OAAO,CACV,IAAA,yBAAgB,GAAE,EAClB,IAAA,4BAAmB,GAAE,EACrB,IAAA,uBAAc,GAAE,EAChB,gBAAM,CAAC,IAAI,EAAE,CAChB,EACD,IAAI,mDAAwB,EAAE,CACjC,CAAC;IACN,CAAC;CACJ;AAZD,8CAYC","sourcesContent":["import { format } from 'winston';\nimport { WinstonFactoryBase } from './WinstonFactoryBase';\nimport { ChunkingConsoleTransport } from './ChunkingConsoleTransport';\nimport { bigIntSafeFormat, injectContextFormat, severityFormat } from './format';\n\n/**\n * WinstonGcpFactory - the GCP/Cloud Run backend. Emits flat JSON to stdout; the\n * Cloud Run / GKE logging agent natively parses it — `severity` + `message` lift\n * onto the LogEntry and every registered context key lands at top-level\n * jsonPayload.<name> (requestId, tenantId, …), filterable directly. There is NO\n * @google-cloud transport — correlation rides the webpieces context, read\n * DIRECTLY from RequestContext on each line. This matches the tested-in-GCP\n * onetablet/monorepo-nx1 core logger exactly.\n *\n * The service name + version come from {@link ServiceInfo}, which startup must have populated\n * (this constructor reads them); they are NOT factory options.\n *\n * Writes through a {@link ChunkingConsoleTransport} rather than a plain Console, because THIS is the\n * backend with a size limit: Cloud Logging caps a LogEntry at 256 KiB and — critically — an\n * oversized jsonPayload entry is DROPPED, not truncated, with no error raised anywhere. A big\n * response body or stack trace would simply never appear. The transport splits such a record into\n * several complete, parseable records sharing a `jsonPayload.logChunk.uid`.\n */\nexport class WinstonGcpFactory extends WinstonFactoryBase {\n constructor() {\n super(\n format.combine(\n bigIntSafeFormat(),\n injectContextFormat(),\n severityFormat(),\n format.json(),\n ),\n new ChunkingConsoleTransport(),\n );\n }\n}\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -33,5 +33,6 @@
|
|
|
33
33
|
*/
|
|
34
34
|
export { WinstonGcpFactory } from './WinstonGcpFactory';
|
|
35
35
|
export { WinstonConsoleFactory } from './WinstonConsoleFactory';
|
|
36
|
+
export { ChunkingConsoleTransport } from './ChunkingConsoleTransport';
|
|
36
37
|
export { WinstonLogger, LEVEL_TO_WINSTON } from './WinstonLogger';
|
|
37
38
|
export { LEVEL_TO_SEVERITY, bigIntSafeFormat, injectContextFormat, severityFormat, localPrettyFormat, } from './format';
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.localPrettyFormat = exports.severityFormat = exports.injectContextFormat = exports.bigIntSafeFormat = exports.LEVEL_TO_SEVERITY = exports.LEVEL_TO_WINSTON = exports.WinstonLogger = exports.WinstonConsoleFactory = exports.WinstonGcpFactory = void 0;
|
|
3
|
+
exports.localPrettyFormat = exports.severityFormat = exports.injectContextFormat = exports.bigIntSafeFormat = exports.LEVEL_TO_SEVERITY = exports.LEVEL_TO_WINSTON = exports.WinstonLogger = exports.ChunkingConsoleTransport = exports.WinstonConsoleFactory = exports.WinstonGcpFactory = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* @webpieces/winston
|
|
6
6
|
*
|
|
@@ -38,6 +38,8 @@ var WinstonGcpFactory_1 = require("./WinstonGcpFactory");
|
|
|
38
38
|
Object.defineProperty(exports, "WinstonGcpFactory", { enumerable: true, get: function () { return WinstonGcpFactory_1.WinstonGcpFactory; } });
|
|
39
39
|
var WinstonConsoleFactory_1 = require("./WinstonConsoleFactory");
|
|
40
40
|
Object.defineProperty(exports, "WinstonConsoleFactory", { enumerable: true, get: function () { return WinstonConsoleFactory_1.WinstonConsoleFactory; } });
|
|
41
|
+
var ChunkingConsoleTransport_1 = require("./ChunkingConsoleTransport");
|
|
42
|
+
Object.defineProperty(exports, "ChunkingConsoleTransport", { enumerable: true, get: function () { return ChunkingConsoleTransport_1.ChunkingConsoleTransport; } });
|
|
41
43
|
var WinstonLogger_1 = require("./WinstonLogger");
|
|
42
44
|
Object.defineProperty(exports, "WinstonLogger", { enumerable: true, get: function () { return WinstonLogger_1.WinstonLogger; } });
|
|
43
45
|
Object.defineProperty(exports, "LEVEL_TO_WINSTON", { enumerable: true, get: function () { return WinstonLogger_1.LEVEL_TO_WINSTON; } });
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/logging/winston/src/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,yDAAwD;AAA/C,sHAAA,iBAAiB,OAAA;AAC1B,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,iDAAkE;AAAzD,8GAAA,aAAa,OAAA;AAAE,iHAAA,gBAAgB,OAAA;AACxC,mCAMkB;AALd,2GAAA,iBAAiB,OAAA;AACjB,0GAAA,gBAAgB,OAAA;AAChB,6GAAA,mBAAmB,OAAA;AACnB,wGAAA,cAAc,OAAA;AACd,2GAAA,iBAAiB,OAAA","sourcesContent":["/**\n * @webpieces/winston\n *\n * Node-only winston {@link LoggerFactory} backends for webpieces. Install one at\n * startup via `LogManager.setFactory(...)`:\n *\n * ```ts\n * import { ServiceInfo } from '@webpieces/core-util';\n * import { WinstonGcpFactory, WinstonConsoleFactory } from '@webpieces/winston';\n *\n * ServiceInfo.setInfo('my-service', '2.1.0'); // FIRST — the factories read it in their constructor\n * const loggerFactory = process.env.K_SERVICE\n * ? new WinstonGcpFactory() // Cloud Run → stdout JSON\n * : new WinstonConsoleFactory(); // local → pretty console\n * // hand to setupRuntime(new RuntimeSetupOptions(loggerFactory, ...))\n * ```\n *\n * BREAKING (was `new WinstonFactoryOptions(svcGitHash)` passed to each factory): the version moved\n * to `ServiceInfo.setInfo(name, version)` in @webpieces/core-util, because it is a fact about the\n * SERVICE, not about winston — bunyan needs the same version and previously could not stamp one at\n * all. It is also no longer presumed to be a git SHA: `version` is opaque, so a project deploying\n * semver or CI build numbers is no longer misdescribed. Migration: delete the `WinstonFactoryOptions`\n * import, call `ServiceInfo.setInfo(<name>, <the same hash>)` before building the factory, and drop\n * the ctor argument. A forgotten call throws at startup. Note the field renamed `svcGitHash` →\n * `version`, so GCP log filters/alerts on `jsonPayload.svcGitHash` must be updated.\n *\n * Both backends auto-enrich every line with the logged context keys, read\n * DIRECTLY from the active RequestContext (@webpieces/core-context) on each line —\n * no ContextReader is threaded in. Every line also carries `svcName` + `version` from ServiceInfo,\n * though neither renders in the LOCAL pretty format (you know your own service, and can check git).\n *\n * @packageDocumentation\n */\nexport { WinstonGcpFactory } from './WinstonGcpFactory';\nexport { WinstonConsoleFactory } from './WinstonConsoleFactory';\nexport { WinstonLogger, LEVEL_TO_WINSTON } from './WinstonLogger';\nexport {\n LEVEL_TO_SEVERITY,\n bigIntSafeFormat,\n injectContextFormat,\n severityFormat,\n localPrettyFormat,\n} from './format';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/logging/winston/src/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,yDAAwD;AAA/C,sHAAA,iBAAiB,OAAA;AAC1B,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,uEAAsE;AAA7D,oIAAA,wBAAwB,OAAA;AACjC,iDAAkE;AAAzD,8GAAA,aAAa,OAAA;AAAE,iHAAA,gBAAgB,OAAA;AACxC,mCAMkB;AALd,2GAAA,iBAAiB,OAAA;AACjB,0GAAA,gBAAgB,OAAA;AAChB,6GAAA,mBAAmB,OAAA;AACnB,wGAAA,cAAc,OAAA;AACd,2GAAA,iBAAiB,OAAA","sourcesContent":["/**\n * @webpieces/winston\n *\n * Node-only winston {@link LoggerFactory} backends for webpieces. Install one at\n * startup via `LogManager.setFactory(...)`:\n *\n * ```ts\n * import { ServiceInfo } from '@webpieces/core-util';\n * import { WinstonGcpFactory, WinstonConsoleFactory } from '@webpieces/winston';\n *\n * ServiceInfo.setInfo('my-service', '2.1.0'); // FIRST — the factories read it in their constructor\n * const loggerFactory = process.env.K_SERVICE\n * ? new WinstonGcpFactory() // Cloud Run → stdout JSON\n * : new WinstonConsoleFactory(); // local → pretty console\n * // hand to setupRuntime(new RuntimeSetupOptions(loggerFactory, ...))\n * ```\n *\n * BREAKING (was `new WinstonFactoryOptions(svcGitHash)` passed to each factory): the version moved\n * to `ServiceInfo.setInfo(name, version)` in @webpieces/core-util, because it is a fact about the\n * SERVICE, not about winston — bunyan needs the same version and previously could not stamp one at\n * all. It is also no longer presumed to be a git SHA: `version` is opaque, so a project deploying\n * semver or CI build numbers is no longer misdescribed. Migration: delete the `WinstonFactoryOptions`\n * import, call `ServiceInfo.setInfo(<name>, <the same hash>)` before building the factory, and drop\n * the ctor argument. A forgotten call throws at startup. Note the field renamed `svcGitHash` →\n * `version`, so GCP log filters/alerts on `jsonPayload.svcGitHash` must be updated.\n *\n * Both backends auto-enrich every line with the logged context keys, read\n * DIRECTLY from the active RequestContext (@webpieces/core-context) on each line —\n * no ContextReader is threaded in. Every line also carries `svcName` + `version` from ServiceInfo,\n * though neither renders in the LOCAL pretty format (you know your own service, and can check git).\n *\n * @packageDocumentation\n */\nexport { WinstonGcpFactory } from './WinstonGcpFactory';\nexport { WinstonConsoleFactory } from './WinstonConsoleFactory';\nexport { ChunkingConsoleTransport } from './ChunkingConsoleTransport';\nexport { WinstonLogger, LEVEL_TO_WINSTON } from './WinstonLogger';\nexport {\n LEVEL_TO_SEVERITY,\n bigIntSafeFormat,\n injectContextFormat,\n severityFormat,\n localPrettyFormat,\n} from './format';\n"]}
|