# Tamga - Modern Python Logging Utility ## Overview Tamga is a high-performance Python logging library with colorful console output, multiple output formats, and async capabilities. Named after an ancient Turkic symbol used for marking ownership and identity. **Author**: Doğukan Ürker **License**: MIT **Repository**: https://github.com/DogukanUrker/Tamga Key features: - Buffered writing system (10x faster than traditional logging) - Beautiful console output with Tailwind CSS colors - Multiple outputs: console, file, JSON, SQLite, MongoDB - Multi-service notifications via Apprise (80+ services) - Automatic file rotation with backups - Thread-safe with async MongoDB support - Structured logging with key-value data ## Installation ```bash pip install tamga # Basic installation pip install tamga[notifications] # With notification support pip install tamga[mongo] # With MongoDB integration pip install tamga[all] # All features ``` ## Quick Start ```python from tamga import Tamga # Create logger with default settings logger = Tamga() # Log messages logger.info("Application started") logger.warning("Memory usage at 85%") logger.error("Failed to connect to API") logger.success("User registered successfully") logger.debug("Cache initialized with 1000 entries") logger.critical("Database connection lost") ``` ## Configuration Parameters ### Quick Reference #### Output Configuration - `console_output`: bool = True - Enable logging to console - `colored_output`: bool = True - Enable colored console output - `file_output`: bool = False - Enable logging to a file - `json_output`: bool = False - Enable logging to a JSON file - `mongo_output`: bool = False - Enable logging to MongoDB - `sql_output`: bool = False - Enable logging to SQL database #### Display Settings - `show_date`: bool = True - Show date in console logs - `show_time`: bool = True - Show time in console logs - `show_timezone`: bool = False - Show timezone in console logs #### File Paths and Configurations - `file_path`: str = "tamga.log" - Path to the log file - `json_path`: str = "tamga.json" - Path to the JSON log file - `sql_path`: str = "tamga.db" - Path to the SQL log file - `sql_table_name`: str = "logs" - SQL table name for logs #### MongoDB Configuration - `mongo_uri`: str = None - MongoDB connection URI - `mongo_database_name`: str = "tamga" - MongoDB database name - `mongo_collection_name`: str = "logs" - MongoDB collection name #### Notification Settings - `notify_services`: list = None - List of Apprise notification service URLs - `notify_levels`: list = [] - List of log levels to send notifications for (default includes NOTIFY) - `notify_title`: str = "{appname}: {level} - {date}" - Template for notification titles - `notify_format`: str = "text" - Notification format type (text/markdown/html) #### Size Limits and Buffering - `max_file_size_mb`: int = 10 - Maximum size in MB for log file - `max_json_size_mb`: int = 10 - Maximum size in MB for JSON file - `max_sql_size_mb`: int = 50 - Maximum size in MB for SQL file - `enable_backup`: bool = True - Enable backup when max size is reached - `buffer_size`: int = 50 - Number of logs to buffer before writing to file ### Configuration Examples #### Display Settings ```python logger = Tamga( # Console output colored_output=True, # Enable colored output (default: True) console_output=True, # Enable console logging (default: True) # Timestamp components show_date=True, # Show date (default: True) show_time=True, # Show time (default: True) show_timezone=False, # Show timezone (default: False) ) ``` #### Output Destinations ```python logger = Tamga( # File outputs file_output=False, # Enable file logging (default: False) file_path="tamga.log", # Log file path (default: "tamga.log") json_output=False, # Enable JSON logging (default: False) json_path="tamga.json", # JSON file path (default: "tamga.json") sql_output=False, # Enable SQLite logging (default: False) sql_path="tamga.db", # SQLite file path (default: "tamga.db") sql_table_name="logs", # Table name (default: "logs") # External services mongo_output=False, # Enable MongoDB (default: False) ) ``` #### Performance Settings ```python logger = Tamga( # Buffer configuration buffer_size=50, # Logs to buffer before writing (default: 50) # File rotation (in MB) max_file_size_mb=10, # Max log file size (default: 10) max_json_size_mb=10, # Max JSON file size (default: 10) max_sql_size_mb=50, # Max SQLite size (default: 50) enable_backup=True, # Create backups on rotation (default: True) ) ``` #### MongoDB Configuration ```python logger = Tamga( mongo_output=True, mongo_uri="mongodb+srv://user:pass@cluster.mongodb.net", mongo_database_name="tamga", # Default: "tamga" mongo_collection_name="logs", # Default: "logs" ) ``` #### Notification Configuration ```python logger = Tamga( # Apprise notification services (supports 80+ services) notify_services=[ # Discord "discord://webhook_id/webhook_token", # Slack "slack://tokenA/tokenB/tokenC/#channel", # Email via SMTP "mailto://user:pass@smtp.gmail.com:587/?to=alerts@company.com", # SMS via Twilio "twilio://SID:Token@+1234567890/+0987654321", # Telegram "tgram://bot_token/chat_id", # Microsoft Teams "msteams://TokenA/TokenB/TokenC/", # And many more... ], # Which log levels trigger notifications notify_levels=["NOTIFY"], # Default: ["NOTIFY"] # Notification title template notify_title="{appname}: {level} - {date}", # Default template # Format: "text", "markdown", or "html" notify_format="text", # Default: "text" ) ``` ## Logging Methods ### Standard Levels ```python logger.info("Informational message") # Sky blue logger.warning("Warning message") # Amber logger.error("Error occurred") # Rose logger.success("Operation completed") # Emerald logger.debug("Debug information") # Indigo logger.critical("Critical failure") # Red logger.database("Query executed") # Green logger.notify("Important notification") # Purple - sends notification logger.metric("Response time: 125ms") # Cyan logger.trace("Detailed trace info") # Gray ``` **Note on `notify()`**: This method sends notifications through configured Apprise services. You can also configure other levels to trigger notifications: ```python logger = Tamga( notify_services=["discord://webhook_id/webhook_token"], notify_levels=["CRITICAL", "ERROR", "NOTIFY"], # These levels send notifications ) # These trigger notifications: logger.critical("System down") logger.error("Payment failed") logger.notify("New customer signed up!") # This doesn't trigger notification: logger.warning("High memory usage") # WARNING not in notify_levels ``` ### Custom Logging ```python # Custom level and color logger.custom("Deploy completed", "DEPLOY", "purple") # Structured logging with key-value data using any log method logger.info("User action", user_id="123", action="login", ip_address="192.168.1.1", success=True ) # Works with all log levels logger.error("Database connection failed", host="localhost", port=5432, timeout=30) logger.success("Payment processed", amount=99.99, currency="USD", method="credit_card") logger.warning("High memory usage", memory_pct=85, threshold=80) logger.critical("System overload", cpu_pct=95, memory_pct=98) ``` ### Advanced Notification Usage ```python # Send notification with custom title logger.notify("Payment processed", title="💰 Payment Alert") # Send to specific services (overrides default) logger.notify( "Urgent: Server down", services=["mailto://admin@company.com", "sms://..."] ) ``` ### Buffer Control ```python # Force write all buffered logs logger.flush() ``` ## Output Formats ### Console ``` [28.06.25 | 14:30:45 | UTC] INFO Application started [28.06.25 | 14:30:46 | UTC] ERROR Connection failed ``` ### File (tamga.log) ``` [28.06.25 | 14:30:45 | UTC] INFO: Application started [28.06.25 | 14:30:46 | UTC] ERROR: Connection failed ``` ### JSON ```json { "level": "INFO", "message": "Application started", "date": "28.06.25", "time": "14:30:45", "timezone": "UTC", "timestamp": 1719584445.123456 } ``` ### SQLite Schema ```sql CREATE TABLE logs ( level TEXT, message TEXT, date TEXT, time TEXT, timezone TEXT, timestamp REAL ) ``` ## Common Usage Patterns ### Production Configuration ```python import os logger = Tamga( # File logging with rotation file_output=True, file_path="logs/app.log", max_file_size_mb=50, enable_backup=True, # JSON for log aggregation json_output=True, # Performance optimization console_output=False, buffer_size=200, # Centralized logging mongo_output=True, mongo_uri=os.getenv("MONGO_URI"), # Multi-service notifications for critical events notify_services=[ # Discord webhook for dev team os.getenv("DISCORD_WEBHOOK", "discord://webhook_id/webhook_token"), # Slack for ops team os.getenv("SLACK_WEBHOOK", "slack://tokenA/tokenB/tokenC/#alerts"), # Email notifications f"mailto://{os.getenv('SMTP_USER')}:{os.getenv('SMTP_PASS')}@{os.getenv('SMTP_SERVER')}:587/?to={os.getenv('ALERT_EMAIL')}", # SMS for critical issues os.getenv("TWILIO_SMS", "twilio://SID:Token@+1234567890/+0987654321"), ] if os.getenv("NOTIFICATIONS_ENABLED") else [], notify_levels=["CRITICAL", "ERROR", "NOTIFY"], notify_title="🚨 {appname} Alert: {level}", notify_format="markdown", ) ``` ### High-Performance Logging ```python logger = Tamga( file_output=True, console_output=False, # Disable console for speed buffer_size=1000, # Large buffer ) # Process large dataset for i, record in enumerate(large_dataset): logger.info(f"Processing record {record.id}") # Periodic flush to prevent memory buildup if i % 10000 == 0: logger.flush() ``` ### Development Configuration ```python logger = Tamga( # Maximum visibility colored_output=True, show_date=True, show_time=True, show_timezone=True, # Immediate feedback buffer_size=1, # Local file for debugging file_output=True, file_path="debug.log", ) ``` ### Structured Request Logging ```python import time import uuid def log_request(request): request_id = str(uuid.uuid4()) start_time = time.time() # Log request details logger.info("Request started", request_id=request_id, method=request.method, path=request.path, ip=request.remote_addr ) try: response = process(request) duration = time.time() - start_time logger.info("Request completed", request_id=request_id, status=response.status_code, duration_ms=round(duration * 1000) ) return response except Exception as e: logger.error(f"Request {request_id} failed: {str(e)}") raise ``` ### Multi-Service Logging ```python service_name = os.getenv("SERVICE_NAME", "unknown") logger = Tamga( # Service-specific collection mongo_output=True, mongo_collection_name=service_name, # Include service context file_output=True, file_path=f"logs/{service_name}.log", ) # Add service context to all logs def log_with_context(message, level="info"): logger.info(message, service=service_name, version=os.getenv("VERSION"), instance=os.getenv("INSTANCE_ID") ) ``` ## Performance Guidelines ### Buffer Size Recommendations - **Real-time monitoring**: `buffer_size=1` (immediate writes) - **Web applications**: `buffer_size=50` (default, balanced) - **Background jobs**: `buffer_size=200-500` (efficient batching) - **Data processing**: `buffer_size=1000+` (maximum performance) ### Performance Tips 1. **Disable console output in production** for 10x speed improvement 2. **Use flush() after critical messages** to ensure immediate write 3. **Increase buffer size** for batch operations 4. **Use MongoDB logging asynchronously** to avoid blocking ### Approximate Throughput - Console (colored): ~1,000 logs/second - File (buffered): ~100,000 logs/second - JSON (buffered): ~80,000 logs/second - SQLite: ~50,000 logs/second - MongoDB (async): ~30,000 logs/second ## File Rotation When a file reaches `max_file_size_mb`: 1. If `enable_backup=True`, creates timestamped backup: - `tamga.log` → `tamga.log.20250628_143022.bak` 2. Clears the original file: - Log files: Emptied - JSON files: Reset to `[]` - SQLite: Records deleted, schema preserved ## Notifications Tamga uses Apprise for notifications, supporting 80+ services including Discord, Slack, Email, SMS, Telegram, Microsoft Teams, and many more. Notifications are sent asynchronously with HTML/Markdown/Text formatting options. Configure which levels trigger notifications: ```python logger = Tamga( notify_services=["discord://webhook_id/webhook_token"], notify_levels=["CRITICAL", "ERROR", "NOTIFY"], notify_format="markdown", # or "html", "text" ) # These trigger notifications: logger.critical("System down") logger.error("Payment failed") logger.notify("New premium subscription!") # This doesn't trigger notification: logger.warning("High memory usage") # WARNING not in notify_levels ``` ## Available Colors Custom logging supports all Tailwind CSS colors: - Grays: slate, gray, zinc, neutral, stone - Colors: red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose ```python logger.custom("Custom event", "EVENT", "purple") logger.custom("Alert", "ALERT", "orange") ``` ## Thread Safety Tamga is thread-safe with locked buffer operations: ```python import threading logger = Tamga(file_output=True) def worker(worker_id): for i in range(100): logger.info(f"Worker {worker_id}: Item {i}") # Safe to use from multiple threads threads = [threading.Thread(target=worker, args=(i,)) for i in range(10)] for t in threads: t.start() for t in threads: t.join() ``` ## Error Handling Tamga handles failures gracefully without crashing your application: - MongoDB connection failures don't affect other outputs - Notification failures don't stop logging - File write errors attempt console fallback ## Best Practices 1. **Use appropriate log levels** - Don't use ERROR for warnings 2. **Flush critical messages** - Ensure important logs are written 3. **Configure for your environment** - Different settings for dev/prod 4. **Use structured logging** - Better for parsing and analysis 5. **Monitor log file sizes** - Enable rotation to prevent disk issues 6. **Set up notifications** - Get alerted for critical events 7. **Optimize buffer size** - Balance performance vs reliability ## Complete Example ```python from tamga import Tamga import os # Production-ready configuration logger = Tamga( # Console only in development console_output=os.getenv("ENV") != "production", # Always log to file file_output=True, file_path="logs/app.log", max_file_size_mb=50, # JSON for log aggregation json_output=True, # Performance settings buffer_size=100 if os.getenv("ENV") == "production" else 10, # MongoDB for centralized logging mongo_output=bool(os.getenv("MONGO_URI")), mongo_uri=os.getenv("MONGO_URI"), # Multi-service notifications notify_services=[ os.getenv("DISCORD_WEBHOOK"), os.getenv("SLACK_WEBHOOK"), f"mailto://{os.getenv('SMTP_USER')}:{os.getenv('SMTP_PASS')}@smtp.gmail.com:587/?to=alerts@company.com", ] if os.getenv("NOTIFICATIONS_ENABLED") else [], notify_levels=["CRITICAL", "NOTIFY"], notify_title="{appname} Alert: {level}", notify_format="markdown", ) # Application usage logger.info("Application starting") logger.info("Configuration loaded", environment=os.getenv("ENV"), debug_mode=True ) try: # Application logic logger.success("Service initialized") # Important business event - triggers notification logger.notify("New premium subscription: user_123 purchased Pro plan") except Exception as e: logger.critical(f"Fatal error: {str(e)}") logger.flush() # Ensure critical error is written raise finally: logger.info("Shutting down") logger.flush() ``` ## Integration Notes - **Flask/Django**: Initialize Tamga at app startup, use throughout views - **AsyncIO**: MongoDB operations are handled asynchronously automatically - **Celery**: Each worker can have its own logger instance - **Docker**: Mount volume for log files to persist across containers ## Summary Tamga provides a modern, fast, and feature-rich logging solution with beautiful console output and extensive integration options. Its buffered architecture and async support make it suitable for everything from simple scripts to high-performance distributed systems.