@nestjs-labs/nestjs-pino-extra 1.0.0 → 1.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +93 -181
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -16
- package/dist/index.js.map +1 -1
- package/dist/module-option.d.ts +15 -5
- package/dist/module-option.d.ts.map +1 -0
- package/dist/module-option.js +44 -17
- package/dist/module-option.js.map +1 -1
- package/package.json +51 -34
- package/dist/formatters.d.ts +0 -10
- package/dist/formatters.js +0 -28
- package/dist/formatters.js.map +0 -1
- package/dist/options.d.ts +0 -5
- package/dist/options.js +0 -59
- package/dist/options.js.map +0 -1
- package/dist/serializers.d.ts +0 -8
- package/dist/serializers.js +0 -30
- package/dist/serializers.js.map +0 -1
- package/dist/streams.d.ts +0 -20
- package/dist/streams.js +0 -63
- package/dist/streams.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/formatters.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* add custom formatters
|
|
3
|
-
* https://github.com/pinojs/pino-http?tab=readme-ov-file#custom-formatters
|
|
4
|
-
*/
|
|
5
|
-
export declare function getOtelFormatters(spanIdKey?: string, traceIdKey?: string): {
|
|
6
|
-
level: (label: string) => {
|
|
7
|
-
level: string;
|
|
8
|
-
};
|
|
9
|
-
log(object: Record<string, unknown>): Record<string, unknown>;
|
|
10
|
-
};
|
package/dist/formatters.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getOtelFormatters = getOtelFormatters;
|
|
4
|
-
const api_1 = require("@opentelemetry/api");
|
|
5
|
-
/**
|
|
6
|
-
* add custom formatters
|
|
7
|
-
* https://github.com/pinojs/pino-http?tab=readme-ov-file#custom-formatters
|
|
8
|
-
*/
|
|
9
|
-
function getOtelFormatters(spanIdKey = 'spanId', traceIdKey = 'traceId') {
|
|
10
|
-
return {
|
|
11
|
-
level: (label) => {
|
|
12
|
-
return { level: label };
|
|
13
|
-
},
|
|
14
|
-
// Workaround for PinoInstrumentation (does not support latest version yet)
|
|
15
|
-
log(object) {
|
|
16
|
-
var _a;
|
|
17
|
-
const span = api_1.trace.getSpan(api_1.context.active());
|
|
18
|
-
if (!span)
|
|
19
|
-
return object;
|
|
20
|
-
const spanContext = (_a = api_1.trace.getSpan(api_1.context.active())) === null || _a === void 0 ? void 0 : _a.spanContext();
|
|
21
|
-
if (!spanContext)
|
|
22
|
-
return object;
|
|
23
|
-
const { spanId, traceId } = spanContext;
|
|
24
|
-
return { ...object, [spanIdKey]: spanId, [traceIdKey]: traceId };
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=formatters.js.map
|
package/dist/formatters.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":";;AAMA,8CAmBC;AAzBD,4CAAoD;AAEpD;;;GAGG;AACH,SAAgB,iBAAiB,CAC/B,YAAoB,QAAQ,EAC5B,aAAqB,SAAS;IAE9B,OAAO;QACL,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE;YACvB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC1B,CAAC;QACD,2EAA2E;QAC3E,GAAG,CAAC,MAA+B;;YACjC,MAAM,IAAI,GAAG,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7C,IAAI,CAAC,IAAI;gBAAE,OAAO,MAAM,CAAC;YACzB,MAAM,WAAW,GAAG,MAAA,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,CAAC,0CAAE,WAAW,EAAE,CAAC;YACnE,IAAI,CAAC,WAAW;gBAAE,OAAO,MAAM,CAAC;YAEhC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC;YACxC,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;QACnE,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { context, trace } from '@opentelemetry/api';\n\n/**\n * add custom formatters\n * https://github.com/pinojs/pino-http?tab=readme-ov-file#custom-formatters\n */\nexport function getOtelFormatters(\n spanIdKey: string = 'spanId',\n traceIdKey: string = 'traceId',\n) {\n return {\n level: (label: string) => {\n return { level: label };\n },\n // Workaround for PinoInstrumentation (does not support latest version yet)\n log(object: Record<string, unknown>) {\n const span = trace.getSpan(context.active());\n if (!span) return object;\n const spanContext = trace.getSpan(context.active())?.spanContext();\n if (!spanContext) return object;\n\n const { spanId, traceId } = spanContext;\n return { ...object, [spanIdKey]: spanId, [traceIdKey]: traceId };\n },\n };\n}\n"]}
|
package/dist/options.d.ts
DELETED
package/dist/options.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPinoHttpOption = getPinoHttpOption;
|
|
4
|
-
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
const pino_1 = require("pino");
|
|
6
|
-
const formatters_1 = require("./formatters");
|
|
7
|
-
const serializers_1 = require("./serializers");
|
|
8
|
-
/**
|
|
9
|
-
* get pino http option
|
|
10
|
-
*/
|
|
11
|
-
function getPinoHttpOption(level = 'info', spanIdKey = 'spanId', traceIdKey = 'traceId') {
|
|
12
|
-
return {
|
|
13
|
-
// https://getpino.io/#/docs/api?id=timestamp-boolean-function
|
|
14
|
-
// Change time value in production log.
|
|
15
|
-
// timestamp: stdTimeFunctions.isoTime,
|
|
16
|
-
level,
|
|
17
|
-
quietReqLogger: false,
|
|
18
|
-
timestamp: pino_1.default.stdTimeFunctions.isoTime,
|
|
19
|
-
customAttributeKeys: {
|
|
20
|
-
req: 'req',
|
|
21
|
-
res: 'res',
|
|
22
|
-
err: 'err',
|
|
23
|
-
responseTime: 'taken(ms)',
|
|
24
|
-
},
|
|
25
|
-
formatters: (0, formatters_1.getOtelFormatters)(spanIdKey, traceIdKey),
|
|
26
|
-
serializers: (0, serializers_1.getSerializers)(),
|
|
27
|
-
redact: {
|
|
28
|
-
paths: [
|
|
29
|
-
'password',
|
|
30
|
-
'reqBody.password',
|
|
31
|
-
'user.password',
|
|
32
|
-
'reqBody.user.password',
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
genReqId: function (req, res) {
|
|
36
|
-
var _a;
|
|
37
|
-
const reqId = (_a = req.id) !== null && _a !== void 0 ? _a : req.headers['x-request-id'];
|
|
38
|
-
if (reqId)
|
|
39
|
-
return reqId;
|
|
40
|
-
const id = (0, node_crypto_1.randomUUID)();
|
|
41
|
-
res.setHeader('X-Request-Id', id);
|
|
42
|
-
return id;
|
|
43
|
-
},
|
|
44
|
-
// Define a custom logger level
|
|
45
|
-
customLogLevel(_, res, err) {
|
|
46
|
-
if (res.statusCode >= 400 && res.statusCode < 500) {
|
|
47
|
-
return 'warn';
|
|
48
|
-
}
|
|
49
|
-
else if (res.statusCode >= 500 || err) {
|
|
50
|
-
return 'error';
|
|
51
|
-
}
|
|
52
|
-
else if (res.statusCode >= 300 && res.statusCode < 400) {
|
|
53
|
-
return 'silent';
|
|
54
|
-
}
|
|
55
|
-
return 'info';
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=options.js.map
|
package/dist/options.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";;AAYA,8CAoDC;AA/DD,6CAAyC;AAEzC,+BAAwB;AAGxB,6CAAiD;AACjD,+CAA+C;AAE/C;;GAEG;AACH,SAAgB,iBAAiB,CAC/B,QAAgB,MAAM,EACtB,YAAoB,QAAQ,EAC5B,aAAqB,SAAS;IAE9B,OAAO;QACL,8DAA8D;QAC9D,uCAAuC;QACvC,uCAAuC;QACvC,KAAK;QACL,cAAc,EAAE,KAAK;QACrB,SAAS,EAAE,cAAI,CAAC,gBAAgB,CAAC,OAAO;QACxC,mBAAmB,EAAE;YACnB,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,KAAK;YACV,YAAY,EAAE,WAAW;SAC1B;QACD,UAAU,EAAE,IAAA,8BAAiB,EAAC,SAAS,EAAE,UAAU,CAAC;QACpD,WAAW,EAAE,IAAA,4BAAc,GAAE;QAC7B,MAAM,EAAE;YACN,KAAK,EAAE;gBACL,UAAU;gBACV,kBAAkB;gBAClB,eAAe;gBACf,uBAAuB;aACxB;SACF;QACD,QAAQ,EAAE,UAAU,GAAG,EAAE,GAAG;;YAC1B,MAAM,KAAK,GAAG,MAAA,GAAG,CAAC,EAAE,mCAAI,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YACpD,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;YACxB,MAAM,EAAE,GAAG,IAAA,wBAAU,GAAE,CAAC;YACxB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YAClC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,+BAA+B;QAC/B,cAAc,CACZ,CAAkB,EAClB,GAAoC,EACpC,GAAW;YAEX,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;gBAClD,OAAO,MAAM,CAAC;YAChB,CAAC;iBAAM,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;gBACxC,OAAO,OAAO,CAAC;YACjB,CAAC;iBAAM,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;gBACzD,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'http';\nimport { randomUUID } from 'node:crypto';\n\nimport pino from 'pino';\nimport type { Options } from 'pino-http';\n\nimport { getOtelFormatters } from './formatters';\nimport { getSerializers } from './serializers';\n\n/**\n * get pino http option\n */\nexport function getPinoHttpOption(\n level: string = 'info',\n spanIdKey: string = 'spanId',\n traceIdKey: string = 'traceId',\n): Options {\n return {\n // https://getpino.io/#/docs/api?id=timestamp-boolean-function\n // Change time value in production log.\n // timestamp: stdTimeFunctions.isoTime,\n level,\n quietReqLogger: false,\n timestamp: pino.stdTimeFunctions.isoTime,\n customAttributeKeys: {\n req: 'req',\n res: 'res',\n err: 'err',\n responseTime: 'taken(ms)',\n },\n formatters: getOtelFormatters(spanIdKey, traceIdKey),\n serializers: getSerializers(),\n redact: {\n paths: [\n 'password',\n 'reqBody.password',\n 'user.password',\n 'reqBody.user.password',\n ],\n },\n genReqId: function (req, res) {\n const reqId = req.id ?? req.headers['x-request-id'];\n if (reqId) return reqId;\n const id = randomUUID();\n res.setHeader('X-Request-Id', id);\n return id;\n },\n // Define a custom logger level\n customLogLevel(\n _: IncomingMessage,\n res: ServerResponse<IncomingMessage>,\n err?: Error,\n ) {\n if (res.statusCode >= 400 && res.statusCode < 500) {\n return 'warn';\n } else if (res.statusCode >= 500 || err) {\n return 'error';\n } else if (res.statusCode >= 300 && res.statusCode < 400) {\n return 'silent';\n }\n\n return 'info';\n },\n };\n}\n"]}
|
package/dist/serializers.d.ts
DELETED
package/dist/serializers.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSerializers = getSerializers;
|
|
4
|
-
/**
|
|
5
|
-
* get serializers
|
|
6
|
-
* https://github.com/pinojs/pino-http?tab=readme-ov-file#custom-serializers--custom-log-attribute-keys
|
|
7
|
-
*/
|
|
8
|
-
function getSerializers() {
|
|
9
|
-
return {
|
|
10
|
-
req(req) {
|
|
11
|
-
const request = req.raw;
|
|
12
|
-
return {
|
|
13
|
-
id: req.id,
|
|
14
|
-
method: req.method,
|
|
15
|
-
url: req.url,
|
|
16
|
-
headers: request.headers,
|
|
17
|
-
query: request.query,
|
|
18
|
-
body: request.body,
|
|
19
|
-
};
|
|
20
|
-
},
|
|
21
|
-
res(response) {
|
|
22
|
-
const { statusCode: status, ...serialized } = response;
|
|
23
|
-
return Object.assign({ status }, serialized);
|
|
24
|
-
},
|
|
25
|
-
err(err) {
|
|
26
|
-
return err;
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=serializers.js.map
|
package/dist/serializers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serializers.js","sourceRoot":"","sources":["../src/serializers.ts"],"names":[],"mappings":";;AAWA,wCAuBC;AA3BD;;;GAGG;AACH,SAAgB,cAAc;IAC5B,OAAO;QACL,GAAG,CAAC,GAAsB;YACxB,MAAM,OAAO,GAAG,GAAG,CAAC,GAEnB,CAAC;YACF,OAAO;gBACL,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,QAA4B;YAC9B,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,GAAG,QAAQ,CAAC;YACvD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC;QAC/C,CAAC;QACD,GAAG,CAAC,GAAoB;YACtB,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { SerializerFn } from 'pino';\nimport type {\n SerializedError,\n SerializedRequest,\n SerializedResponse,\n} from 'pino-std-serializers';\n\n/**\n * get serializers\n * https://github.com/pinojs/pino-http?tab=readme-ov-file#custom-serializers--custom-log-attribute-keys\n */\nexport function getSerializers(): { [key: string]: SerializerFn } {\n return {\n req(req: SerializedRequest) {\n const request = req.raw as unknown as Request & {\n query: Record<string, unknown>;\n };\n return {\n id: req.id,\n method: req.method,\n url: req.url,\n headers: request.headers,\n query: request.query,\n body: request.body,\n };\n },\n res(response: SerializedResponse) {\n const { statusCode: status, ...serialized } = response;\n return Object.assign({ status }, serialized);\n },\n err(err: SerializedError) {\n return err;\n },\n };\n}\n"]}
|
package/dist/streams.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import pino from 'pino';
|
|
2
|
-
/**
|
|
3
|
-
* create pretty stream entry
|
|
4
|
-
*/
|
|
5
|
-
export declare function createPrettyStreamEntry(app: string, level: pino.Level): pino.StreamEntry;
|
|
6
|
-
/**
|
|
7
|
-
* create loki stream entry
|
|
8
|
-
* https://github.com/pinojs/pino/blob/master/docs/transports.md#pino-loki
|
|
9
|
-
*/
|
|
10
|
-
export declare function createLokiStreamEntry(app: string, level: pino.Level, host: string): pino.StreamEntry;
|
|
11
|
-
/**
|
|
12
|
-
* create file stream entry
|
|
13
|
-
* https://github.com/iccicci/rotating-file-stream?tab=readme-ov-file#initialrotation
|
|
14
|
-
*/
|
|
15
|
-
export declare function createFileStreamEntry(app: string, level: pino.Level, filepath: string): pino.StreamEntry;
|
|
16
|
-
/**
|
|
17
|
-
* add multi destination stream
|
|
18
|
-
* support pretty, file, loki
|
|
19
|
-
*/
|
|
20
|
-
export declare function getMultiDestinationStream(app: string, level?: pino.Level, filepath?: string, loki?: string): pino.MultiStreamRes;
|
package/dist/streams.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createPrettyStreamEntry = createPrettyStreamEntry;
|
|
4
|
-
exports.createLokiStreamEntry = createLokiStreamEntry;
|
|
5
|
-
exports.createFileStreamEntry = createFileStreamEntry;
|
|
6
|
-
exports.getMultiDestinationStream = getMultiDestinationStream;
|
|
7
|
-
const node_path_1 = require("node:path");
|
|
8
|
-
const pino_1 = require("pino");
|
|
9
|
-
const pino_loki_1 = require("pino-loki");
|
|
10
|
-
const pino_pretty_1 = require("pino-pretty");
|
|
11
|
-
const rotating_file_stream_1 = require("rotating-file-stream");
|
|
12
|
-
/**
|
|
13
|
-
* create pretty stream entry
|
|
14
|
-
*/
|
|
15
|
-
function createPrettyStreamEntry(app, level) {
|
|
16
|
-
const stream = (0, pino_pretty_1.default)({
|
|
17
|
-
translateTime: false,
|
|
18
|
-
hideObject: false,
|
|
19
|
-
colorize: true,
|
|
20
|
-
});
|
|
21
|
-
return { level, stream };
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* create loki stream entry
|
|
25
|
-
* https://github.com/pinojs/pino/blob/master/docs/transports.md#pino-loki
|
|
26
|
-
*/
|
|
27
|
-
function createLokiStreamEntry(app, level, host) {
|
|
28
|
-
const stream = (0, pino_loki_1.pinoLoki)({
|
|
29
|
-
replaceTimestamp: true,
|
|
30
|
-
batching: true,
|
|
31
|
-
interval: 5,
|
|
32
|
-
host, // Change if Loki hostname is different
|
|
33
|
-
labels: { app },
|
|
34
|
-
});
|
|
35
|
-
return { level, stream };
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* create file stream entry
|
|
39
|
-
* https://github.com/iccicci/rotating-file-stream?tab=readme-ov-file#initialrotation
|
|
40
|
-
*/
|
|
41
|
-
function createFileStreamEntry(app, level, filepath) {
|
|
42
|
-
const { dir, base } = node_path_1.default.parse(filepath);
|
|
43
|
-
const stream = (0, rotating_file_stream_1.createStream)(base, {
|
|
44
|
-
size: '1G', // 1G rotate every 1 Gigabyte written
|
|
45
|
-
interval: '1d', // rotate daily
|
|
46
|
-
compress: 'gzip', // compress rotated files
|
|
47
|
-
path: dir,
|
|
48
|
-
});
|
|
49
|
-
return { level, stream };
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* add multi destination stream
|
|
53
|
-
* support pretty, file, loki
|
|
54
|
-
*/
|
|
55
|
-
function getMultiDestinationStream(app, level = 'info', filepath, loki) {
|
|
56
|
-
const entries = [createPrettyStreamEntry(app, level)];
|
|
57
|
-
if (filepath)
|
|
58
|
-
entries.push(createFileStreamEntry(app, level, filepath));
|
|
59
|
-
if (loki)
|
|
60
|
-
entries.push(createLokiStreamEntry(app, level, loki));
|
|
61
|
-
return pino_1.default.multistream(entries);
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=streams.js.map
|
package/dist/streams.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"streams.js","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":";;AAUA,0DAUC;AAMD,sDAaC;AAMD,sDAcC;AAMD,8DAWC;AA5ED,yCAA6B;AAE7B,+BAAwB;AACxB,yCAAqC;AACrC,6CAAqC;AACrC,+DAAoD;AAEpD;;GAEG;AACH,SAAgB,uBAAuB,CACrC,GAAW,EACX,KAAiB;IAEjB,MAAM,MAAM,GAAG,IAAA,qBAAU,EAAC;QACxB,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,SAAgB,qBAAqB,CACnC,GAAW,EACX,KAAiB,EACjB,IAAY;IAEZ,MAAM,MAAM,GAAG,IAAA,oBAAQ,EAAC;QACtB,gBAAgB,EAAE,IAAI;QACtB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,CAAC;QACX,IAAI,EAAE,uCAAuC;QAC7C,MAAM,EAAE,EAAE,GAAG,EAAE;KAChB,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,SAAgB,qBAAqB,CACnC,GAAW,EACX,KAAiB,EACjB,QAAgB;IAEhB,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,mBAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,IAAA,mCAAY,EAAC,IAAI,EAAE;QAChC,IAAI,EAAE,IAAI,EAAE,qCAAqC;QACjD,QAAQ,EAAE,IAAI,EAAE,eAAe;QAC/B,QAAQ,EAAE,MAAM,EAAE,yBAAyB;QAC3C,IAAI,EAAE,GAAG;KACV,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,SAAgB,yBAAyB,CACvC,GAAW,EACX,QAAoB,MAAM,EAC1B,QAAiB,EACjB,IAAa;IAEb,MAAM,OAAO,GAAuB,CAAC,uBAAuB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAC1E,IAAI,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IACxE,IAAI,IAAI;QAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAEhE,OAAO,cAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC","sourcesContent":["import path from 'node:path';\n\nimport pino from 'pino';\nimport { pinoLoki } from 'pino-loki';\nimport pinoPretty from 'pino-pretty';\nimport { createStream } from 'rotating-file-stream';\n\n/**\n * create pretty stream entry\n */\nexport function createPrettyStreamEntry(\n app: string,\n level: pino.Level,\n): pino.StreamEntry {\n const stream = pinoPretty({\n translateTime: false,\n hideObject: false,\n colorize: true,\n });\n return { level, stream };\n}\n\n/**\n * create loki stream entry\n * https://github.com/pinojs/pino/blob/master/docs/transports.md#pino-loki\n */\nexport function createLokiStreamEntry(\n app: string,\n level: pino.Level,\n host: string,\n): pino.StreamEntry {\n const stream = pinoLoki({\n replaceTimestamp: true,\n batching: true,\n interval: 5,\n host, // Change if Loki hostname is different\n labels: { app },\n });\n return { level, stream };\n}\n\n/**\n * create file stream entry\n * https://github.com/iccicci/rotating-file-stream?tab=readme-ov-file#initialrotation\n */\nexport function createFileStreamEntry(\n app: string,\n level: pino.Level,\n filepath: string,\n): pino.StreamEntry {\n const { dir, base } = path.parse(filepath);\n\n const stream = createStream(base, {\n size: '1G', // 1G rotate every 1 Gigabyte written\n interval: '1d', // rotate daily\n compress: 'gzip', // compress rotated files\n path: dir,\n });\n return { level, stream };\n}\n\n/**\n * add multi destination stream\n * support pretty, file, loki\n */\nexport function getMultiDestinationStream(\n app: string,\n level: pino.Level = 'info',\n filepath?: string,\n loki?: string,\n): pino.MultiStreamRes {\n const entries: pino.StreamEntry[] = [createPrettyStreamEntry(app, level)];\n if (filepath) entries.push(createFileStreamEntry(app, level, filepath));\n if (loki) entries.push(createLokiStreamEntry(app, level, loki));\n\n return pino.multistream(entries);\n}\n"]}
|