Metadata-Version: 2.4
Name: python-telegram-logging
Version: 0.0.2
Summary: A Python logging handler that sends logs to Telegram
Project-URL: GitHub, https://github.com/alcibiadescleinias/python-telegram-logging/
Author-email: Ivan Cheprasov <my.phd.memory@gmail.com>
License: MIT License
        
        Copyright (c) 2024 Ivan
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: aiohttp,handler,logging,requests,telegram
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Logging
Requires-Python: >=3.8
Requires-Dist: aiohttp>=3.8.6
Requires-Dist: requests>=2.31.0
Provides-Extra: dev
Requires-Dist: autoflake==2.1.1; extra == 'dev'
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: flake8>=6.1.0; extra == 'dev'
Requires-Dist: isort>=5.12.0; extra == 'dev'
Requires-Dist: mypy>=1.7.0; extra == 'dev'
Requires-Dist: pylint>=3.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest>=7.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# Python Telegram Logging

[![PyPI version](https://badge.fury.io/py/python-telegram-logging.svg)](https://badge.fury.io/py/python-telegram-logging)
[![CI](https://github.com/alcibiadescleinias/python-telegram-logging/actions/workflows/ci.yml/badge.svg)](https://github.com/alcibiadescleinias/python-telegram-logging/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/alcibiadescleinias/python-telegram-logging/branch/main/graph/badge.svg)](https://codecov.io/gh/alcibiadescleinias/python-telegram-logging)
[![Python Versions](https://img.shields.io/pypi/pyversions/python-telegram-logging.svg)](https://pypi.org/project/python-telegram-logging/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A Python logging handler that sends logs to Telegram with support for both synchronous and asynchronous operations.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**

- [Who is Target User?](#who-is-target-user)
- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
  - [Synchronous Usage](#synchronous-usage)
  - [Asynchronous Usage](#asynchronous-usage)
  - [Queued Usage (for synchronous handlers)](#queued-usage-for-synchronous-handlers)
- [Advanced Usage](#advanced-usage)
  - [Custom Formatting](#custom-formatting)
  - [Error Handling](#error-handling)
- [Handler Comparison](#handler-comparison)
- [Technical Details](#technical-details)
- [Requirements](#requirements)
- [License](#license)
- [TODO](#todo)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Who is Target User?

This package is ideal for developers with simple Python applications who want to receive error notifications directly via Telegram. Suppose you lack the resources to maintain a full-fledged logging/alerting setup using tools like Kibana, Elasticsearch, or Grafana, or do not have time to configure complex alert rules. In that case, this package provides a lightweight and hassle-free solution

## Features

- 🚀 **Multiple Handler Types**:
  - `SyncTelegramHandler`: Synchronous handler using `requests`
  - `AsyncTelegramHandler`: Asynchronous handler with built-in queue using `aiohttp`
  - `QueuedTelegramHandler`: Thread-safe queued wrapper for synchronous handlers only (currently)

- 🔒 **Thread Safety**: All handlers are thread-safe and can be used in multi-threaded applications

- 🎨 **Formatting Support**:
  - HTML formatting
  - Markdown formatting
  - Custom formatters support

- 🛡️ **Error Handling**:
  - Rate limiting with configurable strategies (TODO)
  - Automatic message splitting for long logs
  - Custom error callbacks (in case if message is not sent, raised exception)

## Installation

```bash
pip install python-telegram-logging
```

## Quick Start

Use one of the exanple below or check [examples](examples) folder.

### Synchronous Usage

```python
import logging
from python_telegram_logging import SyncTelegramHandler, ParseMode

# Create and configure the handler
handler = SyncTelegramHandler(
    token="YOUR_BOT_TOKEN",
    chat_id="YOUR_CHAT_ID",
    parse_mode=ParseMode.HTML
)

# Add it to your logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(handler)

# Use it!
logger.info("Hello from Python! 🐍")
```

### Asynchronous Usage

```python
import logging
from python_telegram_logging import AsyncTelegramHandler, ParseMode

# Create and configure the handler
handler = AsyncTelegramHandler(
    token="YOUR_BOT_TOKEN",
    chat_id="YOUR_CHAT_ID",
    parse_mode=ParseMode.HTML
)

# Add it to your logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(handler)

# Use it in your async code!
logger.info("Hello from async Python! 🐍")
```

### Queued Usage (for synchronous handlers)

> ⚠️ **Important**: `QueuedTelegramHandler` is designed to work with synchronous handlers only. For asynchronous applications, use `AsyncTelegramHandler` directly as it already includes queue functionality.

```python
import logging
from python_telegram_logging import SyncTelegramHandler, QueuedTelegramHandler, ParseMode

# Create the base synchronous handler
base_handler = SyncTelegramHandler(
    token="YOUR_BOT_TOKEN",
    chat_id="YOUR_CHAT_ID",
    parse_mode=ParseMode.HTML
)

# Wrap it in a queued handler for non-blocking operation
handler = QueuedTelegramHandler(base_handler, queue_size=1000)

# Add it to your logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(handler)

# Use it!
logger.info("Hello from queued logger! 🐍")
```

## Advanced Usage

### Custom Formatting

```python
import logging
from python_telegram_logging import SyncTelegramHandler, ParseMode

# Create a custom formatter
class HTMLFormatter(logging.Formatter):
    def format(self, record):
        return f"""
<b>{record.levelname}</b>: {record.getMessage()}
<code>
File: {record.filename}
Line: {record.lineno}
</code>
"""

# Use the custom formatter
handler = SyncTelegramHandler(
    token="YOUR_BOT_TOKEN",
    chat_id="YOUR_CHAT_ID",
    parse_mode=ParseMode.HTML
)
handler.setFormatter(HTMLFormatter())
```

### Error Handling

```python
from python_telegram_logging import SyncTelegramHandler

def on_error(error: Exception):
    print(f"Failed to send log to Telegram: {error}")

handler = SyncTelegramHandler(
    token="YOUR_BOT_TOKEN",
    chat_id="YOUR_CHAT_ID",
    error_callback=on_error
)
```

## Handler Comparison

| Feature | SyncTelegramHandler | AsyncTelegramHandler | QueuedTelegramHandler |
|---------|--------------------|--------------------|---------------------|
| Blocking | Yes | No | No |
| Thread-Safe | Yes | Yes | Yes |
| Dependencies | requests | aiohttp | - |
| Use Case | Simple scripts | Async applications | High-performance sync apps |
| Message Order | Guaranteed | Best-effort | Best-effort |
| Queue Support | No | Built-in | Yes (sync handlers only) |
| Handler Type | Sync | Async | Sync wrapper |

## Technical Details

- Rate limiting: Implements a token bucket algorithm to respect Telegram's rate limits
- Message splitting: Automatically splits messages longer than 4096 characters
- Thread safety: Uses appropriate synchronization primitives for each context
- Resource management: Proper cleanup of resources on handler close
- Error handling: Configurable error callbacks and retry strategies

## Requirements

- Python 3.8+
- `requests` >= 2.31.0
- `aiohttp` >= 3.8.6

## License

MIT License

## Contributing

Feel free to open issues or PR.

Please install and run pre-commit rules [.pre-commit-config.yaml](.pre-commit-config.yaml):
```
pre-commit install && ` pre-commit run --all-files
```

## TODO

- [ ] what if queue is full?
> Notes:
> Configurable blocking behavior: Added block_on_full option to either block when the queue is full or continue with alternative handling.
> Selective message dropping: Added discard_level_on_full to allow dropping less important messages (e.g., DEBUG) while ensuring critical messages (ERROR, CRITICAL) are handled.
> Timeout control: Added timeout parameter to prevent indefinite blocking if block_on_full is True.
> Default behavior: By default, it will:
> - Not block (block_on_full=False)
> - Silently drop DEBUG messages when full
> - Call handleError() for more important messages
