marekmiklusek/telegram-logger

Send Laravel logs and exceptions to Telegram, with flood protection and redaction of sensitive context.

Maintainers

Package info

github.com/marekmiklusek/telegram-logger

pkg:composer/marekmiklusek/telegram-logger

Transparency log

Statistics

Installs: 981

Dependents: 2

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.3 2026-03-21 15:19 UTC

This package is auto-updated.

Last update: 2026-08-22 13:48:20 UTC


README

blog-featured-how-to-delete-telegram

๐Ÿ“ข Laravel Telegram Logger

๐Ÿš€ Laravel Telegram Logger is a package that sends Laravel log messages and exceptions to Telegram for real-time monitoring.

๐Ÿ“Œ Features

โœ… Real-time logging to Telegram
โœ… Supports all log levels (debug, info, warning, error, etc.)
โœ… Automatic exception handling (captures error file, line, and message)
โœ… Configurable log level filtering
โœ… Silent notifications support (to avoid sound/vibration in Telegram)
โœ… Minimal setup, easy to integrate
โœ… Can be enabled/disabled via configuration

๐Ÿ“‹ Requirements

  • PHP 8.4+
  • Laravel 13.0+
  • allow_url_fopen enabled in php.ini (the default)

๐Ÿ›  Installation

Require the package via Composer:

composer require marekmiklusek/telegram-logger

๐Ÿ”ง Configuration

Publish the package configuration:

php artisan vendor:publish --tag=telegram-logger-config

This will create a config file at config/telegram-logger.php.

.env Configuration

Add your Telegram Bot API token and Chat ID to your .env file:

TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_CHAT_ID=your_chat_id

All other options are configurable via .env as well:

TELEGRAM_LOG_LEVEL=error
TELEGRAM_LOG_SILENT=false
TELEGRAM_LOG_ENABLED=true
TELEGRAM_LOG_THROW_ON_FAILURE=false
TELEGRAM_LOG_MAX_PER_MINUTE=20
TELEGRAM_LOG_DEDUPE_SECONDS=60

Config File (config/telegram-logger.php)

return [
    'bot_token' => (string) env('TELEGRAM_BOT_TOKEN', ''),
    'chat_id' => (string) env('TELEGRAM_CHAT_ID', ''),
    'level' => (string) env('TELEGRAM_LOG_LEVEL', 'error'),
    'silent_notification' => (bool) env('TELEGRAM_LOG_SILENT', false),
    'is_enabled' => (bool) env('TELEGRAM_LOG_ENABLED', true),
    'throw_on_failure' => (bool) env('TELEGRAM_LOG_THROW_ON_FAILURE', false),
    'api_url' => (string) env('TELEGRAM_LOG_API_URL', 'https://api.telegram.org'),
    'max_per_minute' => (int) env('TELEGRAM_LOG_MAX_PER_MINUTE', 20),
    'dedupe_seconds' => (int) env('TELEGRAM_LOG_DEDUPE_SECONDS', 60),
    'redact_keys' => ['password', 'secret', 'token', 'authorization', 'api_key', 'apikey', 'credit_card', 'cvv'],
];

๐Ÿ— Usage

Basic Logging

Use Laravel's Log facade as usual, and errors will be sent to Telegram automatically:

use Illuminate\Support\Facades\Log;

Log::debug('Debug message');
Log::info('Info message');
Log::warning('Warning message');
Log::error('Error message');

Logging with Context

You can pass additional context to logs:

Log::error('User not found', ['user_id' => 42, 'action' => 'login']);

Logging Exceptions

Exceptions are automatically detected and logged:

try {
    throw new \Exception('Database connection failed!');
} catch (\Exception $exception) {
    Log::error('Unhandled exception occurred', ['exception' => $exception]);
}

โš™ How It Works

The package listens to Laravel's logging events and sends structured messages to Telegram.

Example Telegram Log Output

๐Ÿ› ๏ธ Application: MyLaravelApp
๐ŸŒ Environment: production

โŒ Level: ERROR
๐Ÿ“ Message: User not found

๐Ÿ“Œ File:
/var/www/html/app/Http/Controllers/UserController.php
๐ŸŽฏ Line: 45

๐Ÿ“‚ Context:
{
    "user_id": 42,
    "action": "login"
}

โณ Time: 2025-02-19 10:15:30

