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

pino-telegram

v3.2.0

Published

Free logging solution with beautiful formatting - Unlimited real-time logs through Telegram. Perfect Pino transport for any scale!

Readme

📱 pino-telegram

🆓 FREE logging for your projects! No costs, no limits, just reliable log through Telegram.

The ultimate Pino transport that sends your application logs directly to Telegram - completely free and perfect for startups, side projects, and production applications that need reliable logging without breaking the bank!

npm version License: MIT Node.js Version TypeScript

🎯 Why Choose pino-telegram?

💰 Absolutely FREE

  • No subscription fees - Telegram is completely free
  • No usage limits - Send unlimited logs
  • No vendor lock-in - Own your logging infrastructure
  • Perfect for startups - Start logging immediately without worrying about costs

🚀 Production Ready

  • Real-time notifications - Get instant alerts on your phone
  • Rich formatting - HTML, Markdown support with error stack traces
  • Smart filtering - Only send logs that matter (configurable levels)
  • TypeScript native - Full type safety and IntelliSense support

📱 Accessible Anywhere

  • Mobile first - Monitor your apps from anywhere
  • Team collaboration - Add team members to your logging channel
  • Cross-platform - Works on iOS, Android, Desktop, Web

🚀 Quick Start (2 minutes setup!)

1️⃣ Install the package

npm install pino-telegram
# or
yarn add pino-telegram
# or
pnpm add pino-telegram
# or
bun add pino-telegram

2️⃣ Create a Telegram Bot (30 seconds)

  1. Open Telegram and search for @BotFather
  2. Start a chat and send /newbot
  3. Follow the prompts to create your bot
  4. Copy the bot token (looks like 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)

💡 Pro tip: Save the bot token securely - you'll need it for your app!

3️⃣ Get Your Chat ID

Option A: Quick method

  1. Start a chat with your new bot
  2. Send any message to your bot
  3. Visit: https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
  4. Find the chat ID in the JSON response (message.chat.id)

Option B: Add to group

  1. Create a group and add your bot
  2. Send a message in the group
  3. Visit the same URL above
  4. Use the group chat ID (negative number)

4️⃣ Start Logging!

const pino = require('pino');

export const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: 'YOUR_BOT_TOKEN',
      chatId: 'YOUR_CHAT_ID'
    }
  }
});
import { logger } from './logger'

// Your logs now go directly to Telegram! 🎉
logger.info('🚀 Application started successfully!');
logger.warn('⚠️ High memory usage detected');
logger.error('💥 Database connection failed', { 
  error: 'Connection timeout',
  retries: 3 
});

📱 What You'll See in Telegram

After running the code above, you'll receive formatted messages in your Telegram chat:

💡 Note: Timestamps are optional since Telegram shows message time. The format shown below is with timestamps disabled (recommended).

📱 Telegram Message 1:

[INFO] 🚀 Application started successfully!

📱 Telegram Message 2:

[WARN] ⚠️ High memory usage detected

📱 Telegram Message 3:

[ERROR] 💥 Database connection failed

- error: <code>Connection timeout</code>
- retries: <code>3</code>

📚 Usage Examples

🏗️ Basic Setup

const pino = require('pino');

const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.TELEGRAM_CHAT_ID,
      level: 'info' // Send info, warn, error, fatal
    }
  }
});

logger.info('User registered', { userId: 123, email: '[email protected]' });

🎯 Production Configuration

const pino = require('pino');

const logger = pino({
  transport: {
    targets: [
      // Send errors to Telegram
      {
        target: 'pino-telegram',
        level: 'error',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.TELEGRAM_CHAT_ID,
          parseMode: 'HTML'
        }
      },
      // Also log everything to console
      {
        target: 'pino-pretty',
        level: 'debug',
        options: { colorize: true }
      }
    ]
  }
});

🌐 Express.js Integration

const express = require('express');
const pino = require('pino');

const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.TELEGRAM_CHAT_ID,
      level: 'warn' // Only warnings and errors
    }
  }
});

