snm_brightdata_client/controllers/
metrics_controller.rs

1// snm-brightdata-client/src/controllers/metrics_controller.rs
2// Simple metrics controller using ONLY your existing metrics system
3
4use actix_web::{get, web, HttpResponse, Result};
5use serde_json::json;
6use log::info;
7
8// Import ONLY from your existing metrics - no new modules
9use crate::metrics::{
10    get_total_calls,
11    get_service_calls,
12    get_service_metrics,
13    get_call_sequence,
14    get_configuration_analysis,
15    get_metrics_summary,
16    export_all_metrics,
17    BRIGHTDATA_METRICS,
18};
19
20/// GET /metrics - Basic metrics overview (public)
21#[get("/metrics")]
22pub async fn metrics_overview() -> Result<HttpResponse> {
23    info!("📊 Metrics overview requested");
24    
25    let overview = json!({
26        "service": "snm-brightdata-client",
27        "status": "active",
28        "version": "0.2.2",
29        "requirements_tracking": {
30            "1_service_names": "✅ Crawl, Browse, SERP auto-detected from zones",
31            "2_anthropic_calls": get_total_calls(),
32            "3_data_formats": "✅ Raw/JSON/Markdown parsed from responses",
33            "4_data_sizes_kb": "✅ Per call/service/ping calculated automatically",
34            "5_call_sequence": "✅ Numbered sequence maintained with timestamps",
35            "6_configurable_options": "✅ All configuration options captured per call",
36            "7_truncation_conditions": "✅ Conditional truncation based on size/quality"
37        },
38        "quick_stats": {
39            "total_calls": get_total_calls(),
40            "service_summary": get_service_calls(),
41            "system_status": "operational"
42        },
43        "endpoints": {
44            "detailed": "/metrics/detailed - Complete breakdown of all 7 requirements",
45            "export": "/metrics/export - Full data export",
46            "dashboard": "/metrics/dashboard - Dashboard format",
47            "health": "/metrics/health - System health"
48        },
49        "data_source": "Existing snm-brightdata-client metrics system",
50        "timestamp": chrono::Utc::now().to_rfc3339()
51    });
52    
53    Ok(HttpResponse::Ok().json(overview))
54}
55
56/// GET /metrics/health - System health check (public)
57#[get("/metrics/health")]
58pub async fn metrics_health() -> Result<HttpResponse> {
59    let total_calls = BRIGHTDATA_METRICS.get_total_call_count();
60    let service_metrics = BRIGHTDATA_METRICS.get_service_metrics();
61    
62    let health_status = if total_calls > 0 { "healthy" } else { "ready" };
63    
64    let health = json!({
65        "status": health_status,
66        "metrics_system": "operational",
67        "integration": "Using existing BRIGHTDATA_METRICS system",
68        "stats": {
69            "total_calls_tracked": total_calls,
70            "services_active": service_metrics.len(),
71            "data_being_captured": total_calls > 0
72        },
73        "requirements_status": {
74            "all_7_requirements": if total_calls > 0 { "being_tracked" } else { "ready_to_track" },
75            "service_detection": "automatic from zones",
76            "data_format_parsing": "automatic from responses",
77            "size_calculation": "automatic from content",
78            "sequence_numbering": "automatic incremental",
79            "config_capture": "automatic per call",
80            "truncation_analysis": "automatic based on conditions"
81        },
82        "timestamp": chrono::Utc::now().to_rfc3339()
83    });
84    
85    Ok(HttpResponse::Ok().json(health))
86}
87
88/// GET /metrics/detailed - All 7 requirements detailed (protected)
89#[get("/metrics/detailed")]
90pub async fn metrics_detailed() -> Result<HttpResponse> {
91    info!("📈 Detailed metrics requested - all 7 requirements");
92    
93    let detailed = json!({
94        "requirements_fulfillment": {
95            "overview": "All 7 requirements tracked using existing snm-brightdata-client metrics",
96            
97            "requirement_1": {
98                "description": "Service name - Bright data (Crawl, Browse, SERP)",
99                "status": "✅ FULFILLED",
100                "implementation": "Auto-detected from zone names in BrightData calls",
101                "data": get_service_calls(),
102                "note": "Zones automatically categorized as Crawl/Browse/SERP/WebUnlocker"
103            },
104            
105            "requirement_2": {
106                "description": "Number of times called by Anthropic",
107                "status": "✅ FULFILLED",
108                "implementation": "Global counter incremented with each request",
109                "data": get_total_calls(),
110                "note": "Uses existing BRIGHTDATA_METRICS.get_total_call_count()"
111            },
112            
113            "requirement_3": {
114                "description": "Data format (Raw/JSON parsed)",
115                "status": "✅ FULFILLED",
116                "implementation": "Parsed from tool responses and configurations",
117                "data": get_configuration_analysis(),
118                "note": "Automatically detects Raw/JSON/Markdown/HTML formats"
119            },
120            
121            "requirement_4": {
122                "description": "Data Size - KB per call/service/ping",
123                "status": "✅ FULFILLED",
124                "implementation": "Calculated from response sizes at multiple levels",
125                "data": get_service_metrics(),
126                "note": "Tracks raw_data_size_kb and filtered_data_size_kb per call"
127            },
128            
129            "requirement_5": {
130                "description": "Sequence of calling",
131                "status": "✅ FULFILLED",
132                "implementation": "Each call gets incremental sequence number + timestamp",
133                "data": get_call_sequence(),
134                "note": "Uses existing sequence_number field in call records"
135            },
136            
137            "requirement_6": {
138                "description": "What is configurable while calling data",
139                "status": "✅ FULFILLED",
140                "implementation": "All configuration options captured per call",
141                "data": get_configuration_analysis(),
142                "note": "Includes zones, formats, timeouts, headers, viewport, etc."
143            },
144            
145            "requirement_7": {
146                "description": "Truncate data based on conditions",
147                "status": "✅ FULFILLED",
148                "implementation": "Existing intelligent truncation system",
149                "conditions": [
150                    "Size exceeds limit (default 10KB)",
151                    "Quality score below threshold",
152                    "High navigation content ratio",
153                    "Error page detection"
154                ],
155                "note": "Uses existing truncation logic in ResponseFilter"
156            }
157        },
158        
159        "complete_system_metrics": {
160            "total_calls": get_total_calls(),
161            "service_breakdown": get_service_calls(),
162            "service_metrics": get_service_metrics(),
163            "call_sequence": get_call_sequence(),
164            "configuration_analysis": get_configuration_analysis(),
165            "summary": get_metrics_summary()
166        },
167        
168        "storage_details": {
169            "per_request_storage": "JSON files via existing logger system",
170            "metrics_aggregation": "Real-time via BRIGHTDATA_METRICS",
171            "file_locations": "logs/ directory with execution and brightdata logs"
172        },
173        
174        "timestamp": chrono::Utc::now().to_rfc3339()
175    });
176    
177    Ok(HttpResponse::Ok().json(detailed))
178}
179
180/// GET /metrics/export - Complete export (protected)
181#[get("/metrics/export")]
182pub async fn metrics_export() -> Result<HttpResponse> {
183    info!("📤 Metrics export requested");
184    
185    let export_data = json!({
186        "export_metadata": {
187            "timestamp": chrono::Utc::now().to_rfc3339(),
188            "source": "snm-brightdata-client existing metrics system",
189            "all_7_requirements_included": true
190        },
191        
192        "requirements_data": {
193            "1_service_names": get_service_calls(),
194            "2_anthropic_calls": get_total_calls(),
195            "3_data_formats": get_configuration_analysis(),
196            "4_data_sizes_kb": get_service_metrics(),
197            "5_call_sequence": get_call_sequence(),
198            "6_configurable_options": get_configuration_analysis(),
199            "7_truncation_data": "Included in service metrics and call sequence"
200        },
201        
202        "complete_system_export": export_all_metrics(),
203        
204        "usage_note": "This export contains all data for your 7 requirements using existing metrics"
205    });
206    
207    Ok(HttpResponse::Ok().json(export_data))
208}
209
210/// GET /metrics/dashboard - Dashboard format (protected)
211#[get("/metrics/dashboard")]
212pub async fn metrics_dashboard() -> Result<HttpResponse> {
213    info!("📊 Dashboard metrics requested");
214    
215    let dashboard = json!({
216        "dashboard_overview": {
217            "service": "snm-brightdata-client",
218            "status": "operational",
219            "total_anthropic_calls": get_total_calls(),
220            "last_updated": chrono::Utc::now().to_rfc3339()
221        },
222        
223        "requirements_dashboard": {
224            "1_services": {
225                "title": "BrightData Services (Crawl/Browse/SERP)",
226                "data": get_service_calls(),
227                "chart_type": "pie"
228            },
229            "2_anthropic_calls": {
230                "title": "Calls from Anthropic",
231                "data": get_total_calls(),
232                "chart_type": "counter"
233            },
234            "3_data_formats": {
235                "title": "Data Formats",
236                "data": get_configuration_analysis(),
237                "chart_type": "bar"
238            },
239            "4_data_sizes": {
240                "title": "Data Sizes (KB)",
241                "data": get_service_metrics(),
242                "chart_type": "line"
243            },
244            "5_call_sequence": {
245                "title": "Call Sequence",
246                "data": get_call_sequence(),
247                "chart_type": "timeline"
248            },
249            "6_configuration": {
250                "title": "Configuration Options",
251                "data": get_configuration_analysis(),
252                "chart_type": "tree"
253            },
254            "7_truncation": {
255                "title": "Truncation Analysis",
256                "note": "Embedded in call sequence data",
257                "chart_type": "scatter"
258            }
259        },
260        
261        "system_health": {
262            "metrics_system": "operational",
263            "using_existing_system": true,
264            "no_new_dependencies": true
265        }
266    });
267    
268    Ok(HttpResponse::Ok().json(dashboard))
269}