mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-08-11 11:47:50 +00:00
Refactor log management and usage analytics
This commit is contained in:
+13
-11
@@ -3,36 +3,38 @@ Logging configuration for Routstr.
|
||||
|
||||
CRITICAL LOG MESSAGES FOR USAGE STATISTICS:
|
||||
===========================================
|
||||
The following log messages are parsed by the usage tracking system (routstr/core/admin.py).
|
||||
The following log messages are parsed by the usage tracking system
|
||||
(routstr/core/usage_analytics_store.py and routstr/core/log_manager.py).
|
||||
DO NOT modify or remove these messages without updating the usage tracking logic:
|
||||
|
||||
1. "Received proxy request" (INFO) - routstr/proxy.py
|
||||
- Used to count total incoming requests
|
||||
- Includes model information in context
|
||||
|
||||
2. "Payment adjustment completed for streaming" (INFO) - routstr/upstream/base.py
|
||||
"Payment adjustment completed for non-streaming" (INFO) - routstr/upstream/base.py
|
||||
2. "Calculated token-based cost" (INFO) - routstr/auth.py
|
||||
- Used to track successful completions and revenue
|
||||
- The 'cost_data.total_msats' field is extracted for revenue calculation
|
||||
- Must include 'cost_data' in extra dict
|
||||
- The 'token_cost' and 'model' fields are extracted for dashboard metrics
|
||||
|
||||
3. "Payment processed successfully" (INFO) - routstr/auth.py
|
||||
3. "Max cost payment finalized" (INFO) - routstr/auth.py
|
||||
- Used as the successful completion fallback when token usage is unavailable
|
||||
- The 'charged_amount' and 'model' fields are extracted for dashboard metrics
|
||||
|
||||
4. "Payment processed successfully" (INFO) - routstr/auth.py
|
||||
- Used to count successful payment processing events
|
||||
- Tracks payment-related metrics
|
||||
|
||||
4. "Upstream request failed, revert payment" (WARNING) - routstr/proxy.py
|
||||
5. "Upstream request failed, revert payment" (WARNING) - routstr/proxy.py
|
||||
- Used to track failed requests and refunds
|
||||
- The 'max_cost_for_model' field is extracted for refund calculation
|
||||
- Must include 'max_cost_for_model' in extra dict
|
||||
|
||||
5. Any ERROR level logs with "upstream" in the message
|
||||
6. Any ERROR level logs with "upstream" in the message
|
||||
- Used to count upstream provider errors
|
||||
- Helps identify service reliability issues
|
||||
|
||||
If you need to modify these messages, ensure you also update the parsing logic in:
|
||||
- routstr/core/admin.py:_aggregate_metrics_by_time()
|
||||
- routstr/core/admin.py:_get_summary_stats()
|
||||
- routstr/core/admin.py:get_revenue_by_model()
|
||||
- routstr/core/usage_analytics_store.py
|
||||
- routstr/core/log_manager.py
|
||||
"""
|
||||
|
||||
import logging.config
|
||||
|
||||
@@ -21,7 +21,7 @@ class UsageAnalyticsStore:
|
||||
bytes.
|
||||
"""
|
||||
|
||||
SCHEMA_VERSION = "2"
|
||||
SCHEMA_VERSION = "3"
|
||||
|
||||
def __init__(self, logs_dir: Path, db_path: Path | None = None):
|
||||
self.logs_dir = logs_dir
|
||||
@@ -473,10 +473,7 @@ class UsageAnalyticsStore:
|
||||
elif level == "WARNING":
|
||||
bucket["warnings"] += 1
|
||||
|
||||
completed = (
|
||||
"completed for streaming" in message
|
||||
or "completed for non-streaming" in message
|
||||
)
|
||||
completed, revenue_msats = self._extract_success_metrics(entry, message)
|
||||
if completed:
|
||||
bucket["total_requests"] += 1
|
||||
bucket["successful_chat_completions"] += 1
|
||||
@@ -484,13 +481,9 @@ class UsageAnalyticsStore:
|
||||
model_bucket["requests"] += 1
|
||||
model_bucket["successful"] += 1
|
||||
|
||||
cost_data = entry.get("cost_data")
|
||||
if isinstance(cost_data, dict):
|
||||
actual_cost = cost_data.get("total_msats", 0)
|
||||
if isinstance(actual_cost, (int, float)) and actual_cost > 0:
|
||||
cost_float = float(actual_cost)
|
||||
bucket["revenue_msats"] += cost_float
|
||||
model_bucket["revenue_msats"] += cost_float
|
||||
if revenue_msats > 0:
|
||||
bucket["revenue_msats"] += revenue_msats
|
||||
model_bucket["revenue_msats"] += revenue_msats
|
||||
|
||||
failed = (
|
||||
"upstream request failed" in message
|
||||
@@ -988,6 +981,29 @@ class UsageAnalyticsStore:
|
||||
return None
|
||||
return f"{timestamp[:16]}:00"
|
||||
|
||||
def _extract_success_metrics(
|
||||
self, entry: dict[str, Any], message: str
|
||||
) -> tuple[bool, float]:
|
||||
# These auth logs are emitted once per successful settlement across providers
|
||||
# and avoid duplicate counting from provider-specific completion logs.
|
||||
logger_name = str(entry.get("name", ""))
|
||||
if not logger_name.startswith("routstr.auth"):
|
||||
return False, 0.0
|
||||
|
||||
if "calculated token-based cost" in message:
|
||||
token_cost = entry.get("token_cost", 0)
|
||||
if isinstance(token_cost, (int, float)) and token_cost > 0:
|
||||
return True, float(token_cost)
|
||||
return True, 0.0
|
||||
|
||||
if "max cost payment finalized" in message:
|
||||
charged_amount = entry.get("charged_amount", 0)
|
||||
if isinstance(charged_amount, (int, float)) and charged_amount > 0:
|
||||
return True, float(charged_amount)
|
||||
return True, 0.0
|
||||
|
||||
return False, 0.0
|
||||
|
||||
def _new_minute_stats(self) -> dict[str, float]:
|
||||
return {
|
||||
"total_entries": 0.0,
|
||||
|
||||
@@ -66,9 +66,7 @@ function normalizeBaseUrl(url: string): string {
|
||||
}
|
||||
|
||||
export function CheatSheet(): JSX.Element {
|
||||
const [baseUrl, setBaseUrl] = useState(() =>
|
||||
typeof window === 'undefined' ? '' : ConfigurationService.getLocalBaseUrl()
|
||||
);
|
||||
const [baseUrl, setBaseUrl] = useState('');
|
||||
const [apiKeyInput, setApiKeyInput] = useState('');
|
||||
const [walletInfo, setWalletInfo] = useState<WalletSnapshot | null>(null);
|
||||
const [refundReceipt, setRefundReceipt] = useState<RefundReceipt | null>(
|
||||
|
||||
Reference in New Issue
Block a user