const app = express();

// Log all requests
app.use((req, res, next) => {
  logger.info(`${req.method} ${req.path}`, {
    ip: req.ip,
    userAgent: req.get('User-Agent')
  });
  next();
});

// Error handling
app.use((err, req, res, next) => {
  logger.error('Unhandled error', {
    error: err.message,
    stack: err.stack,
    path: req.path,
    method: req.method
  });
  res.status(500).json({ error: 'Internal server error' });
});

app.listen(3000, () => {
  logger.info('🚀 Server started on port 3000');
});

🐳 Docker Container Logging

// Perfect for containerized applications
const pino = require('pino');

const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.TELEGRAM_CHAT_ID,
      level: process.env.LOG_LEVEL || 'info'
    }
  }
});

// Container lifecycle events
process.on('SIGTERM', () => {
  logger.warn('📤 Received SIGTERM, shutting down gracefully');
  process.exit(0);
});

process.on('uncaughtException', (err) => {
  logger.fatal('💥 Uncaught exception', { error: err.message, stack: err.stack });
  process.exit(1);
});

🔧 Custom Transport Stream

const pino = require('pino');
const { createTelegramTransport } = require('pino-telegram');

// Create custom transport with advanced options
const telegramStream = createTelegramTransport({
  botToken: process.env.TELEGRAM_BOT_TOKEN,
  chatId: process.env.TELEGRAM_CHAT_ID,
  level: 'error',
  parseMode: 'MarkdownV2',
  apiUrl: 'https://api.telegram.org' // Custom Telegram API URL
});

const logger = pino(telegramStream);

logger.error('Database connection failed', {
  database: 'postgresql',
  host: 'db.example.com',
  port: 5432,
  timeout: 5000
});

📊 Monitoring & Alerts

const pino = require('pino');

const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.TELEGRAM_CHAT_ID,
      level: 'warn'
    }
  }
});

// Performance monitoring
setInterval(() => {
  const memUsage = process.memoryUsage();
  const cpuUsage = process.cpuUsage();
  
  if (memUsage.heapUsed > 100 * 1024 * 1024) { // 100MB
    logger.warn('🔥 High memory usage', {
      heapUsed: `${Math.round(memUsage.heapUsed / 1024 / 1024)}MB`,
      heapTotal: `${Math.round(memUsage.heapTotal / 1024 / 1024)}MB`
    });
  }
}, 60000); // Check every minute

// Business metrics
function processPayment(amount, userId) {
  logger.info('💳 Payment processed', {
    amount: `$${amount}`,
    userId,
    timestamp: new Date().toISOString()
  });
}

⚙️ Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | botToken | string | required | Telegram bot token from @BotFather | | chatId | string | required | Chat ID where messages will be sent | | level | LogLevel | 'info' | Minimum log level: trace, debug, info, warn, error, fatal | | onlyLevels | LogLevel[] | undefined | Send only these specific log levels (takes priority over level) | | excludeLevels | LogLevel[] | undefined | Exclude these specific log levels from being sent | | parseMode | ParseMode | 'HTML' | Message format: HTML, Markdown, MarkdownV2 | | includeTimestamp | boolean | false | Include timestamp in messages (Telegram shows message time by default) | | apiUrl | string | 'https://api.telegram.org' | Telegram API URL (for custom instances) | | threadIds | ThreadIdMapping | undefined | Message thread IDs for organizing logs into separate forum threads |

🧵 Message Thread IDs (Forum Organization)

Telegram supports forum topics and message threads that allow you to organize logs by level within a single chat. This feature is optional - thread IDs are only used when you explicitly provide them:

const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.LOGS_CHAT_ID,
      // OPTIONAL: Only specify threadIds if you want forum organization
      threadIds: {
        info: 123,    // Thread ID 123 for info logs
        warn: 456,    // Thread ID 456 for warning logs
        error: 789,   // Thread ID 789 for error logs
        fatal: 999    // Thread ID 999 for fatal logs
        // Only specify the levels you want to organize
      }
    }
  }
});

