npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@kueshi/logify

v3.1.4

Published

Logify - Logging padronizado para NestJS, Express, Fastify e Next.js

Readme

NPM Version NPM Downloads License


O Problema

Em arquiteturas de microsserviços, uma única ação de um usuário pode disparar uma cadeia de eventos através de várias APIs, workers em filas (como RabbitMQ/SQS) e tarefas agendadas (CRONs). Rastrear o fluxo completo dessa operação ("tracing") torna-se um desafio. Sem um identificador único que conecte todos os logs, diagnosticar erros e entender o comportamento do sistema é quase impossível.

A Solução: Log Rastreável com Contexto

O Logify resolve isso de forma elegante, garantindo que seus logs tenham rastreabilidade ponta a ponta. Ele gerencia automaticamente um correlation_id e user_id através de AsyncLocalStorage, uma API nativa do Node.js, assegurando que o contexto seja mantido em operações assíncronas.

  • Tracing Automático: Gere um correlation_id único para cada requisição HTTP e propague-o automaticamente.
  • Segurança por Padrão: Dados sensíveis como password, token, cpf são automaticamente ofuscados (data masking) nos logs.
  • Integração Simples: Adicione Logify ao seu projeto NestJS, Express, Fastify ou Next.js com poucas linhas de código.
  • Contexto em Workers: Mantenha o contexto de rastreabilidade em workers e jobs assíncronos.

📚 Tabela de Conteúdos


📦 Instalação

npm install @kueshi/logify

Pré-requisitos: Node.js >= 16.x

🚀 Uso por Framework

O módulo NestJS é o mais completo, oferecendo Injeção de Dependência, Interceptors globais e Decorators para Workers.

1. Configuração Básica (HTTP)

No seu AppModule e main.ts:

// app.module.ts
import { Module } from '@nestjs/common';
import { LogifyModule } from '@kueshi/logify/nest';

@Module({
  imports: [
    LogifyModule.forRoot({
      serviceName: 'minha-api-nest',
      ignoredPaths: ['/health', '/metrics'], // Opcional
    }),
  ],
})
export class AppModule {}
// main.ts
import { LogifyService } from '@kueshi/logify/nest';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { bufferLogs: true });
  // Substitui o logger padrão do NestJS pelo Logify
  app.useLogger(app.get(LogifyService));
  await app.listen(3000);
}
bootstrap();

Resultado: Toda requisição HTTP agora gera logs automáticos de request.start, request.end (com latência) e erros com stack trace, todos com o mesmo correlation_id.

2. Uso em Workers (RabbitMQ / SQS / Cron)

Para manter o correlation_id vindo de uma mensagem de fila, use o decorator @LogifyWorkerContext.

import { LogifyWorkerContext, LogifyService } from '@kueshi/logify/nest';

@Injectable()
export class WorkerService {
  constructor(private readonly logify: LogifyService) {}

  @RabbitSubscribe({ queue: 'fila-processamento' })
  @LogifyWorkerContext() // <--- Mágica: Extrai headers e cria o contexto de log
  async handleMessage(msg: any) {
    // O contexto já existe! Logs daqui pra frente sairão com o ID da mensagem original.
    this.logify.log('Processando mensagem...');
  }
}

3. Propagação Manual de Contexto (Get / Set)

Às vezes, você precisa obter os IDs para enviá-los a outra API ou forçar um contexto manualmente.

import { LogifyService } from '@kueshi/logify/nest';

@Injectable()
export class ProducerService {
  constructor(private readonly logify: LogifyService) {}

  async enviarParaFila(dados: any) {
    // 1. GET: Recupera os headers atuais para propagar o contexto
    const headers = this.logify.getPropagationHeaders();
    
    console.log(`Enviando com ID: ${headers['X-Correlation-Id']}`);

    // Exemplo com AMQP
    await this.amqpConnection.publish('exchange', 'key', dados, { headers });
  }

  async processarAlgoManual(payload: any) {
    // 2. SET (Plano B): Se não puder usar o Decorator, inicie o contexto manualmente
    this.logify.setLoggingContext({
        corr_id: payload.traceId,
        user_id: 'admin-manual'
    });

    this.logify.log('Agora estou logando dentro do contexto manual');
  }
}

1. Configuração

O middleware do Logify deve ser registrado antes das suas rotas.

import express from 'express';
import { createLogifyMiddleware } from '@kueshi/logify/express';

const app = express();

// Registre o middleware
app.use(createLogifyMiddleware({ serviceName: 'api-express' }));

app.get('/', (req, res) => {
  // O middleware já logou o início da requisição (request.start)
  res.send('Hello World'); 
  // O fim da requisição (request.end) será logado automaticamente
});

2. Controle Manual de Contexto (Get / Set)

Fora do NestJS, o controle manual é feito através da classe estática LogifyCore.

import { LogifyCore } from '@kueshi/logify';

