
    ɧ-ib4                        U d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZ d dlZd dlmZ  ej        e          Zda ej        dd	                                          d	k    Z e ej        d
d                    Z e ej        dd                    Z e ej        dd                    Z e ej        dd                    Zh dZddhZdaeej                 e d<   da!eej"                 e d<   da#eej$                 e d<   e G d d                      Z%d Z&de'e%         fdZ(d Z)d Z*d Z+d e,d!e-fd"Z.d#efd$Z/d% Z0d& Z1dS )'    )RequestN)	dataclass)datetime	timedelta)Optional)get_connectionFENABLE_API_LOGGINGtrueLOGGING_SAMPLE_RATEz1.0LOG_RETENTION_DAYS30LOG_BATCH_SIZE10LOG_BATCH_INTERVALz2.0>   .js.css.eot.gif.ico.jpg.png.svg.ttf.jpeg.webp.woff.woff2z/healthz/favicon.ico
_log_queue_log_worker_task_shutdown_eventc                       e Zd ZU dZeed<   eed<   eed<   eed<   eed<   eed<   ee         ed<   eed	<   eed
<   eed<   eed<   eed<   eed<   e	ed<   eed<   dS )LogEntryzData class for API log entries.	timestamp	client_ipmethodurlpathquery_paramsrequest_body
user_agentaccept_languageaccept_encodingrefererx_forwarded_forstatus_codeprocess_timeresponse_sizeN)
__name__
__module____qualname____doc__r   __annotations__strr   intfloat     G/var/www/html/web-builder-api.evdpl.com/src/middleware/mysql_logging.pyr"   r"   $   s         ))NNNKKK	HHH
III3-OOOLLLr;   r"   c                    K   t           rd S 	 t                       d {V } |                     d           d {V  |                                  d {V }|sO|                     d           d {V  |                                  d {V  t
                              d           da d S # t          $ rB}t
                              d|            t
                              d           Y d }~d S d }~ww xY w)NzSHOW TABLES LIKE 'api_logs'ai  
                CREATE TABLE api_logs (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    timestamp DATETIME NOT NULL,
                    client_ip VARCHAR(45) NOT NULL,
                    method VARCHAR(10) NOT NULL,
                    url TEXT NOT NULL,
                    path VARCHAR(255) NOT NULL,
                    query_params JSON,
                    request_body JSON,
                    user_agent TEXT,
                    accept_language VARCHAR(255),
                    accept_encoding VARCHAR(255),
                    referer TEXT,
                    x_forwarded_for VARCHAR(255),
                    status_code INT NOT NULL,
                    process_time FLOAT NOT NULL,
                    response_size INT NOT NULL,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    INDEX idx_timestamp (timestamp),
                    INDEX idx_client_ip (client_ip),
                    INDEX idx_method (method),
                    INDEX idx_path (path),
                    INDEX idx_status_code (status_code)
                )
                z#Created api_logs table with indexesTz(Could not ensure api_logs table exists: zBAPI logging will be disabled until database connection is restored)	_API_LOGS_TABLE_READYr   executefetchonecommitloggerinfo	Exceptionwarning)conntable_existses      r<   _ensure_api_logs_table_existsrI   8   sU      +#%%%%%%%%ll8999999999!]]__,,,,,, 	?,,        8 ++--KK=>>> $   E!EEFFF[\\\s   BB+ +
