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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@blank-software/sentry-nestjs

v1.0.3

Published

Pacchetto npm per integrare NestJS con Sentry e Pino per massima observability

Readme

🚀 NestJS Sentry Integration

Integrazione completa e moderna di NestJS con @sentry/nestjs per error tracking, performance monitoring e logging nativo automatico.

✨ Caratteristiche

  • 🔧 Setup zero-configuration - Funziona subito out-of-the-box
  • 📊 Integrazione Sentry nativa - Usa @sentry/nestjs >= 9.41.0
  • 📝 Dual Logging System - NestJS Logger + Sentry.logger in automatico
  • 🎯 Interceptor automatico - Performance tracking e error handling
  • 🏷️ Decorators avanzati - Accesso a User, Span e Scope
  • 🌍 Modulo globale - Disponibile in tutta l'applicazione
  • 🎭 TypeScript ready - Tipizzazione completa inclusa

📦 Installazione

npm install @blank-software/sentry-nestjs @sentry/nestjs

Nota: Non serve più installare pino o pino-sentry-transport! 🎉

🚀 Setup Rapido

1. Configurazione del modulo principale

import { Module } from '@nestjs/common';
import { SentryModule } from '@blank-software/sentry-nestjs';

@Module({
  imports: [
    SentryModule.forRoot({
      dsn: process.env.SENTRY_DSN,
      environment: process.env.NODE_ENV || 'development',
      debug: process.env.NODE_ENV === 'development',
      tracesSampleRate: 1.0,
      enableLogging: true, // ✅ Abilita logging automatico
      logLevels: ['log', 'warn', 'error'], // ✅ Tipi di log da inviare a Sentry
    }),
    // ... altri moduli
  ],
})
export class AppModule {}

2. Main.ts (Interceptor globale opzionale)

import { NestFactory } from '@nestjs/core';
import { SentryInterceptor, SentryService } from '@blank-software/sentry-nestjs';
import { AppModule } from './app.module';

async function bootstrap() {
  // ✅ Sentry è già inizializzato nel modulo!
  const app = await NestFactory.create(AppModule);
  
  // Interceptor globale per performance tracking automatico
  app.useGlobalInterceptors(new SentryInterceptor(app.get(SentryService)));
  
  await app.listen(3000);
}
bootstrap();

📖 Utilizzo

🎯 Dual Logging System - Due Modi Per Loggare!

1. NestJS Logger (Automatico a Sentry)

import { Injectable, Logger } from '@nestjs/common';

@Injectable()
export class YourService {
  private readonly logger = new Logger(YourService.name);

  someMethod() {
    // ✅ Tutti questi vanno automaticamente a Sentry
    this.logger.log('Info message');     // 📝 Console + Sentry
    this.logger.warn('Warning message'); // ⚠️ Console + Sentry  
    this.logger.error('Error message');  // ❌ Console + Sentry
    this.logger.debug('Debug message');  // 🐛 Console + Sentry
  }
}

2. Sentry Logger Diretto (Con Metadati)

import { Injectable } from '@nestjs/common';
import { SentryService } from '@blank-software/sentry-nestjs';
import * as Sentry from '@sentry/nestjs';

@Injectable()
export class YourService {
  constructor(private readonly sentryService: SentryService) {}

  advancedLogging() {
    // ✅ Usa Sentry.logger direttamente per log strutturati
    Sentry.logger.info('User action performed', {
      action: 'login',
      userId: '123',
      timestamp: new Date(),
      metadata: { ip: '192.168.1.1', userAgent: 'Chrome' }
    });

    // ✅ Oppure usa i wrapper del service
    this.sentryService.logInfo('Business logic executed', {
      operation: 'data-processing',
      duration: '150ms',
      result: 'success'
    });

    this.sentryService.logError('Operation failed', {
      error: 'validation-failed',
      input: { field: 'email' },
      severity: 'medium'
    });
  }
}