app.post('/webhook', (req, res) => {
  // SET: Força um contexto baseado no corpo da requisição
  LogifyCore.setLoggingContext({ 
    corr_id: req.body.transactionId 
  });

  const logger = new LogifyCore('webhook-handler');
  logger.info('Contexto definido manualmente');

  // GET: Pega os headers para chamar outra API e propagar o contexto
  const headers = LogifyCore.getPropagationHeaders();
  // await axios.post('http://outra-api', { ... }, { headers });
  
  res.json({ ok: true });
});

1. Configuração

Use o plugin logifyFastify para integrar com o Fastify.

import Fastify from 'fastify';
import { logifyFastify } from '@kueshi/logify/fastify';

const app = Fastify();

// Registre o plugin
app.register(logifyFastify, { serviceName: 'api-fastify' });

app.get('/', async (req, reply) => {
  return { hello: 'world' }; // Logs automáticos de request e response
});

2. Controle Manual (Get / Set)

Assim como no Express, use a classe estática LogifyCore.

import { LogifyCore } from '@kueshi/logify';

app.get('/manual', async (req, reply) => {
  const ctx = LogifyCore.getLoggingContext();
  const logger = new LogifyCore('manual-route');
  logger.info(`O ID de correlação atual é ${ctx.correlation_id}`);
  return { currentId: ctx.correlation_id };
});

Ideal para o Pages Router (pages/api). Para o App Router, use o controle manual.

1. Configuração (Wrapper de API)

// pages/api/users.ts
import { withLogifyApi } from '@kueshi/logify/next';

const handler = async (req, res) => {
  // Sua lógica de API aqui
  res.status(200).json({ name: 'John Doe' });
};

// Envolva seu handler com o withLogifyApi
export default withLogifyApi(handler, { serviceName: 'api-next' });

2. Server Actions (App Router)

Em Server Actions, não há middlewares tradicionais, então o controle de contexto deve ser manual.

'use server'
import { LogifyCore } from '@kueshi/logify';

export async function minhaServerAction(data: any) {
  // Inicia um novo contexto para este job
  LogifyCore.setLoggingContext({ user_id: 'system-action' });
  
  const logger = new LogifyCore('server-action');
  logger.info('Executando ação no servidor...');
  // ...
}

Para scripts node puros, CRONs fora de um framework ou CLIs.

import { LogifyCore } from '@kueshi/logify';

const logger = new LogifyCore('meu-script-batch');

async function run() {
  // Inicia o contexto de log para este processo
  LogifyCore.setLoggingContext({ corr_id: `batch-${Date.now()}` });

  logger.info('Iniciando processamento...');
  
  try {
     // ... sua lógica de negócio ...
     logger.info('Processamento concluído com sucesso.');
  } catch (err) {
     logger.error('Falha inesperada no script', { err });
  }
}

run();

⚙️ Configuração

As opções podem ser passadas para LogifyModule.forRoot() (NestJS), createLogifyMiddleware() (Express), etc.

| Chave | Tipo | Obrigatório | Descrição | | --------------- | --------- | ----------- | ----------------------------------------------------------------------------------------------------- | | serviceName | string | Sim | Nome do seu serviço/aplicação. Ele aparecerá em todos os logs. | | ignoredPaths | string[]| Não | Uma lista de rotas a serem ignoradas pelo log automático (ex: ['/health', '/metrics']). | | logLevel | string | Não | Nível mínimo de log a ser exibido. Padrão: 'info'. | | prettyPrint | boolean | Não | Formata os logs em formato legível para humanos. Não recomendado para produção. Padrão: false. |


📖 Referência da API

LogifyCore (Estático)

Disponível em @kueshi/logify. Use para controle manual de contexto em qualquer ambiente.

  • setLoggingContext(params) Inicia ou sobrescreve o contexto de log atual.

    • params: object - Pode conter headers (de uma requisição), corr_id, user_id ou access_token (para extrair o user_id).
  • getLoggingContext() Retorna o contexto atual: { correlation_id: string, user_id: string }.

  • getPropagationHeaders(base?) Retorna um objeto de headers ({ 'X-Correlation-Id': ..., 'X-User-Id': ... }) pronto para ser enviado para outras APIs.

    • base: object (opcional) - Headers existentes para mesclar com os do Logify.

LogifyService (Injetável no NestJS)

Disponível via Injeção de Dependência no NestJS.

  • log(message, ...args)

  • error(message, error?, ...args)

  • warn(message, ...args)

  • debug(message, ...args) Métodos padrão de log que injetam o contexto automaticamente.

  • getPropagationHeaders() Wrapper para o método estático LogifyCore.getPropagationHeaders().

  • setLoggingContext(params) Wrapper para o método estático LogifyCore.setLoggingContext().


🤝 Como Contribuir

Contribuições são bem-vindas! Se você tem uma sugestão ou encontrou um bug, por favor, abra uma Issue ou envie um Pull Request.

  1. Faça um Fork do projeto
  2. Crie sua Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit suas mudanças (git commit -m 'Add some AmazingFeature')
  4. Push para a Branch (git push origin feature/AmazingFeature)
  5. Abra um Pull Request

📜 Licença

Este projeto está licenciado sob a Licença MIT. Veja o arquivo LICENSE para mais detalhes.