Benefits:

  • Optional Feature - Only used when you explicitly configure it
  • Single Chat - All logs in one place, easy to monitor
  • Organized by Level - Each specified log level gets its own thread
  • Forum Structure - Perfect for team discussions and context
  • Flexible - Choose which levels to organize and their thread IDs

Important Notes:

  • No defaults - Thread IDs are only used when you provide them
  • Partial mapping - You can specify thread IDs for only some log levels
  • Custom IDs - Use any thread ID numbers that match your Telegram forum setup

🎯 Advanced Log Filtering

The transport now supports precise log level filtering with three options that work together:

  1. level - Traditional minimum level filtering (backward compatible)
  2. onlyLevels - Send only specific log levels (exact matching)
  3. excludeLevels - Exclude specific log levels from being sent

Priority: onlyLevels > level > excludeLevels

🎯 Multi-Channel Strategy

Perfect for organizing logs by severity across different Telegram channels as your application scales:

// 🌟 RECOMMENDED: Severity-based channel organization
const logger = pino({
  transport: {
    targets: [
      // 🚨 Critical Issues - Immediate attention needed
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.CRITICAL_CHAT_ID,      // -1001111111111
          onlyLevels: ['fatal']
        }
      },
      
      // ❌ Error Logs - Development team monitoring  
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.ERROR_CHAT_ID,         // -1002222222222
          onlyLevels: ['error']
        }
      },
      
      // ⚠️ Warning Logs - Performance monitoring
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.WARNING_CHAT_ID,       // -1003333333333
          onlyLevels: ['warn']
        }
      },
      
      // ℹ️ Business Metrics - Product team insights
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.BUSINESS_CHAT_ID,      // -1004444444444
          onlyLevels: ['info']
        }
      }
    ]
  }
});

// Simple usage - automatic routing, no duplicates!
logger.info('🆕 New user registered');        // → Business channel
logger.warn('⚡ High CPU usage detected');    // → Warning channel
logger.error('🔌 Payment gateway timeout');   // → Error channel  
logger.fatal('💥 Database cluster failure');  // → Critical channel

Benefits:

  • No Duplicates - Each log goes to exactly one channel
  • Team Focus - Each team sees only relevant logs
  • Scalable - Easy to add new channels as you grow
  • Simple Usage - Developers just use standard logger.info(), logger.warn(), etc.

📊 Log Filtering Examples

Traditional Min Level Filtering

// level: 'warn' - sends warn, error, fatal
logger.warn('⚠️ Warning message');    // ✅ Sent
logger.error('❌ Error message');     // ✅ Sent  
logger.fatal('💀 Fatal message');     // ✅ Sent

// These will NOT be sent
logger.info('ℹ️ Info message');       // ❌ Not sent
logger.debug('🐛 Debug message');     // ❌ Not sent
logger.trace('🔍 Trace message');     // ❌ Not sent

Exact Level Matching with onlyLevels

// onlyLevels: ['error'] - sends ONLY errors
const errorLogger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.ERROR_CHAT_ID,
      onlyLevels: ['error']  // Only error messages
    }
  }
});

errorLogger.warn('⚠️ Warning');      // ❌ Not sent
errorLogger.error('❌ Error');       // ✅ Sent
errorLogger.fatal('💀 Fatal');       // ❌ Not sent

Exclude Specific Levels with excludeLevels

// level: 'info' + excludeLevels: ['warn'] - sends info, error, fatal (but not warn)
const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.CHAT_ID,
      level: 'info',
      excludeLevels: ['warn']  // Exclude warnings
    }
  }
});

logger.info('ℹ️ Info message');      // ✅ Sent
logger.warn('⚠️ Warning');           // ❌ Not sent (excluded)
logger.error('❌ Error');            // ✅ Sent
logger.fatal('💀 Fatal');            // ✅ Sent

Enable Timestamps (Optional)