🔄 Servizio Sentry Completo

import { Injectable } from '@nestjs/common';
import { SentryService } from '@blank-software/sentry-nestjs';

@Injectable()
export class YourService {
  constructor(private readonly sentryService: SentryService) {}

  async businessLogic() {
    try {
      // Imposta contesto utente
      this.sentryService.setUser({
        id: '123',
        email: '[email protected]',
        username: 'john_doe',
      });

      // Log strutturato per business logic
      this.sentryService.logInfo('Business operation started', {
        operation: 'user-workflow',
        phase: 'initialization',
        timestamp: new Date()
      });

      // Performance tracking
      const transaction = this.sentryService.startTransaction({
        name: 'business-operation',
        op: 'task',
        tags: { component: 'user-service', version: '1.0.0' }
      });

      // Simula operazione
      await this.processUserData();

      // Log successo
      this.sentryService.logInfo('Business operation completed', {
        operation: 'user-workflow',
        phase: 'completion',
        duration: '250ms',
        result: 'success'
      });

      transaction.setStatus('ok');
      transaction.finish();

    } catch (error) {
      // Log errore con contesto
      this.sentryService.logError('Business operation failed', {
        operation: 'user-workflow',
        error: error.message,
        phase: 'execution',
        severity: 'high'
      });

      this.sentryService.captureException(error, 'YourService.businessLogic');
      throw error;
    }
  }

  private async processUserData() {
    this.sentryService.withScope((scope) => {
      scope.setTag('operation', 'data-processing');
      scope.setContext('processing-info', {
        timestamp: new Date(),
        phase: 'validation'
      });
      
      // Log nel contesto dello scope
      this.sentryService.logInfo('Processing user data', {
        step: 'validation',
        rules: ['email', 'phone', 'address']
      });
    });
  }
}

🏷️ Decorators Avanzati

import { Controller, Get, Post, Body } from '@nestjs/common';
import { 
  SentryUser, 
  SentryTransaction, 
  SentryScope,
  User
} from '@blank-software/sentry-nestjs';

@Controller('users')
export class UsersController {
  @Get('profile')
  getProfile(
    @SentryUser() user: User | null,
    @SentryTransaction() transaction: any,
    @SentryScope() scope: any,
  ) {
    // Usa il scope per aggiungere contesto
    scope.setTag('endpoint', 'user-profile');
    scope.setContext('request-info', {
      hasUser: !!user,
      timestamp: new Date()
    });
    
    return { 
      user: user?.email || 'anonymous',
      transactionName: transaction?.name || 'unknown'
    };
  }

  @Post('update')
  updateProfile(
    @Body() data: any,
    @SentryScope() scope: any
  ) {
    // Aggiungi contesto specifico per questa richiesta
    scope.setContext('update-data', data);
    scope.setTag('operation', 'profile-update');
    
    return { message: 'Profile updated', data };
  }
}

🔧 Controller di Debug Completo

import { Controller, Get, Post, Body, Logger } from '@nestjs/common';
import { SentryService } from '@blank-software/sentry-nestjs';
import * as Sentry from '@sentry/nestjs';

@Controller('debug')
export class DebugController {
  private readonly logger = new Logger(DebugController.name);

  constructor(private readonly sentryService: SentryService) {}

  @Get('test-nestjs-logs')
  testNestJSLogs() {
    // ✅ NestJS Logger - Va automaticamente a Sentry
    this.logger.log('✅ NestJS Info log - auto sent to Sentry');
    this.logger.warn('⚠️ NestJS Warning log - auto sent to Sentry');
    this.logger.error('❌ NestJS Error log - auto sent to Sentry');
    this.logger.debug('🐛 NestJS Debug log - auto sent to Sentry');
    
    return { 
      message: 'NestJS native logs sent automatically to Sentry!',
      method: 'NestJS Logger',
      timestamp: new Date()
    };
  }

