@@ -372,3 +372,76 @@ def close(self):
372372 if hasattr (self ._local , 'connection' ) and self ._local .connection :
373373 self ._local .connection .close ()
374374 self ._local .connection = None
375+
376+ def get_aggregated_stats (self , start_time : Optional [datetime ] = None , end_time : Optional [datetime ] = None ) -> Dict [str , Any ]:
377+ """使用SQL直接聚合统计,避免加载大量数据到内存"""
378+ conditions = []
379+ params = []
380+
381+ if start_time :
382+ conditions .append ("timestamp >= ?" )
383+ params .append (start_time .isoformat ())
384+ if end_time :
385+ conditions .append ("timestamp <= ?" )
386+ params .append (end_time .isoformat ())
387+
388+ where_clause = " AND " .join (conditions ) if conditions else "1=1"
389+
390+ with self ._get_cursor () as cursor :
391+ # 总数和动作统计
392+ cursor .execute (f'''
393+ SELECT
394+ COUNT(*) as total,
395+ SUM(CASE WHEN action='block' THEN 1 ELSE 0 END) as blocked,
396+ SUM(CASE WHEN action='allow' THEN 1 ELSE 0 END) as allowed,
397+ SUM(CASE WHEN action='challenge' THEN 1 ELSE 0 END) as challenged,
398+ AVG(risk_score) as avg_risk,
399+ AVG(processing_time_ms) as avg_time
400+ FROM traffic_logs WHERE { where_clause }
401+ ''' , params )
402+ row = cursor .fetchone ()
403+
404+ # 威胁类型统计
405+ cursor .execute (f'''
406+ SELECT threat_type, COUNT(*) as cnt
407+ FROM traffic_logs WHERE { where_clause }
408+ GROUP BY threat_type
409+ ''' , params )
410+ threat_counts = {r [0 ]: r [1 ] for r in cursor .fetchall ()}
411+
412+ # 动作统计
413+ cursor .execute (f'''
414+ SELECT action, COUNT(*) as cnt
415+ FROM traffic_logs WHERE { where_clause }
416+ GROUP BY action
417+ ''' , params )
418+ action_counts = {r [0 ]: r [1 ] for r in cursor .fetchall ()}
419+
420+ # 风险等级统计
421+ cursor .execute (f'''
422+ SELECT risk_level, COUNT(*) as cnt
423+ FROM traffic_logs WHERE { where_clause }
424+ GROUP BY risk_level
425+ ''' , params )
426+ risk_counts = {r [0 ]: r [1 ] for r in cursor .fetchall ()}
427+
428+ # TOP源IP
429+ cursor .execute (f'''
430+ SELECT source_ip, COUNT(*) as cnt
431+ FROM traffic_logs WHERE { where_clause }
432+ GROUP BY source_ip ORDER BY cnt DESC LIMIT 10
433+ ''' , params )
434+ top_ips = [(r [0 ], r [1 ]) for r in cursor .fetchall ()]
435+
436+ return {
437+ 'total_requests' : row [0 ] or 0 ,
438+ 'blocked_requests' : row [1 ] or 0 ,
439+ 'allowed_requests' : row [2 ] or 0 ,
440+ 'challenged_requests' : row [3 ] or 0 ,
441+ 'avg_risk_score' : row [4 ] or 0.0 ,
442+ 'avg_processing_time_ms' : row [5 ] or 0.0 ,
443+ 'threat_counts' : threat_counts ,
444+ 'action_counts' : action_counts ,
445+ 'risk_level_counts' : risk_counts ,
446+ 'top_source_ips' : top_ips
447+ }
0 commit comments