Example Telegram Log Output (Exception)

๐Ÿ› ๏ธ Application: MyLaravelApp
๐ŸŒ Environment: production

โŒ Level: ERROR
๐Ÿ“ Message: Unhandled exception occurred

๐Ÿ”ฅ Exception: PDOException
๐Ÿ’ฅ Message: Database connection failed!

๐Ÿ“Œ File:
/var/www/html/app/Services/DatabaseService.php
๐ŸŽฏ Line: 30

โณ Time: 2025-02-19 10:18:45

๐ŸŽฏ Advanced Configuration

1๏ธโƒฃ Logger Enablement

You can enable or disable the logger in config/telegram-logger.php:

return [
    'is_enabled' => false,
];

โœ… If true, logs will be sent to Telegram as configured
โœ… If false, the logger will be completely disabled (no logs sent)

2๏ธโƒฃ Log Level Filtering

You can define the minimum log level in config/telegram-logger.php:

return [
    'level' => 'warning',
];
  • debug: Logs everything
  • info: Logs info, notice, warning, error, critical, alert, emergency
  • error: Logs error, critical, alert, emergency
  • critical: Logs only critical, alert, emergency

3๏ธโƒฃ Silent Notifications

Enable silent notifications (no sound/vibration) in config/telegram-logger.php

return [
    'silent_notification' => true,
];

โœ… If true, messages will be sent silently.
โœ… If false, Telegram will send notifications normally.

4๏ธโƒฃ Failure Reporting

By default a failed delivery is swallowed โ€” a logger must never break the application:

return [
    'throw_on_failure' => false,
];

Set TELEGRAM_LOG_THROW_ON_FAILURE=true locally to surface the actual Telegram API error (invalid token, chat not found, rate limit) instead of silence.

If Telegram rejects the message formatting (HTTP 400), the package automatically retries once as plain text, so the log is delivered even when formatting fails.

๐Ÿ’ก Troubleshooting

โ“ Logs not appearing in Telegram?

  1. Set TELEGRAM_LOG_THROW_ON_FAILURE=true โ€” the real API error will be thrown.
  2. Check that your .env values are correctly set:
php artisan config:clear
php artisan config:cache
  1. Ensure your bot has permission to send messages to your chat.
  2. Verify TELEGRAM_LOG_LEVEL is not more severe than the level you are logging.
  3. Confirm allow_url_fopen is enabled โ€” without it the API cannot be reached and the package throws Telegram API is unreachable.

โ“ Behind a proxy?

Point TELEGRAM_LOG_API_URL at your own Bot API endpoint.

โ“ Getting "Chat not found" error?

  • Make sure you have sent a message to your bot first.
  • Use this tool to get your Chat ID.

5๏ธโƒฃ Flood Protection

An error storm must not turn into hundreds of Telegram requests, so two limits apply:

return [
    'dedupe_seconds' => 60,
    'max_per_minute' => 20,
];
  • dedupe_seconds sends an identical message only once per window
  • max_per_minute caps how many messages leave the application per minute

Set either to 0 to disable it. Both require a working cache; when no cache is available they are skipped and logs are delivered as usual.

6๏ธโƒฃ Redacting Sensitive Data

Context is sent to a third party, so known sensitive keys are replaced with [REDACTED]:

Log::error('Login failed', ['email' => 'a@b.com', 'password' => 'hunter2']);
๐Ÿ“‚ Context:
{
    "email": "a@b.com",
    "password": "[REDACTED]"
}

Keys are matched case-insensitively as a substring, so password also covers password_confirmation. Nested arrays are redacted too. Configure the list via redact_keys, or set it to [] to disable redaction.

๐Ÿงช Testing

composer test

This runs the full quality chain: Pint, Rector, PHPStan (level max), 100% type coverage and the test suite with 100% code coverage.

Individual steps:

composer test:lint           # Pint code style check
composer test:refactor       # Rector dry run
composer test:types          # PHPStan level max
composer test:type-coverage  # 100% type coverage
composer test:unit           # Pest with 100% code coverage

To apply automatic fixes:

composer lint       # Pint
composer refactor   # Rector

๐Ÿ“ Changelog

See CHANGELOG.md for release notes and upgrade instructions.

๐Ÿ“œ License

This package is open-source and licensed under the MIT License.