  @Get('test-sentry-logs')
  testSentryLogs() {
    // ✅ Sentry.logger diretto con metadati
    Sentry.logger.info('📝 Direct Sentry info log', { 
      action: 'test_sentry_log',
      component: 'debug-controller',
      metadata: { test: true, version: '2.0.0' }
    });
    
    Sentry.logger.warn('⚠️ Direct Sentry warning log', { 
      action: 'test_sentry_warn',
      level: 'warning',
      details: { reason: 'test-scenario' }
    });
    
    Sentry.logger.error('❌ Direct Sentry error log', { 
      action: 'test_sentry_error',
      severity: 'high',
      context: { endpoint: '/debug/test-sentry-logs' }
    });

    // ✅ Service wrapper con metadati
    this.sentryService.logInfo('📋 Service wrapper info log', {
      method: 'testSentryLogs',
      wrapper: 'SentryService',
      timestamp: new Date()
    });

    return { 
      message: 'Direct Sentry logs with metadata sent!',
      methods: ['Sentry.logger', 'SentryService wrappers'],
      timestamp: new Date()
    };
  }

  @Get('test-mixed-logs')
  testMixedLogs() {
    // ✅ Combina entrambi gli approcci
    this.logger.log('🚀 NestJS: Starting mixed log test');
    
    this.sentryService.logInfo('🎯 Sentry: Mixed log test started', {
      test: 'mixed-logging',
      phase: 'start',
      approaches: ['nestjs', 'sentry-direct']
    });

    // Warning da entrambi
    this.logger.warn('⚠️ NestJS: This is a warning');
    Sentry.logger.warn('⚠️ Sentry: This is also a warning', { 
      source: 'direct',
      correlation: 'mixed-test' 
    });

    // Error da entrambi  
    this.logger.error('❌ NestJS: This is an error');
    this.sentryService.logError('❌ Sentry: This is also an error', { 
      source: 'service-wrapper',
      severity: 'medium',
      correlation: 'mixed-test'
    });

    return {
      message: 'Mixed logging test completed!',
      approaches: ['NestJS Logger', 'Sentry.logger', 'SentryService'],
      benefits: 'NestJS for simple logs, Sentry for structured data',
      timestamp: new Date()
    };
  }

  @Get('test-structured-logs')
  testStructuredLogs() {
    // ✅ Log strutturati per business analytics
    this.sentryService.logInfo('User workflow started', {
      workflow: 'user-onboarding',
      step: 1,
      stepName: 'registration',
      userId: 'debug-user-123',
      metadata: {
        source: 'web-app',
        campaign: 'debug-test',
        timestamp: new Date(),
        features: ['logging', 'analytics', 'monitoring']
      }
    });

    this.sentryService.logInfo('User workflow progress', {
      workflow: 'user-onboarding',
      step: 2,
      stepName: 'verification',
      userId: 'debug-user-123',
      progress: '50%',
      metadata: {
        verificationMethod: 'email',
        attemptsRemaining: 2
      }
    });

    this.sentryService.logInfo('User workflow completed', {
      workflow: 'user-onboarding',
      step: 3,
      stepName: 'completion',
      userId: 'debug-user-123',
      progress: '100%',
      duration: '125ms',
      result: 'success'
    });

    return {
      message: 'Structured logs sent for business analytics!',
      workflow: 'user-onboarding',
      steps: 3,
      analyticsReady: true,
      timestamp: new Date()
    };
  }

