Logs e request id
import pino from 'pino';
createApp({ logger: pino(), logRequests: true });Logger: compatível com o pino (
info(obj, msg),child()). O padrão,consoleLogger({ level, format, redact, stream }), usa oconsole:format: 'json'gera uma linha JSON por evento, para coletores de log.logger: falsedesliga tudo.Níveis:
trace,debug,info,warn,errorefatal, os mesmos do pino.traceefatalsão opcionais na interfaceLogger, para um logger próprio não precisar implementá-los: usectx.log.trace?.(...).stream: 'stdout': manda todos os níveis para a saída padrão. Por padrão,warn,errorefatalvão para o stderr, que alguns coletores tratam inteiro como erro.Request id: cada requisição recebe
ctx.id, também devolvido no headerX-Request-Id. Um id recebido nesse header é reaproveitado se for seguro; isso é configurável emrequestId.O padrão gera um UUID (
crypto.randomUUID()), que não é previsível e não revela quantas requisições o processo atendeu. Se a alocação por requisição importar mais que isso, troque o gerador:tsimport { randomUUID } from 'node:crypto'; const prefix = randomUUID().slice(0, 8); // único por processo let seq = 0; createApp({ requestId: { generate: () => `${prefix}-${(++seq).toString(36)}` } });Num benchmark de
GETsimples, isso reduziu a alocação por requisição em cerca de 8%, sem diferença mensurável de vazão ou memória.requestId: { header: false }deixa de enviar o header;ctx.ide oreqIddos logs continuam.ctx.log: já inclui oreqId, e otraceIdquando a requisição chega comtraceparent(ou otraceIde ospanIddo span, comtelemetry):ctx.log.info({ userId }, 'user created').Trace recebido: um
traceparentW3C válido é exposto emctx.trace({ traceId, parentSpanId, sampled, tracestate }). SemX-Request-Idrecebido, octx.idpassa a ser otraceId, e logs e traces ficam com a mesma chave. O header é validado pela especificação; um valor inválido é ignorado.logRequests: true: registra método, path, status e duração de cada requisição.Dados sensíveis: headers e body nunca são logados automaticamente. O que você logar passa pelo
redactdo logger padrão. As chavesauthorization,cookie,set-cookie,x-api-key,password,secret,token,access_token,refresh_tokene afins, em qualquer nível, saem como[REDACTED]. A comparação ignora maiúsculas,-e_.tscreateApp({ logger: consoleLogger({ redact: ['cpf', 'cardNumber'] }) }); // soma às chaves padrão; false desligaCom o pino, configure o
redactdele.