C757C22C7log_entriesc                 T  K   | sdS 	 t                       d{V }g }| D ]q}|                    |j        |j        |j        |j        |j        |j        |j        |j	        |j
        |j        |j        |j        |j        |j        |j        f           r|                    d|           d{V  |                                 d{V  t&                              dt+          |            d           dS # t,          $ r(}t&                              d|            Y d}~dS d}~ww xY w)z0Insert a batch of log entries into the database.Na^  
            INSERT INTO api_logs
            (timestamp, client_ip, method, url, path, query_params, request_body, 
             user_agent, accept_language, accept_encoding, referer, x_forwarded_for, 
             status_code, process_time, response_size)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            zSuccessfully inserted z log entrieszError inserting log batch: )r   appendr#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   executemanyrA   rB   debuglenrD   error)rJ   rF   valuesentryrH   s        r<   _insert_log_batchrS   j   s      &8#%%%%%%%%   	 	EMM	
"" %%%!"#    &  	
 	
 		
 		
 		
 		
 		
 		
 		
 kkmmLc+.>.>LLLMMMMM 8 8 861667777777778s   C+C5 5
D'?D""D'c                  J  K   t                               d           g } t          j                    }	 	 	 t          j        t
                                          t                     d{V }|                     |           n# t          j	        $ r Y nw xY wt          j                    }t          |           t          k    p(| o||z
  t          k    pt                                          }|r| rt          |            d{V  g } |}t                                          rLt
                                          r3| rt          |            d{V  t                               d           dS n4# t           $ r'}t                               d|            Y d}~nd}~ww xY wr)zMBackground worker that processes log queue and writes to database in batches.zStarted background log workerTtimeoutNz#Background log worker shutting downz Error in background log worker: )rB   rC   timeasynciowait_forr   getr   rL   TimeoutErrorrO   r   r    is_setrS   emptyrD   rP   )batchlast_flush_time	log_entrycurrent_timeshould_flushrH   s         r<   _background_log_workerrc      s     
KK/000EikkOA	A")"2:>>3C3CM_"`"`"```````	Y'''''     9;;LE

n, )O</9=OO)&&((   / /'.........". %%'' J,<,<,>,>  3+E222222222ABBB 	A 	A 	ALL?A??@@@@@@@@	A=As7   AB E/ BE/ BCE/ /
F 9FF c                    K   	 t                       d{V } t          j                    t          t                    z
  }|                     d|f           d{V  | j        r| j        j        nd}|                                  d{V  |dk    r(t          
                    d| dt           d           dS dS # t          $ r(}t                              d|            Y d}~dS d}~ww xY w)	z,Delete API logs older than retention period.N)daysz)DELETE FROM api_logs WHERE timestamp < %sr   zCleaned up z old log entries (older than z days)zError cleaning up old logs: )r   r   nowr   r   r?   _last_cursorrowcountrA   rB   rC   rD   rP   )rF   cutoff_datedeleted_countrH   s       r<   _cleanup_old_logsrk      sF     9#%%%%%%%%lnny6H'I'I'IIll7N
 
 	
 	
 	
 	
 	
 	
 	
 7;6GN)22Qkkmm1KKlmllRdlllmmmmm  9 9 97A778888888889s   B5B= =
C/C**C/c                    K   t                               d           	 	 t                       d{V  t          j        d           d{V  t
                                          rt                               d           dS nN# t          $ rA} t                               d|             t          j        d           d{V  Y d} ~ nd} ~ ww xY w)z3Schedule periodic cleanup of old logs (runs daily).zStarted log cleanup schedulerTNiQ z#Log cleanup scheduler shutting downz Error in log cleanup scheduler: i  )	rB   rC   rk   rX   sleepr    r\   rD   rP   )rH   s    r<   _schedule_log_cleanuprn      s     
KK/000&	&#%%%%%%%%% -&&&&&&&&&%%'' ABBB  	& 	& 	&LL?A??@@@-%%%%%%%%%%%%%%	&&s   A!B 
C7C		Cr'   returnc                       t           v rdS t           fdt          D                       rdS d v s                     d          rdS dS )z*Check if request path should skip logging.Tc              3   B   K   | ]}                     |          V  d S )N)endswith).0extr'   s     r<   	<genexpr>z'_should_skip_logging.<locals>.<genexpr>   s/      
;
;#4==
;
;
;
;
;
;r;   z/js/z/styles.cssF)
SKIP_PATHSanySTATIC_EXTENSIONSrr   )r'   s   `r<   _should_skip_loggingry      sg     zt 
;
;
;
;):
;
;
;;; t ~~}55~t5r;   requestc                   K   | j         j        }t          |          }t          r|r ||            d{V S t          dk     r2ddl}|                                t          k    r ||            d{V S t          j                    }| j        r| j        j	        nd}| j
        }t          | j                   }t          | j                  }	| j                            dd          }
| j                            dd          }| j                            dd          }| j                            dd          }| j                            d	d          }d}|d
v r	 |                                  d{V }|r\	 t#          j        |                    d                    }n3# t"          j        t*          f$ r |                    dd          }Y nw xY wn# t,          $ r d}Y nw xY w ||            d{V }t          j                    |z
  }t/          |dd          }d}	 t/          |dd          }|t1          |          }n# t,          $ r d}Y nw xY wt3          t5          j                    |||||	rt#          j        |	          nd|rt#          j        |          nd|
|||||||          }	 t:          t:                              |           n4# t,          $ r'}t>                               d|            Y d}~nd}~ww xY w|S )a|  
    Logs HTTP requests to MySQL table `api_logs` asynchronously.
    
    Features:
    - Asynchronous logging via background queue (no blocking on DB writes)
    - Batch insertion for better performance
    - Skips static files (JS, CSS, images, fonts)
    - Skips health check endpoint
    - Supports sampling for high-traffic scenarios
    - Automatic cleanup of old logs
    Ng      ?r   unknownz
user-agentzaccept-languagezaccept-encodingr-   zx-forwarded-for)POSTPUTPATCHzutf-8replace)errorsr/   bodyz{})r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   zError enqueueing log entry: )!r&   r'   ry   ENABLE_LOGGINGr   randomrW   perf_counterclienthostr%   r7   dictr(   headersrZ   r   jsonloadsdecodeJSONDecodeErrorUnicodeDecodeErrorrD   getattrrO   r"   r   rf   dumpsr   
put_nowaitrB   rP   )rz   	call_nextr'   should_skipr   
start_timer$   r%   r&   r(   r*   r+   r,   r-   r.   r)   r   responser0   r/   r1   r`   rH   s                          r<   mysql_logging_middlewarer      s      ;D 't,,K  ([ (Yw''''''''' S  ==??000"7+++++++++"$$J'.~D##9I^F
gk

C,--L $$\9==Jo))*;YGGOo))*;YGGOo!!)Y77Go))*;YGGO L)))		  ''''''D JJ#':dkk'.B.B#C#CLL,.@A J J J#';;wy;#I#ILLLJ 	  	  	 LLL	  Yw''''''''H$&&3L(M488KMx..IIM    ,..1=GTZ---41=GTZ---4'''!#  I&9!!!),,, 9 9 97A77888888889 Os`   G 7'F G -GG GG G"!G" "I II1!K 
LK??Lc                    K   t           t                              d           dS t                       d{V  t          st                              d           dS t          j                    a t          j                    at          j	        t                                at          j	        t                                 t                              d           dS )zFInitialize the async logging system. Call this on application startup.NzLogging system already startedz6Database not accessible, logging system will not startzAsync logging system started)r   rB   rE   rI   r>   rX   QueueEventr    create_taskrc   r   rn   rC   r:   r;   r<   start_logging_systemr   Z  s       7888 (
)
)))))))) ! OPPP JmooO *+A+C+CDD -//000
KK./////r;   c                    K   t           dS t                              d           t                                            t          k	 t          j        t          d           d{V  nH# t
          j        $ r6 t                              d           t          	                                 Y nw xY wt                              d           dS )zPGracefully shutdown the async logging system. Call this on application shutdown.Nz%Shutting down async logging system...g      $@rU   z4Log worker did not finish within timeout, cancellingzAsync logging system stopped)
r    rB   rC   setr   rX   rY   r[   rE   cancelr:   r;   r<   stop_logging_systemr   w  s       
KK7888  #	&"#3TBBBBBBBBBBB# 	& 	& 	&NNQRRR##%%%%%	& KK./////s   !A) )AB.-B.)2fastapir   rW   r   osrX   dataclassesr   r   r   typingr   loggingutils.dbr   	getLoggerr2   rB   r>   getenvlowerr   r9   r   r8   r   r   r   rx   rv   r   r   r6   r   Taskr    r   r"   rI   listrS   rc   rk   rn   r7   boolry   r   r   r   r:   r;   r<   <module>r      s            				  ! ! ! ! ! ! ( ( ( ( ( ( ( (        # # # # # #		8	$	$  /88>>@@FJeIBI&;UCCDD S#7>>?? YRY/6677U929%95AABB  A  A  A  (
 '+
HW]# * * *+/ (7<( / / /+/'-( / / /        &/ / /d+8h +8 +8 +8 +8\%A %A %AR9 9 9&& & &(s t    "^G ^ ^ ^ ^B0 0 0:0 0 0 0 0r;   