  @Get('health')
  health() {
    return {
      status: 'healthy',
      service: 'sentry-nestjs-integration',
      version: '2.0.0',
      sentry: {
        initialized: true,
        logging: {
          enabled: true,
          methods: ['nestjs-auto', 'sentry-direct', 'service-wrappers'],
          levels: ['log', 'warn', 'error', 'debug']
        },
        integrations: ['console', 'http', 'performance']
      },
      features: {
        'dual-logging-system': true,
        'nestjs-auto-logging': true,
        'sentry-direct-logging': true,
        'structured-logging': true,
        'performance-tracking': true,
        'error-tracking': true,
        'context-management': true
      },
      endpoints: {
        'GET /debug/test-nestjs-logs': 'Test NestJS native logging (auto to Sentry)',
        'GET /debug/test-sentry-logs': 'Test direct Sentry logging with metadata',
        'GET /debug/test-mixed-logs': 'Test mixed logging approaches',
        'GET /debug/test-structured-logs': 'Test structured business logs',
        'GET /debug/health': 'Health check with full feature overview'
      },
      recommendations: {
        simple: 'Use NestJS Logger for simple application logs',
        structured: 'Use Sentry.logger for business analytics with metadata',
        mixed: 'Combine both approaches based on use case'
      },
      timestamp: new Date()
    };
  }
}

⚙️ Configurazione Avanzata

SentryModule.forRoot({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV || 'production',
  debug: process.env.NODE_ENV === 'development',
  
  // Performance Monitoring
  tracesSampleRate: 0.1, // 10% delle transazioni
  profilesSampleRate: 0.1, // 10% profiling (se supportato)
  
  // ✅ Logging Configuration
  enableLogging: true, // Default: true - Abilita logging automatico
  logLevels: ['log', 'warn', 'error', 'debug'], // Livelli da inviare a Sentry
  
  // Custom integrations
  integrations: [
    // ✅ Console integration viene aggiunta automaticamente
    // Puoi aggiungere altre integrazioni personalizzate qui
  ],
})

🌐 Variabili d'ambiente

# Required
SENTRY_DSN=https://your-sentry-dsn-here

# Optional
NODE_ENV=production
SENTRY_DEBUG=false
SENTRY_TRACES_SAMPLE_RATE=0.1

📋 Requisiti

  • Node.js: >= 18.0.0
  • NestJS: >= 10.0.0
  • TypeScript: >= 5.0.0
  • @sentry/nestjs: >= 9.41.0

🚀 Test degli Endpoint

# Test NestJS native logging (auto sent to Sentry)
curl http://localhost:3000/debug/test-nestjs-logs

# Test direct Sentry logging with metadata
curl http://localhost:3000/debug/test-sentry-logs

# Test mixed logging approaches
curl http://localhost:3000/debug/test-mixed-logs

# Test structured business logs
curl http://localhost:3000/debug/test-structured-logs

# Full health check
curl http://localhost:3000/debug/health

Controlla la tua dashboard Sentry per vedere:

  • 📝 Logs automatici da NestJS Logger
  • 📊 Logs strutturati da Sentry.logger
  • 🎯 Performance data dalle transazioni
  • Errori con contesto completo

🔄 API Reference

SentryService - Metodi Principali

| Metodo | Descrizione | Esempio | |--------|-------------|---------| | logInfo(message, extra?) | Log info strutturato | service.logInfo('User login', { userId: '123' }) | | logWarn(message, extra?) | Log warning strutturato | service.logWarn('Slow query', { duration: '500ms' }) | | logError(message, extra?) | Log error strutturato | service.logError('API failure', { endpoint: '/api/users' }) | | logDebug(message, extra?) | Log debug strutturato | service.logDebug('Debug info', { state: 'processing' }) | | captureException(error, context?) | Cattura errore | service.captureException(error, 'MyService.method') | | captureMessage(message, level?) | Invia messaggio | service.captureMessage('Info message', 'info') | | setUser(user) | Imposta contesto utente | service.setUser({ id: '123', email: '[email protected]' }) | | setTag(key, value) | Aggiunge tag | service.setTag('version', '1.0.0') | | setContext(key, context) | Aggiunge contesto | service.setContext('request', { method: 'POST' }) | | withScope(callback) | Scope temporaneo | service.withScope(scope => scope.setTag('temp', 'value')) |

Approcci di Logging