// includeTimestamp: true - adds timestamps at the end of messages
const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.CHAT_ID,
      includeTimestamp: true  // Shows: [INFO] Message content\n2024-12-19T10:30:45.123Z
    }
  }
});

Example with timestamp:

[INFO] 🚀 Application started successfully!
2024-12-19T10:30:45.123Z

🎨 Message Formatting

HTML Format (Default)

// Produces rich formatted messages
logger.error('Database error', { 
  table: 'users', 
  operation: 'SELECT',
  error: new Error('Connection timeout')
});

Result in Telegram:

[ERROR] 2024-12-19T10:30:45.123Z
Database error

Error: Connection timeout
<stack trace here>

Context:
table: users
operation: SELECT

Markdown Format

const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: 'YOUR_TOKEN',
      chatId: 'YOUR_CHAT_ID',
      parseMode: 'Markdown'
    }
  }
});

🛠️ Advanced Features

🎯 Multiple Chat Destinations

🚀 Recommended: Single Logger with Multiple Targets

// Single logger, multiple channels - BEST approach!
const logger = pino({
  transport: {
    targets: [
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.ERROR_CHAT_ID,
          onlyLevels: ['error', 'fatal']  // Only errors and fatal
        }
      },
      {
        target: 'pino-telegram', 
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.WARNING_CHAT_ID,
          onlyLevels: ['warn']  // Only warnings
        }
      },
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.INFO_CHAT_ID,
          onlyLevels: ['info']  // Only info messages
        }
      }
    ]
  }
});

// Now just use normal logging - no duplicates!
logger.info('User registered');     // → Goes to info channel only
logger.warn('High memory usage');   // → Goes to warning channel only  
logger.error('Database failed');    // → Goes to error channel only

Alternative: Separate Loggers (Old approach)

// ⚠️ Can cause duplicates if not careful with levels
const errorLogger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.TEAM_CHAT_ID,
      onlyLevels: ['error', 'fatal']  // Precise control
    }
  }
});

const businessLogger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.BUSINESS_CHAT_ID,
      onlyLevels: ['info']  // Only business events
    }
  }
});

📱 Environment-Based Configuration

// .env file
// TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz
// TELEGRAM_CHAT_ID=-1001234567890
// NODE_ENV=production
// LOG_LEVEL=warn

const pino = require('pino');

const logger = pino({
  transport: {
    target: 'pino-telegram',
    options: {
      botToken: process.env.TELEGRAM_BOT_TOKEN,
      chatId: process.env.TELEGRAM_CHAT_ID,
      level: process.env.NODE_ENV === 'production' ? 'warn' : 'debug'
    }
  }
});

🔄 Error Handling & Resilience

const { createTelegramTransport } = require('pino-telegram');

// The transport handles errors gracefully
// Failed Telegram sends won't crash your app
const transport = createTelegramTransport({
  botToken: 'invalid-token', // Even with invalid credentials
  chatId: 'invalid-chat-id',
  level: 'error'
});

const logger = pino(transport);

// This won't crash your application
logger.error('This error will be logged locally even if Telegram fails');

🎉 Real-World Use Cases

🛒 E-commerce Application

// Order processing
logger.info('📦 New order created', {
  orderId: 'ORD-12345',
  amount: '$99.99',
  customerId: 'CUST-789'
});

// Payment failures
logger.error('💳 Payment failed', {
  orderId: 'ORD-12345',
  paymentMethod: 'credit_card',
  errorCode: 'insufficient_funds'
});

🌐 API Monitoring

// Track API performance
app.use((req, res, next) => {
  const start = Date.now();
  
  res.on('finish', () => {
    const duration = Date.now() - start;
    
    if (duration > 1000) { // Slow requests
      logger.warn('🐌 Slow API request', {
        method: req.method,
        path: req.path,
        duration: `${duration}ms`,
        statusCode: res.statusCode
      });
    }
    
    if (res.statusCode >= 400) { // Errors
      logger.error('❌ API error', {
        method: req.method,
        path: req.path,
        statusCode: res.statusCode,
        userAgent: req.get('User-Agent')
      });
    }
  });
  
  next();
});

