o
    5)i1                     @   s   d dl Z d dlZd dlZd dlmZmZ d dlmZmZmZm	Z	 d dl
mZmZ d dlZd dlmZ d dlmZ d dlmZmZmZmZ dd	 Zd d
dZdd Zdd Zd ddZdd ZedefddZd!ddZdd Z d"ddZ!dd Z"dS )#    N)RotatingFileHandlerTimedRotatingFileHandler)datetimedatetimezonetime)requestgwraps)contextmanager)DictOptionalAnyUnionc           	      C   s&  | j d}tj|stj|dd t }|t	t| j dd |j
dd D ]}|| q+tj|dt d d	}t|d
d| j ddddd}tjddd}|| || td}|tj || | j ddrt }|| || | jd|  dS )z=Setup application logging with rotation and proper formattingLOG_DIRT)exist_ok	LOG_LEVELINFONz
flask-api-z%Y-%m-%dz.logmidnight   LOG_BACKUP_COUNT   zutf-8F)whenintervalbackupCountencodingutcz1[%(asctime)s] %(name)s.%(levelname)s: %(message)sz%Y-%m-%d %H:%M:%S)fmtdatefmtpypandocDEBUGz)Flask API logging initialized. Log file: )configgetospathexistsmakedirslogging	getLoggersetLevelgetattrhandlersremoveHandlerjoinr   nowstrftimer   	FormattersetFormatter
addHandlerr!   StreamHandlerloggerinfo)	applog_dirroot_loggerhandlerlog_filefile_handler	formatterpypandoc_loggerconsole_handler r@   //var/www/html/oms-prod-mcp/app/utils/helpers.pysetup_logger   s<    






rB   c                 C   s   t | pdS )z(Get a logger instance with optional namez	flask-api)r(   r)   )namer@   r@   rA   
get_logger>   s   rD   c                  C   s   t d} tjdtj}tjtj|tjddtjd}tj	r6tj
ddr6t
 }dd	 | D }||d
< | dt|  dS )z Log incoming request informationr   HTTP_X_FORWARDED_FOR
User-AgentUnknown)methodr%   	client_ip
user_agentcontent_typeT)silentc                 S   s"   i | ]\}}|  d vr||qS ))passwordtokensecret)lower).0kvr@   r@   rA   
<dictcomp>S   s   " z$log_request_info.<locals>.<dictcomp>request_bodyzIncoming request: N)rD   r   environr#   remote_addrrH   r%   headersrK   is_jsonget_jsonitemsr6   jsondumps)r5   rI   log_databody	safe_bodyr@   r@   rA   log_request_infoB   s   ra   c                 C   s4   t d}| j| j| jd}|dt|  | S )zLog response informationresponse)status_codecontent_lengthrK   zResponse sent: )rD   rc   rd   rK   r6   r\   r]   )rb   r5   r^   r@   r@   rA   log_response_infoX   s   re   c              	   C   sR   t d}| du r
d} |jdt  | ttddttddttddd	d
 dS )z!Log exception with full tracebackerrorNTzException occurred: r%   N/ArH   rW   )request_pathrequest_methodrI   )exc_infoextra)rD   rf   	traceback
format_excr+   r   )rj   r5   r@   r@   rA   log_exceptione   s   



rn   c                    s   t   fdd}|S )z%Decorator to log function performancec                     s   t d}t }z" | i |}t }||  }|d j d|dd |W S  tyS } zt }||  }|d j d|ddt|   d }~ww )Nperformancez	Function z executed in .4f secondsz failed after z
 seconds: )	rD   r   r/   total_secondsr6   __name__	Exceptionrf   str)argskwargsr5   
start_timeresultend_timedurationefuncr@   rA   wrapperx   s   $z performance_log.<locals>.wrapperr
   )r~   r   r@   r}   rA   performance_logv   s   r   rC   c                 c   s~    t d}t }zdV  W t }||  }|d|  d|dd dS t }||  }|d|  d|dd w )z2Context manager to log performance of a code blockro   NzBlock 'z' executed in rp   rq   )rD   r   r/   rr   r6   )rC   r5   rx   rz   r{   r@   r@   rA   measure_performance   s   r   c                 C   sf   t d}t  | |pttddttddtrtjddnd|p#i d}|	d	t
|  d
S )zLog audit events for complianceaudituser_id	anonymousrW   rg   rF   rG   )	timestampactionr   rI   rJ   detailszAUDIT: N)rD   r   utcnow	isoformatr+   r	   r   rX   r#   r6   r\   r]   )r   r   r   r5   
audit_datar@   r@   rA   	audit_log   s   

	r   c                 C   s6   dd l }	 z|j|  W S  ty   td|  dw )Nr   zSet the z environment variable)r$   rV   KeyErrorrt   )var_namer$   r@   r@   rA   get_env_variable   s   r      c                 C   s   |dk rdnd| |dS )z.Format the response to be returned by the API.i  successrf   )statusdatarc   r@   )r   rc   r@   r@   rA   format_response   s   r   c                    s.    fdd|D }|rt dd| dS )z7Validate incoming request data against required fields.c                    s   g | ]}| vr|qS r@   r@   )rQ   fieldrequest_datar@   rA   
<listcomp>   s    z)validate_request_data.<locals>.<listcomp>zMissing fields: z, N)
ValueErrorr.   )r   required_fieldsmissing_fieldsr@   r   rA   validate_request_data   s   r   )N)NN)r   )#r$   r(   r\   logging.handlersr   r   r   r   r   r   flaskr   r	   rl   	functoolsr   
contextlibr   typingr   r   r   r   rB   rD   ra   re   rn   r   ru   r   r   r   r   r   r@   r@   r@   rA   <module>   s,    
2


