Refactor project structure and enhance Docker support
- Removed unnecessary `__init__.py` and `Dockerfile` to streamline project organization. - Updated `.dockerignore` and `.gitignore` to improve exclusion patterns for build artifacts and environment files. - Enhanced `Makefile` with new commands for managing Docker containers and added help documentation. - Introduced `pyproject.toml` for better project metadata management and dependency tracking. - Updated `requirements.txt` to reflect changes in dependencies for metrics and monitoring. - Refactored various handler files to improve code organization and maintainability.
This commit is contained in:
189
helper_bot/examples/metrics_usage_examples.py
Normal file
189
helper_bot/examples/metrics_usage_examples.py
Normal file
@@ -0,0 +1,189 @@
|
||||
"""
|
||||
Examples of how to use metrics decorators in your bot handlers.
|
||||
These examples show how to integrate metrics without modifying existing logic.
|
||||
"""
|
||||
|
||||
from aiogram import Router, F
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
from aiogram.filters import Command
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
# Import metrics decorators
|
||||
from ..utils.metrics import track_time, track_errors, db_query_time, metrics
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
# Example 1: Basic command handler with timing and error tracking
|
||||
@router.message(Command("start"))
|
||||
@track_time("start_command", "private_handler")
|
||||
@track_errors("private_handler", "start_command")
|
||||
async def start_command(message: Message, state: FSMContext):
|
||||
"""Start command handler with metrics."""
|
||||
# Your existing logic here
|
||||
await message.answer("Welcome! Bot started.")
|
||||
|
||||
# Optionally record custom metrics
|
||||
metrics.record_command("start", "private_handler", "user")
|
||||
|
||||
|
||||
# Example 2: Group command handler with custom labels
|
||||
@router.message(Command("help"), F.chat.type.in_({"group", "supergroup"}))
|
||||
@track_time("help_command", "group_handler")
|
||||
@track_errors("group_handler", "help_command")
|
||||
async def help_command(message: Message):
|
||||
"""Help command handler for groups."""
|
||||
await message.answer("Group help information.")
|
||||
|
||||
# Record command with group context
|
||||
metrics.record_command("help", "group_handler", "group_user")
|
||||
|
||||
|
||||
# Example 3: Callback handler with timing
|
||||
@router.callback_query(F.data.startswith("menu:"))
|
||||
@track_time("menu_callback", "callback_handler")
|
||||
@track_errors("callback_handler", "menu_callback")
|
||||
async def menu_callback(callback: CallbackQuery):
|
||||
"""Menu callback handler."""
|
||||
data = callback.data
|
||||
await callback.answer(f"Menu: {data}")
|
||||
|
||||
# Record callback processing
|
||||
metrics.record_message("callback_query", "callback", "callback_handler")
|
||||
|
||||
|
||||
# Example 4: Database operation with query timing
|
||||
@db_query_time("user_lookup", "users", "select")
|
||||
async def get_user_info(user_id: int):
|
||||
"""Example database function with timing."""
|
||||
# Your database query here
|
||||
# result = await db.fetch_one("SELECT * FROM users WHERE id = ?", user_id)
|
||||
return {"user_id": user_id, "status": "active"}
|
||||
|
||||
|
||||
# Example 5: Complex handler with multiple metrics
|
||||
@router.message(Command("stats"))
|
||||
@track_time("stats_command", "admin_handler")
|
||||
@track_errors("admin_handler", "stats_command")
|
||||
async def stats_command(message: Message):
|
||||
"""Stats command with detailed metrics."""
|
||||
try:
|
||||
# Record command execution
|
||||
metrics.record_command("stats", "admin_handler", "admin_user")
|
||||
|
||||
# Your stats logic here
|
||||
stats = await get_bot_stats()
|
||||
|
||||
# Record successful execution
|
||||
await message.answer(f"Bot stats: {stats}")
|
||||
|
||||
except Exception as e:
|
||||
# Error is automatically tracked by decorator
|
||||
await message.answer("Error getting stats")
|
||||
raise
|
||||
|
||||
|
||||
# Example 6: Message handler with message type tracking
|
||||
@router.message()
|
||||
@track_time("message_processing", "general_handler")
|
||||
async def handle_message(message: Message):
|
||||
"""General message handler."""
|
||||
# Message type is automatically detected by middleware
|
||||
# But you can add custom tracking
|
||||
|
||||
if message.photo:
|
||||
# Custom metric for photo processing
|
||||
metrics.record_message("photo", "general", "photo_handler")
|
||||
|
||||
# Your message handling logic
|
||||
await message.answer("Message received")
|
||||
|
||||
|
||||
# Example 7: Error-prone operation with custom error tracking
|
||||
@track_errors("file_handler", "file_upload")
|
||||
async def upload_file(file_data: bytes, filename: str):
|
||||
"""File upload with error tracking."""
|
||||
try:
|
||||
# Your file upload logic
|
||||
# result = await upload_service.upload(file_data, filename)
|
||||
return {"status": "success", "filename": filename}
|
||||
|
||||
except Exception as e:
|
||||
# Custom error metric
|
||||
metrics.record_error(
|
||||
type(e).__name__,
|
||||
"file_handler",
|
||||
"file_upload"
|
||||
)
|
||||
raise
|
||||
|
||||
|
||||
# Example 8: Background task with metrics
|
||||
async def background_metrics_collection():
|
||||
"""Background task for collecting periodic metrics."""
|
||||
while True:
|
||||
try:
|
||||
# Collect custom metrics
|
||||
active_users = await count_active_users()
|
||||
metrics.set_active_users(active_users, "current")
|
||||
|
||||
# Wait before next collection
|
||||
await asyncio.sleep(300) # 5 minutes
|
||||
|
||||
except Exception as e:
|
||||
metrics.record_error(
|
||||
type(e).__name__,
|
||||
"background_task",
|
||||
"metrics_collection"
|
||||
)
|
||||
await asyncio.sleep(60) # Wait 1 minute on error
|
||||
|
||||
|
||||
# Example 9: Custom metric collection in service
|
||||
class UserService:
|
||||
"""Example service with integrated metrics."""
|
||||
|
||||
@db_query_time("user_creation", "users", "insert")
|
||||
async def create_user(self, user_data: dict):
|
||||
"""Create user with database timing."""
|
||||
# Your user creation logic
|
||||
# user_id = await self.db.execute("INSERT INTO users ...")
|
||||
return {"user_id": 123, "status": "created"}
|
||||
|
||||
@track_time("user_update", "user_service")
|
||||
async def update_user(self, user_id: int, updates: dict):
|
||||
"""Update user with timing."""
|
||||
# Your update logic
|
||||
# await self.db.execute("UPDATE users SET ...")
|
||||
return {"user_id": user_id, "status": "updated"}
|
||||
|
||||
|
||||
# Example 10: Middleware integration example
|
||||
async def custom_middleware(handler, event, data):
|
||||
"""Custom middleware that works with metrics system."""
|
||||
from ..utils.metrics import track_middleware
|
||||
|
||||
async with track_middleware("custom_middleware"):
|
||||
# Your middleware logic
|
||||
result = await handler(event, data)
|
||||
return result
|
||||
|
||||
|
||||
# Helper function for stats (placeholder)
|
||||
async def get_bot_stats():
|
||||
"""Get bot statistics."""
|
||||
return {
|
||||
"total_users": 1000,
|
||||
"active_today": 150,
|
||||
"commands_processed": 5000
|
||||
}
|
||||
|
||||
|
||||
# Helper function for user counting (placeholder)
|
||||
async def count_active_users():
|
||||
"""Count active users."""
|
||||
return 150
|
||||
|
||||
|
||||
# Import asyncio for background task
|
||||
import asyncio
|
||||
Reference in New Issue
Block a user