🔐 Security Monitoring

// Failed login attempts
logger.warn('🔒 Failed login attempt', {
  email: '[email protected]',
  ip: req.ip,
  userAgent: req.get('User-Agent'),
  attempts: 3
});

// Suspicious activity
logger.error('🚨 Potential brute force attack', {
  ip: req.ip,
  attempts: 10,
  timeWindow: '5 minutes'
});

🔧 TypeScript Support

Full TypeScript support with comprehensive type definitions:

import pino from 'pino';
import { 
  createTelegramTransport, 
  ITelegramTransportOptions, 
  LogLevel, 
  ParseMode 
} from 'pino-telegram';

// Type-safe configuration with new filtering options
const options: ITelegramTransportOptions = {
  botToken: process.env.TELEGRAM_BOT_TOKEN!,
  chatId: process.env.TELEGRAM_CHAT_ID!,
  level: 'warn',                        // LogLevel type
  onlyLevels: ['error', 'fatal'],       // LogLevel[] type  
  excludeLevels: ['debug'],             // LogLevel[] type
  parseMode: 'HTML'                     // ParseMode type
};

// Multi-channel setup with full type safety
const logger = pino({
  transport: {
    targets: [
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN!,
          chatId: process.env.ERROR_CHAT_ID!,
          onlyLevels: ['error'] as LogLevel[]  // Type-safe array
        } satisfies ITelegramTransportOptions
      },
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN!,
          chatId: process.env.INFO_CHAT_ID!,
          onlyLevels: ['info'] as LogLevel[]
        } satisfies ITelegramTransportOptions
      }
    ]
  }
});

// Full type safety and IntelliSense support
logger.info('TypeScript logging', { 
  userId: 123, 
  timestamp: new Date() 
});

🚀 Performance & Best Practices

⚡ Optimization Tips

  1. Use appropriate log levels - Don't send debug logs to Telegram in production
  2. Filter sensitive data - Never log passwords, API keys, or personal data
  3. Batch similar logs - Consider rate limiting for high-frequency events
  4. Use environment variables - Keep tokens secure

📈 Smart Multi-Channel Monitoring

// 🚀 BEST PRACTICE: Single logger with precise channel routing
const logger = pino({
  transport: {
    targets: [
      // 🔒 Security events - only warnings and errors
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.SECURITY_CHAT_ID,
          onlyLevels: ['warn', 'error']  // Precise security filtering
        }
      },
      
      // 💼 Business metrics - only info level
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.BUSINESS_CHAT_ID,
          onlyLevels: ['info']  // Only business events
        }
      },
      
      // 🚨 Critical alerts - only fatal errors
      {
        target: 'pino-telegram',
        options: {
          botToken: process.env.TELEGRAM_BOT_TOKEN,
          chatId: process.env.CRITICAL_CHAT_ID,
          onlyLevels: ['fatal']  // Only critical system failures
        }
      }
    ]
  }
});

// Usage - no duplicates, clear routing
logger.info('💳 Payment processed', { amount: 99.99 });     // → Business channel
logger.warn('🔒 Failed login attempt', { ip: '1.2.3.4' });  // → Security channel  
logger.fatal('💥 Database cluster down');                   // → Critical channel

🤝 Community & Support

📖 Documentation

🐛 Issues & Feature Requests

Found a bug or have a feature request? Open an issue on GitHub!

💬 Community

  • Star this repo if you find it helpful!
  • 🐦 Follow @MrAdib for updates
  • 💬 Join discussions in GitHub Issues

📋 Requirements

  • Node.js >= 20.0.0
  • Pino >= 6.0.0
  • Telegram account (free!)

📄 License

MIT © MrAdib


🙏 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development Setup

git clone https://github.com/JohnAdib/pino-telegram.git
cd pino-telegram
npm install
npm run build

⭐ Star this repo if it helps you save money on logging! ⭐

Made with ❤️ by MrAdib

Free logging for everyone! 🎉