o
    ?7i_4                     @   s   U d Z ddlZddlZddlmZmZmZmZ ddlmZm	Z	 ddl
Z
eeZG dd dZdaee ed< defd	d
ZdS )zw
Network Traffic Statistics Service

Aggregates and queries network traffic data using Redis for real-time statistics.
    N)DictListOptionalAny)datetime	timedeltac                   @   s(  e Zd ZdZd+defddZ		d,deded	ed
edededee dee fddZde	ee
f fddZd-dede	ee
f fddZd.dedee	ee
f  fddZd.dedee	ee
f  fddZd/dededee	ee
f  fd d!Zd"ed#efd$d%Zd&edefd'd(Zde	ee
f fd)d*ZdS )0TrafficStatsServicez
    Service for aggregating and querying network traffic statistics.

    Uses Redis for:
    - Sliding window counters (1min, 5min, 15min, 1hour)
    - Per-endpoint traffic accumulation
    - Per-tenant bandwidth tracking
    Ntraffic:
key_prefixc                 C   s.   || _ || _|du| _| jstd dS dS )z
        Initialize traffic stats service.

        Args:
            redis_client: Redis client instance (optional)
            key_prefix: Prefix for Redis keys
        Nz:Redis client not provided. Traffic stats will be disabled.)redis_clientr
   enabledloggerwarning)selfr   r
    r   M/lsinfo/ai/hellotax_ai/base_platform/app/services/monitoring/traffic_stats.py__init__   s   
zTrafficStatsService.__init__endpointmethodrequest_sizeresponse_sizestatus_codeduration_ms	tenant_iduser_idc	              
   C   s  | j sdS ztt }	|| }
| dd | d|
 dD ]>}| j d| d|	| |  }| j|dd | j|d	|
 | j|d
| | j|d| | j|| |d  q| j d| }| j|dd | j|d	|
 | j|d
| | j|d| | j|d |r| j d| }| j|dd | j|d	|
 | j|d |r| j d| }| j|dd | j|d	|
 | j|d | jj	| j d||
idd W dS  t
y } ztd|  W Y d}~dS d}~ww )a  
        Record a request's traffic metrics.

        Args:
            endpoint: Normalized endpoint path
            method: HTTP method
            request_size: Request body size in bytes
            response_size: Response body size in bytes
            status_code: HTTP status code
            duration_ms: Request duration in milliseconds
            tenant_id: Tenant ID (optional)
            user_id: User ID (optional)
        Nzrequests:total   zbandwidth:total1min5min15min1hourwindow::requests	bandwidthrequest_bytesresponse_bytes   	endpoint:iQ ztenant:zuser:endpoints:by_bandwidthT)incrz Failed to record traffic stats: )r   inttime_increment_counterr
   _window_secondsr   hincrbyexpirezadd	Exceptionr   error)r   r   r   r   r   r   r   r   r   current_timetotal_bandwidthwindow
window_keyendpoint_key
tenant_keyuser_keyer   r   r   record_request(   sN    
z"TrafficStatsService.record_requestreturnc              
   C   s*  | j s|  S zott }| j d|d  }| j|}t|dd}t|dd}t|dd}t|dd}|d }|d }	t|d	t|	d	t	
  d
|||||dkrdt|| d	nd|dkrpt|| d	ndddW S  ty }
 ztd|
  |  W  Y d}
~
S d}
~
ww )z{
        Get current real-time traffic statistics.

        Returns:
            Dict with current traffic metrics
        zwindow:1min:<      requestsr   	   bandwidth   request_bytes   response_bytesg      N@r'   requests_per_secbytes_per_sec	timestamptotal_requeststotal_bytesr%   r&   avg_request_sizeavg_response_sizecurrentlast_minutezFailed to get current stats: N)r   _empty_statsr+   r,   r
   r   hgetallgetroundr   utcnow	isoformatr2   r   r3   )r   r4   r7   window_datar#   r$   r%   r&   rD   rE   r;   r   r   r   get_current_statst   s:   
z%TrafficStatsService.get_current_statsr    periodc              
   C   s   | j s	|dddS zFtt }| |}|| }| j d| d| }| j|}|t|ddt|ddt|ddt|ddt	 
 d	W S  tyo } ztd
|  |dddW  Y d}~S d}~ww )z
        Get bandwidth usage over a time period.

        Args:
            period: Time period (1min, 5min, 15min, 1hour)

        Returns:
            Dict with bandwidth usage metrics
        r   )rW   rI   rH   r!   r"   r@   r?   rA   rB   )rW   rI   rH   r%   r&   rF   zFailed to get bandwidth usage: N)r   r+   r,   r.   r
   r   rP   rQ   r   rS   rT   r2   r   r3   )r   rW   r4   window_seconds	window_idr7   rU   r;   r   r   r   get_bandwidth_usage   s(   


z'TrafficStatsService.get_bandwidth_usage
   limitc                 C   s(  | j sg S zr| jj| j dd|d dd}g }|D ]Z\}}|d}| j d| }| j|}t|dd}	t|d	d}
