bytehide-logs 1.0.1
A powerful and easy-to-use logging library that sends encrypted logs to ByteHide server
Requires Python: >=3.8
Keywords: logs, logging, bytehide, encryption, color, monitoring

# ByteHide Logs - Python SDK

[![PyPI version](https://img.shields.io/pypi/v/bytehide-logs.svg)](https://pypi.org/project/bytehide-logs/)
[![Python versions](https://img.shields.io/pypi/pyversions/bytehide-logs.svg)](https://pypi.org/project/bytehide-logs/)
[![License](https://img.shields.io/pypi/l/bytehide-logs.svg)](https://github.com/bytehide/bytehide-logs-python/blob/main/LICENSE)
[![Downloads](https://img.shields.io/pypi/dm/bytehide-logs.svg)](https://pypi.org/project/bytehide-logs/)

A powerful and easy-to-use logging library that sends encrypted logs to ByteHide server.

## Features

- 🔒 **Encrypted Logs**: All logs are encrypted using XOR cipher before sending
- 🚀 **Asynchronous**: Non-blocking log processing with background worker
- 📊 **Multiple Log Levels**: trace, debug, info, warn, error, critical
- 👤 **User Tracking**: Support for authenticated and anonymous users
- 🏷️ **Tags & Metadata**: Rich context with tags, correlation IDs, and custom metadata
- 📍 **Caller Info**: Automatic detection of file, line, and method information
- 📝 **Code Snippets**: Includes code context around log location
- 💾 **File Persistence**: Optional file output with rotation
- 🎨 **Colored Console**: Beautiful colored output for console
- 🔄 **Offline Support**: Automatic retry when network is unavailable
- 🛡️ **Sensitive Data Masking**: Automatic masking of passwords and tokens
- ⏱️ **Duplicate Suppression**: Prevents spam from identical logs

## Installation

```bash
pip install bytehide-logs
```

## Quick Start

### Option 1: Using Environment Variable (Recommended)

```bash
# Set your token in environment
export BYTEHIDE_LOGS_TOKEN="your-project-token-here"
```

```python
from bytehide_logs import Log

# Initialize from environment variable
Log.set_project()

# Enable console output (optional)
Log.write_to_console()

# Start logging!
Log.info("Application started")
Log.warn("This is a warning")
Log.error("An error occurred", exception=some_exception)
```

### Option 2: Direct Token in Code

```python
from bytehide_logs import Log

# Set your project token directly
Log.set_project_token("your-project-token-here")

# Enable console output (optional)
Log.write_to_console()

# Start logging!
Log.info("Application started")
```

## Configuration

### Environment Variables

The SDK automatically reads configuration from environment variables:

```bash
# Project token (priority order)
export BYTEHIDE_LOGS_TOKEN="your-token"      # Recommended - most specific
export BYTEHIDE_PROJECT_TOKEN="your-token"   # Alternative
export PROJECT_TOKEN="your-token"            # Alternative

# Then in your code
Log.set_project()  # Reads from environment automatically
```

You can also use a `.env` file:

```bash
# .env
BYTEHIDE_LOGS_TOKEN=your-project-token-here
ENVIRONMENT=production
```

### Basic Configuration

```python
from bytehide_logs import Log, LogSettings, LogLevel

# Create custom settings
settings = LogSettings()
settings.console_enabled = True
settings.minimum_level = LogLevel.INFO
settings.include_caller_info = True

# Initialize with settings
Log.initialize(settings)
```

### File Persistence

```python
from bytehide_logs import Log, RollingInterval

# Configure file output with daily rotation
Log.write_to_file(
    file_path="logs/app.log",
    interval=RollingInterval.DAY,
    roll_on_file_size_limit=True,
    file_size_limit_bytes=10 * 1024 * 1024  # 10MB
).info("This log goes to file")
```

### User Identification

```python
from bytehide_logs import Log, AuthUser

# Identify authenticated user
user = AuthUser(
    id="user-123",
    email="user@example.com",
    token="user-token"
)
Log.identify(user, update_previous_logs=True)

# All subsequent logs will include user info
Log.info("User action performed")

# Logout (revert to anonymous)
Log.logout()
```

### Rich Logging with Context

```python
from bytehide_logs import Log

# Log with tags
Log.with_tags("payment", "stripe").error("Payment failed")

# Log with context
Log.with_context("order_id", 12345).info("Order created")

# Log with correlation ID
Log.with_correlation_id("req-uuid-123").warn("Request timeout")

# Combine everything
Log.with_tags("api", "critical") \
   .with_context("endpoint", "/api/users") \
   .with_correlation_id("req-456") \
   .error("API endpoint failed")
```

### Global Metadata

```python
from bytehide_logs import Log

# Add metadata that persists across all logs
Log.add_meta_context("version", "1.0.0")
Log.add_meta_context("environment", "production")
Log.add_meta_context("server", "api-01")

# All logs will now include this metadata
Log.info("Application started")
```

### Exception Logging

```python
from bytehide_logs import Log

try:
    # Some code that might fail
    result = risky_operation()
except Exception as e:
    Log.error("Operation failed", exception=e, context={"user_id": 123})
```

## Log Levels

```python
from bytehide_logs import Log

Log.trace("Detailed trace information")     # Very detailed
Log.debug("Debug information")               # Debug info
Log.info("Informational message")            # General info
Log.warn("Warning message")                  # Warnings
Log.error("Error occurred", exception=ex)    # Errors
Log.critical("Critical failure", exception=ex)  # Critical errors
```

## Advanced Features

### Duplicate Suppression

```python
from datetime import timedelta
from bytehide_logs import Log, LogSettings

settings = LogSettings()
settings.duplicate_suppression_window = timedelta(seconds=5)
Log.initialize(settings)

# These logs will be suppressed if identical within 5 seconds
Log.info("Repeated message")
Log.info("Repeated message")  # Suppressed
```

### Sensitive Data Masking

```python
from bytehide_logs import Log, LogSettings

settings = LogSettings()
settings.mask_sensitive_data = ["password", "token", "secret"]
Log.initialize(settings)

# The word "password" will be masked as "****"
Log.info("User password is: secretpass123")
# Output: "User **** is: secretpass123"
```

### Environment Variables

You can configure the SDK using environment variables:

```bash
export PROJECT_TOKEN="your-token"
export ENVIRONMENT="production"

# Or with BYTEHIDE_ prefix
export BYTEHIDE_PROJECT_TOKEN="your-token"
export BYTEHIDE_ENVIRONMENT="production"
```

```python
from bytehide_logs import Log

# Token will be loaded from environment
Log.info("This will use token from environment")
```

### Manual Flush

```python
from bytehide_logs import Log

# Force send all pending logs (useful before app exit)
Log.flush()
```

## Framework Integration

### Flask

```python
from flask import Flask, request, g
from bytehide_logs import Log
import uuid

app = Flask(__name__)
Log.set_project_token("your-token")

@app.before_request
def before_request():
    g.correlation_id = str(uuid.uuid4())
    Log.with_correlation_id(g.correlation_id).info(f"Request started: {request.path}")

@app.after_request
def after_request(response):
    Log.with_correlation_id(g.correlation_id).info(f"Request completed: {request.path} - {response.status_code}")
    return response

@app.errorhandler(Exception)
def handle_error(error):
    Log.with_correlation_id(g.correlation_id).error("Request failed", exception=error)
    return "Internal Server Error", 500
```

### Django

```python
# settings.py
from bytehide_logs import Log, LogSettings

Log.set_project_token("your-token")
settings = LogSettings()
settings.console_enabled = True
Log.initialize(settings)

# middleware.py
from bytehide_logs import Log
import uuid

class BytehideLogsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request.correlation_id = str(uuid.uuid4())
        Log.with_correlation_id(request.correlation_id).info(f"Request: {request.path}")

        response = self.get_response(request)

        Log.with_correlation_id(request.correlation_id).info(f"Response: {response.status_code}")
        return response
```

### FastAPI

```python
from fastapi import FastAPI, Request
from bytehide_logs import Log
import uuid

app = FastAPI()
Log.set_project_token("your-token")

@app.middleware("http")
async def log_requests(request: Request, call_next):
    correlation_id = str(uuid.uuid4())
    Log.with_correlation_id(correlation_id).info(f"Request: {request.url.path}")

    response = await call_next(request)

    Log.with_correlation_id(correlation_id).info(f"Response: {response.status_code}")
    return response

@app.get("/")
async def root():
    Log.info("Root endpoint called")
    return {"message": "Hello World"}
```

## API Reference

### Log Class (Main Facade)

- `Log.set_project_token(token: str)` - Set project token
- `Log.initialize(settings: LogSettings)` - Initialize with settings
- `Log.trace/debug/info/warn/error/critical(message, **options)` - Log at various levels
- `Log.identify(user: AuthUser, update_previous_logs: bool)` - Identify user
- `Log.logout()` - Logout current user
- `Log.add_meta_context(key, value)` - Add global metadata
- `Log.enable() / disable()` - Enable/disable logging
- `Log.flush()` - Force flush pending logs
- `Log.write_to_file(...)` - Configure file output
- `Log.write_to_console()` - Enable console output

### LogSettings

- `persist: bool` - Enable file persistence
- `file_path: str` - Log file path
- `rolling_interval: RollingInterval` - File rotation interval
- `console_enabled: bool` - Enable console output
- `include_caller_info: bool` - Include file/line/method info
- `mask_sensitive_data: List[str]` - Fields to mask
- `minimum_level: LogLevel` - Minimum level to log
- `duplicate_suppression_window: timedelta` - Duplicate suppression window

## Performance

- ✅ **Non-blocking**: All log processing happens in background threads
- ✅ **Async Queue**: Logs are queued and processed asynchronously
- ✅ **Auto-retry**: Failed requests are automatically retried
- ✅ **Batch Processing**: Logs are processed in batches for efficiency
- ✅ **Auto-flush**: Automatic flush every 3 seconds
- ✅ **Shutdown Hooks**: Guaranteed log delivery on application exit

## License

MIT License - see LICENSE file for details

## Support

- Documentation: https://docs.bytehide.com
- Issues: https://github.com/bytehide/bytehide-logs-python/issues
- Email: support@bytehide.com