| Approccio | Quando Usare | Vantaggi | Esempio | |-----------|--------------|----------|---------| | NestJS Logger | Log applicativi semplici | Auto a Sentry, facile | logger.error('DB connection failed') | | Sentry.logger | Business analytics | Metadati strutturati | Sentry.logger.info('User signup', { plan: 'pro' }) | | Service Wrappers | Via di mezzo | Convenienza + metadati | service.logInfo('Order processed', { orderId: '123' }) |

Decorators

| Decorator | Descrizione | Uso | |-----------|-------------|-----| | @SentryUser() | Ottiene user corrente | method(@SentryUser() user: User) | | @SentryScope() | Ottiene scope helper | method(@SentryScope() scope: any) | | @SentryTransaction() | Ottiene transaction/span | method(@SentryTransaction() tx: any) |

📝 Licenza

MIT

🆙 Migrazione da v1.x

Se stai aggiornando dalla versione precedente:

1. Disinstalla dipendenze vecchie

npm uninstall @sentry/node pino pino-sentry-transport

2. Installa nuove dipendenze

npm install @sentry/nestjs@^9.41.0

3. Aggiorna la configurazione

Prima (v1.x):

// ❌ Vecchia configurazione con Pino
SentryModule.forRoot({
  dsn: process.env.SENTRY_DSN,
  pinoOptions: { level: 'info' },
  sentryPinoOptions: { level: 'error' }
});

Dopo (v2.x):

// ✅ Nuova configurazione con dual logging
SentryModule.forRoot({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV,
  enableLogging: true, // NestJS + Sentry logging automatico!
  logLevels: ['log', 'warn', 'error', 'debug'] // Personalizzabile
});

4. Aggiorna il codice

Prima:

// ❌ Vecchio approccio con Pino Logger
constructor(private pinoLogger: SentryPinoLogger) {}

this.pinoLogger.error('Error message');

Dopo:

// ✅ Nuovo approccio dual logging
constructor(private sentryService: SentryService) {}

// Opzione 1: NestJS Logger (automatico a Sentry)
this.logger.error('Error message');

// Opzione 2: Sentry diretto con metadati
this.sentryService.logError('Error message', { 
  context: 'user-service',
  severity: 'high' 
});

💡 Best Practices

📝 Quando Usare Ogni Approccio

NestJS Logger - Per log applicativi standard:

this.logger.log('Server started on port 3000');
this.logger.warn('Database connection slow');
this.logger.error('Authentication failed');

Sentry.logger - Per business analytics e metriche:

Sentry.logger.info('User converted', {
  userId: '123',
  plan: 'premium',
  conversionTime: '5min',
  source: 'landing-page'
});

Service Wrappers - Per comodità con metadati:

this.sentryService.logInfo('Order processed', {
  orderId: 'ORD-123',
  amount: 99.99,
  paymentMethod: 'stripe'
});

🏗️ Struttura Log Consigliata

// ✅ Log strutturato per analytics
{
  message: 'User action completed',
  action: 'purchase',
  userId: '123',
  metadata: {
    product: 'premium-plan',
    amount: 29.99,
    currency: 'EUR',
    paymentMethod: 'stripe',
    timestamp: new Date(),
    sessionId: 'sess-456'
  }
}

🐛 Bug Reports & Feature Requests

Se trovi un bug o vuoi richiedere una nuova funzionalità:

  1. Issues: Bitbucket Issues
  2. Discussions: Usa le discussions per domande generali
  3. Contributi: Pull requests are welcome!

🤝 Contributing

  1. Fork il repository
  2. Crea un branch per la feature (git checkout -b feature/amazing-feature)
  3. Commit le modifiche (git commit -m 'Add amazing feature')
  4. Push al branch (git push origin feature/amazing-feature)
  5. Apri una Pull Request

Made with ❤️ by Blank Software

🎯 Dual Logging System: La potenza di NestJS Logger per semplicità + Sentry.logger per analytics avanzate, tutto in automatico!