@gyramais/log-transport 0.1.0 → 0.3.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/README.md +42 -38
- package/dist/fatal-handlers.d.ts +1 -4
- package/dist/fatal-handlers.d.ts.map +1 -1
- package/dist/fatal-handlers.js +6 -5
- package/dist/fatal-handlers.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +16 -23
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +47 -52
- package/dist/logger.js.map +1 -1
- package/dist/options.d.ts +6 -8
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js.map +1 -1
- package/package.json +1 -1
- package/src/fatal-handlers.ts +8 -10
- package/src/index.ts +3 -3
- package/src/logger.ts +60 -67
- package/src/options.ts +31 -49
package/README.md
CHANGED
|
@@ -5,59 +5,63 @@ partir de configuração explícita, e registra exceção fatal com flush antes
|
|
|
5
5
|
exit.
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from '@gyramais/log-transport';
|
|
13
|
-
|
|
14
|
-
const { logger, lokiTransport } = buildNestLogger({
|
|
15
|
-
service: 'gyra-core', // obrigatório
|
|
8
|
+
import { buildNestLogger } from '@gyramais/log-transport';
|
|
9
|
+
|
|
10
|
+
const { logger } = buildNestLogger({
|
|
11
|
+
service: 'gyra-core', // obrigatório
|
|
16
12
|
level: 'debug',
|
|
17
13
|
pretty: false,
|
|
18
14
|
loki: { host: 'http://loki:3100', basicAuth: '...' },
|
|
15
|
+
redirectConsole: true, // opt-in: troca os métodos de `console`
|
|
16
|
+
fatalHandlers: true, // opt-in: instala uncaughtException/unhandledRejection
|
|
19
17
|
});
|
|
20
|
-
|
|
21
|
-
registerFatalHandlers(logger, lokiTransport);
|
|
22
18
|
```
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
Uma chamada. Os dois efeitos de processo continuam **opt-in** — você escreve `true`,
|
|
21
|
+
não herda nada por importar o pacote — mas não exigem mais uma chamada separada cada,
|
|
22
|
+
com o `logger` costurado na mão.
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
conexões RMQ (`src/main.worker.ts`):
|
|
24
|
+
Sem essas duas opções, **nada no processo é tocado**: `console` intacto, nenhum
|
|
25
|
+
handler instalado.
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
`registerFatalHandlers` e `redirectConsoleToNestLogger` continuam exportados, para
|
|
28
|
+
quem precisar de controle fino (ordem, opções, ou instalar sobre um logger que veio
|
|
29
|
+
de outro lugar).
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
## Um logger por processo
|
|
32
|
+
|
|
33
|
+
Construa **um** logger e passe a referência adiante — para a app e para cada conexão
|
|
34
|
+
de mensageria:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
const { logger } = buildNestLogger({
|
|
35
38
|
service: 'gyra-core',
|
|
36
|
-
host: process.env.LOKI_URL,
|
|
37
|
-
|
|
39
|
+
loki: { host: process.env.LOKI_URL, basicAuth: process.env.LOKI_BASIC_AUTH },
|
|
40
|
+
redirectConsole: true,
|
|
41
|
+
fatalHandlers: true,
|
|
38
42
|
});
|
|
39
43
|
|
|
40
|
-
const
|
|
44
|
+
const app = await NestFactory.create(AppModule, { logger });
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
app.connectMicroservice({ transport: Transport.RMQ, logger, options: { ... } });
|
|
47
|
+
app.connectMicroservice({ transport: Transport.RMQ, logger, options: { ... } });
|
|
44
48
|
```
|
|
45
49
|
|
|
46
|
-
Não é
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
do processo: registros duplicados produziriam
|
|
58
|
-
|
|
59
|
-
`[FATAL-HANDLERS-DUP]
|
|
60
|
-
|
|
50
|
+
Não é estilo, é correção: **cada construção cria seu próprio lote pendente**. N
|
|
51
|
+
loggers são N lotes, e a descarga de exceção fatal alcança só um deles — as linhas
|
|
52
|
+
acumuladas nos outros morrem com o processo, que é o sintoma que a entrega confiável
|
|
53
|
+
existe para impedir.
|
|
54
|
+
|
|
55
|
+
Vale dizer de onde isso vem: os 15 serviços chamavam o `LoggerFactory()` mais de uma
|
|
56
|
+
vez (13 dos 15; o gyra-integration, seis vezes). Como a fábrica não recebia
|
|
57
|
+
argumento, todas as chamadas produziam loggers idênticos — era cópia de código, não
|
|
58
|
+
necessidade. Se você está construindo o segundo logger, pergunte primeiro por quê.
|
|
59
|
+
|
|
60
|
+
**`registerFatalHandlers` é chamado uma vez por processo.** Handler de
|
|
61
|
+
`uncaughtException` é recurso único do processo: registros duplicados produziriam
|
|
62
|
+
linhas `[FATAL]` repetidas e descargas concorrentes. O pacote ignora a chamada extra
|
|
63
|
+
e emite `[FATAL-HANDLERS-DUP]`, mas o certo é chamar uma vez — ou usar
|
|
64
|
+
`fatalHandlers: true`, que já faz isso.
|
|
61
65
|
|
|
62
66
|
## O pacote não lê `process.env`
|
|
63
67
|
|
package/dist/fatal-handlers.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { LoggerService } from '@nestjs/common';
|
|
2
2
|
import LokiTransport = require('winston-loki');
|
|
3
|
-
|
|
4
|
-
flushTimeoutMs?: number;
|
|
5
|
-
exit?: (code: number) => void;
|
|
6
|
-
}
|
|
3
|
+
import type { FatalHandlersOptions } from './options';
|
|
7
4
|
/**
|
|
8
5
|
* Entrega ao Loki o que está bufferizado e só então devolve o controle,
|
|
9
6
|
* desistindo depois de `timeoutMs`. Nunca lança: no caminho de saída do
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fatal-handlers.d.ts","sourceRoot":"","sources":["../src/fatal-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,aAAa,GAAG,QAAQ,cAAc,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"fatal-handlers.d.ts","sourceRoot":"","sources":["../src/fatal-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,aAAa,GAAG,QAAQ,cAAc,CAAC,CAAC;AAE/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAgCtD;;;;;;;;;;GAUG;AACH,QAAA,MAAM,kBAAkB,GACtB,WAAW,aAAa,GAAG,SAAS,EACpC,kBAA4B,KAC3B,OAAO,CAAC,IAAI,CA6Bd,CAAC;AAoDF,QAAA,MAAM,qBAAqB,GACzB,QAAQ,aAAa,EACrB,WAAW,aAAa,GAAG,SAAS,EACpC,UAAS,oBAAyB,KACjC,CAAC,MAAM,IAAI,CA6Fb,CAAC;AAEF,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,CAAC"}
|
package/dist/fatal-handlers.js
CHANGED
|
@@ -89,9 +89,10 @@ const describeReason = (reason) => {
|
|
|
89
89
|
linhas `[FATAL]`, quatro flushes concorrentes no mesmo transport e quatro
|
|
90
90
|
chamadas de exit.
|
|
91
91
|
|
|
92
|
-
O risco
|
|
93
|
-
|
|
94
|
-
handler por logger.
|
|
92
|
+
O risco aparece em serviço que constrói mais de um logger — o que, na frota, era
|
|
93
|
+
o padrão: 13 dos 15 repos chamavam a fábrica mais de uma vez. Nesses, registrar um
|
|
94
|
+
handler por logger é o erro natural. A orientação é construir UM logger por
|
|
95
|
+
processo, mas o guard existe para o caso de alguém não seguir.
|
|
95
96
|
|
|
96
97
|
Este é o único estado global do pacote, e a distinção importa: ele descreve o
|
|
97
98
|
PROCESSO — se os handlers já estão instalados nele —, não configuração. Config
|
|
@@ -113,8 +114,8 @@ const registerFatalHandlers = (logger, transport, options = {}) => {
|
|
|
113
114
|
process.stdout.write(`${JSON.stringify({
|
|
114
115
|
level: 'warn',
|
|
115
116
|
message: '[FATAL-HANDLERS-DUP] registerFatalHandlers chamado mais de uma vez ' +
|
|
116
|
-
'neste processo; a chamada extra foi ignorada.
|
|
117
|
-
'
|
|
117
|
+
'neste processo; a chamada extra foi ignorada. Construa UM logger por ' +
|
|
118
|
+
'processo e registre uma vez.',
|
|
118
119
|
timestamp: new Date().toISOString(),
|
|
119
120
|
})}\n`);
|
|
120
121
|
return () => undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fatal-handlers.js","sourceRoot":"","sources":["../src/fatal-handlers.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"fatal-handlers.js","sourceRoot":"","sources":["../src/fatal-handlers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { buildNestLogger
|
|
2
|
-
export type { BuiltLogger
|
|
1
|
+
export { buildNestLogger } from './logger';
|
|
2
|
+
export type { BuiltLogger } from './logger';
|
|
3
3
|
export { redirectConsoleToNestLogger } from './console-redirect';
|
|
4
4
|
export type { ConsoleRedirectOptions } from './console-redirect';
|
|
5
5
|
export { registerFatalHandlers, flushLokiTransport } from './fatal-handlers';
|
|
6
6
|
export { DEFAULT_APP_LABEL, DEFAULT_LEVEL, DEFAULT_LOKI_INTERVAL_SECONDS, DEFAULT_LOKI_TIMEOUT_MS, } from './options';
|
|
7
|
-
export type { LoggerOptions, LokiOptions, FileOptions,
|
|
7
|
+
export type { LoggerOptions, LokiOptions, FileOptions, FatalHandlersOptions, } from './options';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,6BAA6B,EAC7B,uBAAuB,GACxB,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,aAAa,EACb,WAAW,EACX,WAAW,EACX,oBAAoB,GACrB,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -13,10 +13,9 @@
|
|
|
13
13
|
`dist/` e fariam um grep de auditoria acusar o pacote de ler ambiente.
|
|
14
14
|
*/
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.DEFAULT_LOKI_TIMEOUT_MS = exports.DEFAULT_LOKI_INTERVAL_SECONDS = exports.DEFAULT_LEVEL = exports.DEFAULT_APP_LABEL = exports.flushLokiTransport = exports.registerFatalHandlers = exports.redirectConsoleToNestLogger = exports.
|
|
16
|
+
exports.DEFAULT_LOKI_TIMEOUT_MS = exports.DEFAULT_LOKI_INTERVAL_SECONDS = exports.DEFAULT_LEVEL = exports.DEFAULT_APP_LABEL = exports.flushLokiTransport = exports.registerFatalHandlers = exports.redirectConsoleToNestLogger = exports.buildNestLogger = void 0;
|
|
17
17
|
var logger_1 = require("./logger");
|
|
18
18
|
Object.defineProperty(exports, "buildNestLogger", { enumerable: true, get: function () { return logger_1.buildNestLogger; } });
|
|
19
|
-
Object.defineProperty(exports, "createLokiTransport", { enumerable: true, get: function () { return logger_1.createLokiTransport; } });
|
|
20
19
|
var console_redirect_1 = require("./console-redirect");
|
|
21
20
|
Object.defineProperty(exports, "redirectConsoleToNestLogger", { enumerable: true, get: function () { return console_redirect_1.redirectConsoleToNestLogger; } });
|
|
22
21
|
var fatal_handlers_1 = require("./fatal-handlers");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;EAYE;;;AAEF,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;EAYE;;;AAEF,mCAA2C;AAAlC,yGAAA,eAAe,OAAA;AAGxB,uDAAiE;AAAxD,+HAAA,2BAA2B,OAAA;AAGpC,mDAA6E;AAApE,uHAAA,qBAAqB,OAAA;AAAE,oHAAA,kBAAkB,OAAA;AAElD,qCAKmB;AAJjB,4GAAA,iBAAiB,OAAA;AACjB,wGAAA,aAAa,OAAA;AACb,wHAAA,6BAA6B,OAAA;AAC7B,kHAAA,uBAAuB,OAAA"}
|
package/dist/logger.d.ts
CHANGED
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
import LokiTransport = require('winston-loki');
|
|
2
2
|
import type { LoggerService } from '@nestjs/common';
|
|
3
|
-
import { LoggerOptions
|
|
3
|
+
import { LoggerOptions } from './options';
|
|
4
4
|
export interface BuiltLogger {
|
|
5
5
|
logger: LoggerService;
|
|
6
|
+
unregisterFatalHandlers?: () => void;
|
|
6
7
|
lokiTransport?: LokiTransport;
|
|
7
8
|
}
|
|
8
|
-
export interface CreateLokiTransportOptions extends LokiOptions {
|
|
9
|
-
service: string;
|
|
10
|
-
app?: string;
|
|
11
|
-
instance?: string;
|
|
12
|
-
pretty?: boolean;
|
|
13
|
-
}
|
|
14
9
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* Monta o logger do Nest com os transports pedidos e, se pedido, instala os
|
|
11
|
+
* efeitos de processo.
|
|
17
12
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
13
|
+
* Por default NÃO instala nada: sem `redirectConsole` e sem `fatalHandlers`, nada
|
|
14
|
+
* no processo é tocado. Esses dois mexem no ciclo de vida (o que `console.log`
|
|
15
|
+
* faz, como o processo morre), então continuam sendo escolha declarada do
|
|
16
|
+
* consumidor — só não exigem mais uma chamada separada cada.
|
|
21
17
|
*
|
|
22
|
-
* const
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* Monta o logger do Nest com os transports pedidos e devolve, junto, o transport
|
|
29
|
-
* do Loki — necessário para `registerFatalHandlers` dar flush antes do exit.
|
|
18
|
+
* const { logger } = buildNestLogger({
|
|
19
|
+
* service: 'gyra-core',
|
|
20
|
+
* loki: { host },
|
|
21
|
+
* redirectConsole: true,
|
|
22
|
+
* fatalHandlers: true,
|
|
23
|
+
* });
|
|
30
24
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* processo.
|
|
25
|
+
* Num serviço com vários loggers, peça `fatalHandlers` em UM deles — os handlers
|
|
26
|
+
* são recurso único do processo.
|
|
34
27
|
*/
|
|
35
28
|
export declare const buildNestLogger: (options: LoggerOptions) => BuiltLogger;
|
|
36
29
|
//# sourceMappingURL=logger.d.ts.map
|
package/dist/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAmCA,OAAO,aAAa,GAAG,QAAQ,cAAc,CAAC,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAKpD,OAAO,EAKL,aAAa,EAEd,MAAM,WAAW,CAAC;AAQnB,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,aAAa,CAAC;IAOtB,uBAAuB,CAAC,EAAE,MAAM,IAAI,CAAC;IAOrC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAoGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,aAAa,KAAG,WAwDxD,CAAC"}
|
package/dist/logger.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.buildNestLogger =
|
|
4
|
+
exports.buildNestLogger = void 0;
|
|
5
5
|
/*
|
|
6
6
|
PROVENIÊNCIA: derivado de gyra-core/src/common/logger/LoggerFactory.ts na branch
|
|
7
7
|
GYR-1555 (tag `backup/GYR-1555-pre-close`), onde o defeito de entrega ao Loki foi
|
|
@@ -15,12 +15,19 @@ exports.buildNestLogger = exports.createLokiTransport = void 0;
|
|
|
15
15
|
para o handler de exceção fatal alcançá-lo; aqui ele volta no retorno, porque
|
|
16
16
|
estado global no pacote é o mesmo problema de ler env com outra roupa.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
Houve uma tentativa intermediária, e ela está registrada aqui porque o erro é
|
|
19
|
+
fácil de repetir: ao ver o worker do gyra-core construir QUATRO loggers, a
|
|
20
|
+
conclusão foi "eles precisam compartilhar um transport", e o pacote ganhou um
|
|
21
|
+
`createLokiTransport` para isso. Estava errado — a pergunta certa era por que
|
|
22
|
+
havia quatro loggers.
|
|
23
|
+
|
|
24
|
+
Não havia motivo: o `LoggerFactory` original não recebia argumento, então as
|
|
25
|
+
quatro chamadas sempre produziram loggers idênticos. Era cópia de código. O
|
|
26
|
+
conserto é UM logger por processo, com o handle passado adiante — e aí não
|
|
27
|
+
existe transport para compartilhar. A opção foi removida na 0.3.0.
|
|
28
|
+
|
|
29
|
+
Se algum dia um serviço precisar de dois loggers com LABELS diferentes e um só
|
|
30
|
+
batcher, aí sim a opção volta a fazer sentido. Nenhum dos 15 tem esse caso.
|
|
24
31
|
- O redirecionamento de `console.*` saiu para `console-redirect.ts`, como opt-in
|
|
25
32
|
explícito: é efeito colateral de processo, e importar um pacote não deve mudar
|
|
26
33
|
o que `console.log` faz.
|
|
@@ -29,6 +36,8 @@ const winston_1 = require("winston");
|
|
|
29
36
|
const nest_winston_1 = require("nest-winston");
|
|
30
37
|
const LokiTransport = require("winston-loki");
|
|
31
38
|
const os_1 = require("os");
|
|
39
|
+
const console_redirect_1 = require("./console-redirect");
|
|
40
|
+
const fatal_handlers_1 = require("./fatal-handlers");
|
|
32
41
|
const options_1 = require("./options");
|
|
33
42
|
const formatMeta = (meta) => {
|
|
34
43
|
const splat = meta[Symbol.for('splat')];
|
|
@@ -80,30 +89,6 @@ const buildPrettyFormat = () => {
|
|
|
80
89
|
});
|
|
81
90
|
return winston_1.format.combine(winston_1.format.splat(), localFormat);
|
|
82
91
|
};
|
|
83
|
-
/**
|
|
84
|
-
* Constrói o transport do Loki isoladamente, para o consumidor COMPARTILHAR um
|
|
85
|
-
* único batcher entre vários loggers do mesmo processo.
|
|
86
|
-
*
|
|
87
|
-
* Use isto quando o serviço monta mais de um logger — o worker do gyra-core monta
|
|
88
|
-
* quatro. Com um transport por logger, cada um tem seu batcher, e o flush de
|
|
89
|
-
* exceção fatal cobre só um deles.
|
|
90
|
-
*
|
|
91
|
-
* const lokiTransport = createLokiTransport({ service: 'gyra-core', host });
|
|
92
|
-
* const { logger } = buildNestLogger({ service: 'gyra-core', lokiTransport });
|
|
93
|
-
* // ...e o mesmo `lokiTransport` nos outros loggers do processo
|
|
94
|
-
*/
|
|
95
|
-
const createLokiTransport = (options) => {
|
|
96
|
-
const { service, app, instance, pretty, ...loki } = options;
|
|
97
|
-
return buildLokiTransport(loki, {
|
|
98
|
-
service,
|
|
99
|
-
app: app ?? options_1.DEFAULT_APP_LABEL,
|
|
100
|
-
instance: instance ?? (0, os_1.hostname)(),
|
|
101
|
-
...loki.labels,
|
|
102
|
-
}, pretty
|
|
103
|
-
? buildPrettyFormat()
|
|
104
|
-
: winston_1.format.combine(winston_1.format.timestamp(), winston_1.format.json()));
|
|
105
|
-
};
|
|
106
|
-
exports.createLokiTransport = createLokiTransport;
|
|
107
92
|
const buildLokiTransport = (loki, labels, lineFormat) => new LokiTransport({
|
|
108
93
|
host: loki.host,
|
|
109
94
|
basicAuth: loki.basicAuth,
|
|
@@ -125,36 +110,33 @@ const buildLokiTransport = (loki, labels, lineFormat) => new LokiTransport({
|
|
|
125
110
|
})}\n`),
|
|
126
111
|
});
|
|
127
112
|
/**
|
|
128
|
-
* Monta o logger do Nest com os transports pedidos e
|
|
129
|
-
*
|
|
113
|
+
* Monta o logger do Nest com os transports pedidos e, se pedido, instala os
|
|
114
|
+
* efeitos de processo.
|
|
115
|
+
*
|
|
116
|
+
* Por default NÃO instala nada: sem `redirectConsole` e sem `fatalHandlers`, nada
|
|
117
|
+
* no processo é tocado. Esses dois mexem no ciclo de vida (o que `console.log`
|
|
118
|
+
* faz, como o processo morre), então continuam sendo escolha declarada do
|
|
119
|
+
* consumidor — só não exigem mais uma chamada separada cada.
|
|
120
|
+
*
|
|
121
|
+
* const { logger } = buildNestLogger({
|
|
122
|
+
* service: 'gyra-core',
|
|
123
|
+
* loki: { host },
|
|
124
|
+
* redirectConsole: true,
|
|
125
|
+
* fatalHandlers: true,
|
|
126
|
+
* });
|
|
130
127
|
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* processo.
|
|
128
|
+
* Num serviço com vários loggers, peça `fatalHandlers` em UM deles — os handlers
|
|
129
|
+
* são recurso único do processo.
|
|
134
130
|
*/
|
|
135
131
|
const buildNestLogger = (options) => {
|
|
136
132
|
const lineFormat = options.pretty
|
|
137
133
|
? buildPrettyFormat()
|
|
138
134
|
: winston_1.format.combine(winston_1.format.timestamp(), winston_1.format.json());
|
|
139
|
-
/*
|
|
140
|
-
Passar os dois é ambíguo: um pede para construir um transport novo, o outro
|
|
141
|
-
para reusar um existente. Falhar alto é melhor que escolher em silêncio e
|
|
142
|
-
deixar o consumidor com dois batchers sem saber.
|
|
143
|
-
*/
|
|
144
|
-
if (options.loki && options.lokiTransport) {
|
|
145
|
-
throw new Error('[log-transport] `loki` e `lokiTransport` sao mutuamente exclusivos: ' +
|
|
146
|
-
'use `loki` para construir um transport novo, ou `lokiTransport` para ' +
|
|
147
|
-
'reusar um ja construido por createLokiTransport().');
|
|
148
|
-
}
|
|
149
135
|
const transportsList = [
|
|
150
136
|
new winston_1.transports.Console({ format: lineFormat }),
|
|
151
137
|
];
|
|
152
138
|
let lokiTransport;
|
|
153
|
-
if (options.
|
|
154
|
-
lokiTransport = options.lokiTransport;
|
|
155
|
-
transportsList.push(lokiTransport);
|
|
156
|
-
}
|
|
157
|
-
else if (options.loki) {
|
|
139
|
+
if (options.loki) {
|
|
158
140
|
lokiTransport = buildLokiTransport(options.loki, {
|
|
159
141
|
service: options.service,
|
|
160
142
|
app: options.app ?? options_1.DEFAULT_APP_LABEL,
|
|
@@ -170,7 +152,20 @@ const buildNestLogger = (options) => {
|
|
|
170
152
|
level: options.level ?? options_1.DEFAULT_LEVEL,
|
|
171
153
|
transports: transportsList,
|
|
172
154
|
});
|
|
173
|
-
|
|
155
|
+
/*
|
|
156
|
+
Os dois efeitos de processo continuam OPT-IN — o consumidor escreve `true`, não
|
|
157
|
+
herda nada por importar o pacote. O que mudou na 0.2.0 foi só a ergonomia: eram
|
|
158
|
+
duas chamadas extras com o `logger` e o `lokiTransport` costurados na mão, e o
|
|
159
|
+
`pretty` repetido. "Explícito" não precisava significar "separado".
|
|
160
|
+
*/
|
|
161
|
+
if (options.redirectConsole) {
|
|
162
|
+
(0, console_redirect_1.redirectConsoleToNestLogger)({ pretty: options.pretty });
|
|
163
|
+
}
|
|
164
|
+
let unregisterFatalHandlers;
|
|
165
|
+
if (options.fatalHandlers) {
|
|
166
|
+
unregisterFatalHandlers = (0, fatal_handlers_1.registerFatalHandlers)(logger, lokiTransport, options.fatalHandlers === true ? {} : options.fatalHandlers);
|
|
167
|
+
}
|
|
168
|
+
return { logger, lokiTransport, unregisterFatalHandlers };
|
|
174
169
|
};
|
|
175
170
|
exports.buildNestLogger = buildNestLogger;
|
|
176
171
|
//# sourceMappingURL=logger.js.map
|
package/dist/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAAA,uDAAuD;;;AAEvD
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
package/dist/options.d.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
export interface LokiTransportLike {
|
|
2
|
-
log?: unknown;
|
|
3
|
-
flush?: () => Promise<void>;
|
|
4
|
-
close?: () => void;
|
|
5
|
-
once?: (event: string, listener: (...args: unknown[]) => void) => unknown;
|
|
6
|
-
off?: (event: string, listener: (...args: unknown[]) => void) => unknown;
|
|
7
|
-
}
|
|
8
1
|
export interface LokiOptions {
|
|
9
2
|
host: string;
|
|
10
3
|
basicAuth?: string;
|
|
@@ -12,6 +5,10 @@ export interface LokiOptions {
|
|
|
12
5
|
timeout?: number;
|
|
13
6
|
labels?: Record<string, string>;
|
|
14
7
|
}
|
|
8
|
+
export interface FatalHandlersOptions {
|
|
9
|
+
flushTimeoutMs?: number;
|
|
10
|
+
exit?: (code: number) => void;
|
|
11
|
+
}
|
|
15
12
|
export interface FileOptions {
|
|
16
13
|
filename: string;
|
|
17
14
|
}
|
|
@@ -22,8 +19,9 @@ export interface LoggerOptions {
|
|
|
22
19
|
instance?: string;
|
|
23
20
|
pretty?: boolean;
|
|
24
21
|
loki?: LokiOptions;
|
|
25
|
-
lokiTransport?: LokiTransportLike;
|
|
26
22
|
file?: FileOptions;
|
|
23
|
+
redirectConsole?: boolean;
|
|
24
|
+
fatalHandlers?: boolean | FatalHandlersOptions;
|
|
27
25
|
}
|
|
28
26
|
export declare const DEFAULT_APP_LABEL = "saas";
|
|
29
27
|
export declare const DEFAULT_LEVEL = "debug";
|
package/dist/options.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,WAAW;IAE1B,IAAI,EAAE,MAAM,CAAC;IAEb,SAAS,CAAC,EAAE,MAAM,CAAC;IAMnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,OAAO,CAAC,EAAE,MAAM,CAAC;IAOjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAS5B,OAAO,EAAE,MAAM,CAAC;IAOhB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,KAAK,CAAC,EAAE,MAAM,CAAC;IAQf,QAAQ,CAAC,EAAE,MAAM,CAAC;IASlB,MAAM,CAAC,EAAE,OAAO,CAAC;IAYjB,IAAI,CAAC,EAAE,WAAW,CAAC;IAMnB,IAAI,CAAC,EAAE,WAAW,CAAC;IAWnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAa1B,aAAa,CAAC,EAAE,OAAO,GAAG,oBAAoB,CAAC;CAChD;AAED,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,aAAa,UAAU,CAAC;AAGrC,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,eAAO,MAAM,uBAAuB,QAAQ,CAAC"}
|
package/dist/options.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;EAeE;;;
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;EAeE;;;AAiHW,QAAA,iBAAiB,GAAG,MAAM,CAAC;AAC3B,QAAA,aAAa,GAAG,OAAO,CAAC;AAErC,gEAAgE;AACnD,QAAA,6BAA6B,GAAG,CAAC,CAAC;AAElC,QAAA,uBAAuB,GAAG,KAAK,CAAC"}
|
package/package.json
CHANGED
package/src/fatal-handlers.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { LoggerService } from '@nestjs/common';
|
|
2
2
|
import LokiTransport = require('winston-loki');
|
|
3
3
|
|
|
4
|
+
import type { FatalHandlersOptions } from './options';
|
|
5
|
+
|
|
4
6
|
/*
|
|
5
7
|
O flush no caminho do crash é limitado no tempo de propósito: um Loki
|
|
6
8
|
indisponível não pode impedir o pod de morrer e reiniciar.
|
|
@@ -9,11 +11,6 @@ const FLUSH_TIMEOUT_MS = 2000;
|
|
|
9
11
|
|
|
10
12
|
type FatalOrigin = 'uncaughtException' | 'unhandledRejection';
|
|
11
13
|
|
|
12
|
-
interface FatalHandlersOptions {
|
|
13
|
-
flushTimeoutMs?: number;
|
|
14
|
-
exit?: (code: number) => void;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
14
|
/*
|
|
18
15
|
Winston entrega a linha ao transport por stream, num tick posterior ao
|
|
19
16
|
`logger.error()`. Sem esperar por essa entrega, o batch ainda está vazio quando
|
|
@@ -112,9 +109,10 @@ const describeReason = (
|
|
|
112
109
|
linhas `[FATAL]`, quatro flushes concorrentes no mesmo transport e quatro
|
|
113
110
|
chamadas de exit.
|
|
114
111
|
|
|
115
|
-
O risco
|
|
116
|
-
|
|
117
|
-
handler por logger.
|
|
112
|
+
O risco aparece em serviço que constrói mais de um logger — o que, na frota, era
|
|
113
|
+
o padrão: 13 dos 15 repos chamavam a fábrica mais de uma vez. Nesses, registrar um
|
|
114
|
+
handler por logger é o erro natural. A orientação é construir UM logger por
|
|
115
|
+
processo, mas o guard existe para o caso de alguém não seguir.
|
|
118
116
|
|
|
119
117
|
Este é o único estado global do pacote, e a distinção importa: ele descreve o
|
|
120
118
|
PROCESSO — se os handlers já estão instalados nele —, não configuração. Config
|
|
@@ -148,8 +146,8 @@ const registerFatalHandlers = (
|
|
|
148
146
|
level: 'warn',
|
|
149
147
|
message:
|
|
150
148
|
'[FATAL-HANDLERS-DUP] registerFatalHandlers chamado mais de uma vez ' +
|
|
151
|
-
'neste processo; a chamada extra foi ignorada.
|
|
152
|
-
'
|
|
149
|
+
'neste processo; a chamada extra foi ignorada. Construa UM logger por ' +
|
|
150
|
+
'processo e registre uma vez.',
|
|
153
151
|
timestamp: new Date().toISOString(),
|
|
154
152
|
})}\n`,
|
|
155
153
|
);
|
package/src/index.ts
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
`dist/` e fariam um grep de auditoria acusar o pacote de ler ambiente.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
export { buildNestLogger
|
|
16
|
-
export type { BuiltLogger
|
|
15
|
+
export { buildNestLogger } from './logger';
|
|
16
|
+
export type { BuiltLogger } from './logger';
|
|
17
17
|
|
|
18
18
|
export { redirectConsoleToNestLogger } from './console-redirect';
|
|
19
19
|
export type { ConsoleRedirectOptions } from './console-redirect';
|
|
@@ -30,5 +30,5 @@ export type {
|
|
|
30
30
|
LoggerOptions,
|
|
31
31
|
LokiOptions,
|
|
32
32
|
FileOptions,
|
|
33
|
-
|
|
33
|
+
FatalHandlersOptions,
|
|
34
34
|
} from './options';
|
package/src/logger.ts
CHANGED
|
@@ -13,12 +13,19 @@
|
|
|
13
13
|
para o handler de exceção fatal alcançá-lo; aqui ele volta no retorno, porque
|
|
14
14
|
estado global no pacote é o mesmo problema de ler env com outra roupa.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
Houve uma tentativa intermediária, e ela está registrada aqui porque o erro é
|
|
17
|
+
fácil de repetir: ao ver o worker do gyra-core construir QUATRO loggers, a
|
|
18
|
+
conclusão foi "eles precisam compartilhar um transport", e o pacote ganhou um
|
|
19
|
+
`createLokiTransport` para isso. Estava errado — a pergunta certa era por que
|
|
20
|
+
havia quatro loggers.
|
|
21
|
+
|
|
22
|
+
Não havia motivo: o `LoggerFactory` original não recebia argumento, então as
|
|
23
|
+
quatro chamadas sempre produziram loggers idênticos. Era cópia de código. O
|
|
24
|
+
conserto é UM logger por processo, com o handle passado adiante — e aí não
|
|
25
|
+
existe transport para compartilhar. A opção foi removida na 0.3.0.
|
|
26
|
+
|
|
27
|
+
Se algum dia um serviço precisar de dois loggers com LABELS diferentes e um só
|
|
28
|
+
batcher, aí sim a opção volta a fazer sentido. Nenhum dos 15 tem esse caso.
|
|
22
29
|
- O redirecionamento de `console.*` saiu para `console-redirect.ts`, como opt-in
|
|
23
30
|
explícito: é efeito colateral de processo, e importar um pacote não deve mudar
|
|
24
31
|
o que `console.log` faz.
|
|
@@ -30,6 +37,8 @@ import LokiTransport = require('winston-loki');
|
|
|
30
37
|
import type { LoggerService } from '@nestjs/common';
|
|
31
38
|
import { hostname } from 'os';
|
|
32
39
|
|
|
40
|
+
import { redirectConsoleToNestLogger } from './console-redirect';
|
|
41
|
+
import { registerFatalHandlers } from './fatal-handlers';
|
|
33
42
|
import {
|
|
34
43
|
DEFAULT_APP_LABEL,
|
|
35
44
|
DEFAULT_LEVEL,
|
|
@@ -48,6 +57,13 @@ type LokiShipError = Error & { statusCode?: number };
|
|
|
48
57
|
export interface BuiltLogger {
|
|
49
58
|
logger: LoggerService;
|
|
50
59
|
|
|
60
|
+
/*
|
|
61
|
+
Presente somente quando `options.fatalHandlers` foi pedido. Desfaz o registro
|
|
62
|
+
e libera o guard por processo — em produção o processo não desregistra, ele
|
|
63
|
+
morre; isto existe para teste.
|
|
64
|
+
*/
|
|
65
|
+
unregisterFatalHandlers?: () => void;
|
|
66
|
+
|
|
51
67
|
/*
|
|
52
68
|
Presente somente quando `options.loki` foi informado. Quem trata exceção fatal
|
|
53
69
|
precisa dele para dar flush antes do exit — sem isso a stack do crash nunca sai
|
|
@@ -122,44 +138,6 @@ const buildPrettyFormat = (): Logform.Format => {
|
|
|
122
138
|
return format.combine(format.splat(), localFormat);
|
|
123
139
|
};
|
|
124
140
|
|
|
125
|
-
export interface CreateLokiTransportOptions extends LokiOptions {
|
|
126
|
-
service: string;
|
|
127
|
-
app?: string;
|
|
128
|
-
instance?: string;
|
|
129
|
-
pretty?: boolean;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Constrói o transport do Loki isoladamente, para o consumidor COMPARTILHAR um
|
|
134
|
-
* único batcher entre vários loggers do mesmo processo.
|
|
135
|
-
*
|
|
136
|
-
* Use isto quando o serviço monta mais de um logger — o worker do gyra-core monta
|
|
137
|
-
* quatro. Com um transport por logger, cada um tem seu batcher, e o flush de
|
|
138
|
-
* exceção fatal cobre só um deles.
|
|
139
|
-
*
|
|
140
|
-
* const lokiTransport = createLokiTransport({ service: 'gyra-core', host });
|
|
141
|
-
* const { logger } = buildNestLogger({ service: 'gyra-core', lokiTransport });
|
|
142
|
-
* // ...e o mesmo `lokiTransport` nos outros loggers do processo
|
|
143
|
-
*/
|
|
144
|
-
export const createLokiTransport = (
|
|
145
|
-
options: CreateLokiTransportOptions,
|
|
146
|
-
): LokiTransport => {
|
|
147
|
-
const { service, app, instance, pretty, ...loki } = options;
|
|
148
|
-
|
|
149
|
-
return buildLokiTransport(
|
|
150
|
-
loki,
|
|
151
|
-
{
|
|
152
|
-
service,
|
|
153
|
-
app: app ?? DEFAULT_APP_LABEL,
|
|
154
|
-
instance: instance ?? hostname(),
|
|
155
|
-
...loki.labels,
|
|
156
|
-
},
|
|
157
|
-
pretty
|
|
158
|
-
? buildPrettyFormat()
|
|
159
|
-
: format.combine(format.timestamp(), format.json()),
|
|
160
|
-
);
|
|
161
|
-
};
|
|
162
|
-
|
|
163
141
|
const buildLokiTransport = (
|
|
164
142
|
loki: LokiOptions,
|
|
165
143
|
labels: Record<string, string>,
|
|
@@ -193,41 +171,36 @@ const buildLokiTransport = (
|
|
|
193
171
|
});
|
|
194
172
|
|
|
195
173
|
/**
|
|
196
|
-
* Monta o logger do Nest com os transports pedidos e
|
|
197
|
-
*
|
|
174
|
+
* Monta o logger do Nest com os transports pedidos e, se pedido, instala os
|
|
175
|
+
* efeitos de processo.
|
|
198
176
|
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* processo
|
|
177
|
+
* Por default NÃO instala nada: sem `redirectConsole` e sem `fatalHandlers`, nada
|
|
178
|
+
* no processo é tocado. Esses dois mexem no ciclo de vida (o que `console.log`
|
|
179
|
+
* faz, como o processo morre), então continuam sendo escolha declarada do
|
|
180
|
+
* consumidor — só não exigem mais uma chamada separada cada.
|
|
181
|
+
*
|
|
182
|
+
* const { logger } = buildNestLogger({
|
|
183
|
+
* service: 'gyra-core',
|
|
184
|
+
* loki: { host },
|
|
185
|
+
* redirectConsole: true,
|
|
186
|
+
* fatalHandlers: true,
|
|
187
|
+
* });
|
|
188
|
+
*
|
|
189
|
+
* Num serviço com vários loggers, peça `fatalHandlers` em UM deles — os handlers
|
|
190
|
+
* são recurso único do processo.
|
|
202
191
|
*/
|
|
203
192
|
export const buildNestLogger = (options: LoggerOptions): BuiltLogger => {
|
|
204
193
|
const lineFormat = options.pretty
|
|
205
194
|
? buildPrettyFormat()
|
|
206
195
|
: format.combine(format.timestamp(), format.json());
|
|
207
196
|
|
|
208
|
-
/*
|
|
209
|
-
Passar os dois é ambíguo: um pede para construir um transport novo, o outro
|
|
210
|
-
para reusar um existente. Falhar alto é melhor que escolher em silêncio e
|
|
211
|
-
deixar o consumidor com dois batchers sem saber.
|
|
212
|
-
*/
|
|
213
|
-
if (options.loki && options.lokiTransport) {
|
|
214
|
-
throw new Error(
|
|
215
|
-
'[log-transport] `loki` e `lokiTransport` sao mutuamente exclusivos: ' +
|
|
216
|
-
'use `loki` para construir um transport novo, ou `lokiTransport` para ' +
|
|
217
|
-
'reusar um ja construido por createLokiTransport().',
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
197
|
const transportsList: any[] = [
|
|
222
198
|
new transports.Console({ format: lineFormat }),
|
|
223
199
|
];
|
|
224
200
|
|
|
225
201
|
let lokiTransport: LokiTransport | undefined;
|
|
226
202
|
|
|
227
|
-
if (options.
|
|
228
|
-
lokiTransport = options.lokiTransport as LokiTransport;
|
|
229
|
-
transportsList.push(lokiTransport);
|
|
230
|
-
} else if (options.loki) {
|
|
203
|
+
if (options.loki) {
|
|
231
204
|
lokiTransport = buildLokiTransport(
|
|
232
205
|
options.loki,
|
|
233
206
|
{
|
|
@@ -251,5 +224,25 @@ export const buildNestLogger = (options: LoggerOptions): BuiltLogger => {
|
|
|
251
224
|
transports: transportsList,
|
|
252
225
|
});
|
|
253
226
|
|
|
254
|
-
|
|
227
|
+
/*
|
|
228
|
+
Os dois efeitos de processo continuam OPT-IN — o consumidor escreve `true`, não
|
|
229
|
+
herda nada por importar o pacote. O que mudou na 0.2.0 foi só a ergonomia: eram
|
|
230
|
+
duas chamadas extras com o `logger` e o `lokiTransport` costurados na mão, e o
|
|
231
|
+
`pretty` repetido. "Explícito" não precisava significar "separado".
|
|
232
|
+
*/
|
|
233
|
+
if (options.redirectConsole) {
|
|
234
|
+
redirectConsoleToNestLogger({ pretty: options.pretty });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
let unregisterFatalHandlers: (() => void) | undefined;
|
|
238
|
+
|
|
239
|
+
if (options.fatalHandlers) {
|
|
240
|
+
unregisterFatalHandlers = registerFatalHandlers(
|
|
241
|
+
logger,
|
|
242
|
+
lokiTransport,
|
|
243
|
+
options.fatalHandlers === true ? {} : options.fatalHandlers,
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return { logger, lokiTransport, unregisterFatalHandlers };
|
|
255
248
|
};
|
package/src/options.ts
CHANGED
|
@@ -15,37 +15,6 @@
|
|
|
15
15
|
Quem lê env é o serviço, no entrypoint, onde o env já mora hoje.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
/*
|
|
19
|
-
Estrutura mínima do transport que o pacote manipula, declarada aqui para o
|
|
20
|
-
`options.ts` não precisar importar o winston-loki.
|
|
21
|
-
|
|
22
|
-
Lista os membros que são de fato tocados — `log` pelo winston ao montar o
|
|
23
|
-
logger, e `flush`/`close`/`once`/`off` pelo caminho de exceção fatal.
|
|
24
|
-
|
|
25
|
-
Era `object`, que aceitava `{ qualquer: 'coisa' }` e até um `Date` em tempo de
|
|
26
|
-
compilação; o erro só aparecia no boot, quando o winston recusava o transport
|
|
27
|
-
com "Invalid transport, must be an object with a log method".
|
|
28
|
-
*/
|
|
29
|
-
export interface LokiTransportLike {
|
|
30
|
-
/*
|
|
31
|
-
Todos os membros são opcionais, e isso é deliberado — não desleixo.
|
|
32
|
-
|
|
33
|
-
Não existe membro que dê para exigir: o tipo real do `LokiTransport` declara
|
|
34
|
-
`log` e `flush` como opcionais, então exigir qualquer um deles rejeitaria o
|
|
35
|
-
transport de verdade. Tentei, e o `tsc` recusou o caso legítimo.
|
|
36
|
-
|
|
37
|
-
Com todos opcionais, a detecção de "weak type" do TypeScript faz o trabalho:
|
|
38
|
-
um objeto sem NENHUMA propriedade em comum com esta interface é rejeitado. É o
|
|
39
|
-
suficiente para pegar `{ qualquer: 'coisa' }` e `Date`, que passavam quando o
|
|
40
|
-
tipo era `object`.
|
|
41
|
-
*/
|
|
42
|
-
log?: unknown;
|
|
43
|
-
flush?: () => Promise<void>;
|
|
44
|
-
close?: () => void;
|
|
45
|
-
once?: (event: string, listener: (...args: unknown[]) => void) => unknown;
|
|
46
|
-
off?: (event: string, listener: (...args: unknown[]) => void) => unknown;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
18
|
export interface LokiOptions {
|
|
50
19
|
/* Endereço do Loki. Sem ele não há para onde enviar, então é obrigatório. */
|
|
51
20
|
host: string;
|
|
@@ -68,6 +37,11 @@ export interface LokiOptions {
|
|
|
68
37
|
labels?: Record<string, string>;
|
|
69
38
|
}
|
|
70
39
|
|
|
40
|
+
export interface FatalHandlersOptions {
|
|
41
|
+
flushTimeoutMs?: number;
|
|
42
|
+
exit?: (code: number) => void;
|
|
43
|
+
}
|
|
44
|
+
|
|
71
45
|
export interface FileOptions {
|
|
72
46
|
filename: string;
|
|
73
47
|
}
|
|
@@ -114,34 +88,42 @@ export interface LoggerOptions {
|
|
|
114
88
|
`LOG_GRAFANA_LOKI === 'true'`. Ausente significa não enviar, e o pacote não
|
|
115
89
|
precisa parsear string booleana.
|
|
116
90
|
|
|
117
|
-
Cada chamada
|
|
118
|
-
|
|
91
|
+
Cada chamada constrói um transport novo — e é por isso que o serviço deve
|
|
92
|
+
construir UM logger por processo e passar o handle adiante, em vez de chamar
|
|
93
|
+
isto várias vezes. N loggers seriam N batchers, e a descarga de exceção fatal
|
|
94
|
+
alcançaria apenas um deles.
|
|
119
95
|
*/
|
|
120
96
|
loki?: LokiOptions;
|
|
121
97
|
|
|
122
98
|
/*
|
|
123
|
-
Transport
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
loggers — um para a app e três para conexões RMQ. Com quatro transports
|
|
128
|
-
independentes há quatro batchers, e o `registerFatalHandlers` drena apenas o
|
|
129
|
-
que recebeu: as linhas bufferizadas nos outros três morrem com o processo, que
|
|
130
|
-
é exatamente o sintoma que a entrega confiável existe para impedir.
|
|
99
|
+
Transport de arquivo, usado quando não há Loki. Mantém a precedência do código
|
|
100
|
+
original: havendo `loki`, o arquivo é ignorado.
|
|
101
|
+
*/
|
|
102
|
+
file?: FileOptions;
|
|
131
103
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
104
|
+
/*
|
|
105
|
+
Redireciona `console.*` para o Logger do Nest, para que biblioteca de terceiro
|
|
106
|
+
e código legado que escrevem em `console` também cheguem aos transports.
|
|
135
107
|
|
|
136
|
-
|
|
108
|
+
Continua sendo OPT-IN — trocar os métodos de `console` é efeito colateral global
|
|
109
|
+
do processo, e importar o pacote não deve mudar isso sozinho. O que mudou em
|
|
110
|
+
relação à 0.1.0 é só a ergonomia: o consumidor declara aqui em vez de fazer uma
|
|
111
|
+
segunda chamada e repetir o `pretty`.
|
|
137
112
|
*/
|
|
138
|
-
|
|
113
|
+
redirectConsole?: boolean;
|
|
139
114
|
|
|
140
115
|
/*
|
|
141
|
-
|
|
142
|
-
|
|
116
|
+
Instala os handlers de exceção fatal, com o transport que esta construção usa.
|
|
117
|
+
|
|
118
|
+
`true` para o comportamento padrão, ou um objeto para ajustar (`flushTimeoutMs`,
|
|
119
|
+
`exit`) — o que os testes precisam. O `unregister` volta em
|
|
120
|
+
`unregisterFatalHandlers`, no retorno.
|
|
121
|
+
|
|
122
|
+
Também segue opt-in, e pelo mesmo motivo: mexe no ciclo de vida do processo.
|
|
123
|
+
Num serviço com vários loggers, peça isto em UM deles — os handlers são recurso
|
|
124
|
+
único do processo, e a segunda chamada é ignorada com aviso.
|
|
143
125
|
*/
|
|
144
|
-
|
|
126
|
+
fatalHandlers?: boolean | FatalHandlersOptions;
|
|
145
127
|
}
|
|
146
128
|
|
|
147
129
|
export const DEFAULT_APP_LABEL = 'saas';
|