t|d
d}t|dd}|||	|
|||	dkrct	||	 dnd|	dkrot	||	 dndd q|W S  t
y } ztd|  g W  Y d}~S d}~ww )z
        Get traffic statistics grouped by endpoint.

        Args:
            limit: Maximum number of endpoints to return

        Returns:
            List of endpoint traffic stats
        r)   r   r   T)
withscoresutf-8r(   r?   r@   rA   rB   r'   )r   r#   rI   r%   r&   rJ   rK   z#Failed to get traffic by endpoint: N)r   r   	zrevranger
   decoderP   r+   rQ   appendrR   r2   r   r3   )r   r\   top_endpointsresultsendpoint_bytesr5   r   r8   endpoint_datar#   r$   r%   r&   r;   r   r   r   get_traffic_by_endpoint   sB   




z+TrafficStatsService.get_traffic_by_endpointc              
   C   s  | j sg S zeg }d}	 | jj|| j ddd\}}|| |dkr$nqg }|d| D ]-}|ddd	 }| j|}t|	d
d}	t|	dd}
|
t||	|
d q-|jdd dd |d| W S  ty } ztd|  g W  Y d}~S d}~ww )z
        Get traffic statistics grouped by tenant.

        Args:
            limit: Maximum number of tenants to return

        Returns:
            List of tenant traffic stats
        r   Tztenant:*d   )matchcountNr^   r"   r?   r@   )r   r#   rI   c                 S   s   | d S )NrI   r   )xr   r   r   <lambda>  s    z;TrafficStatsService.get_traffic_by_tenant.<locals>.<lambda>)keyreversez!Failed to get traffic by tenant: )r   r   scanr
   extendr`   splitrP   r+   rQ   ra   sortr2   r   r3   )r   r\   tenant_keyscursorkeysrc   r9   r   tenant_datar#   r$   r;   r   r   r   get_traffic_by_tenant   sB   





z)TrafficStatsService.get_traffic_by_tenantr$   byc              
   C   sP   | j sg S z| |W S  ty' } ztd|  g W  Y d}~S d}~ww )z
        Get top bandwidth consumers (users or tenants).

        Args:
            limit: Maximum number of consumers to return
            by: Sort by 'bandwidth' or 'requests'

        Returns:
            List of top consumers
        zFailed to get top consumers: N)r   rf   r2   r   r3   )r   r\   rx   r;   r   r   r   get_top_consumers"  s   z%TrafficStatsService.get_top_consumersrm   valuec                 C   s    | j  | }| j|| dS )zIncrement a Redis counterN)r
   r   incrby)r   rm   rz   full_keyr   r   r   r-   7  s   z&TrafficStatsService._increment_counterr6   c                 C   s   ddddd}| |dS )zGet window size in secondsr>   i,  i  i  r   )rQ   )r   r6   windowsr   r   r   r.   <  s   z#TrafficStatsService._window_secondsc                 C   s(   ddt   dddddddddS )zReturn empty stats structurer   rC   rG   rL   )r   rS   rT   )r   r   r   r   rO   F  s   
z TrafficStatsService._empty_stats)Nr	   )NN)r    )r[   )r[   r$   )__name__
__module____qualname____doc__strr   r+   r   r<   r   r   rV   rZ   r   rf   rw   ry   r-   r.   rO   r   r   r   r   r      s<    		
L- ! 0$0
r   _traffic_stats_servicer=   c               
   C   s   t du rUz0ddl} ddlm} |jr| j|jdd}n| j|j|j|j	|j
dd}t|a td W t S  tyT } ztd|  tdd	a W Y d}~t S d}~ww t S )
z-Get or create traffic stats service singletonNr   )settingsF)decode_responses)hostportdbpasswordr   z,Traffic stats service initialized with Redisz.Failed to initialize Redis for traffic stats: )r   )r   redis
app.configr   	REDIS_URLfrom_urlRedis
REDIS_HOST
REDIS_PORTREDIS_DBREDIS_PASSWORDr   r   infor2   r   )r   r   r   r;   r   r   r   get_traffic_stats_service]  s"   r   )r   r,   loggingtypingr   r   r   r   r   r   json	getLoggerr~   r   r   r   __annotations__r   r   r   r   r   <module>   s    
  M