o
    PCVj[  ã                   @   sä   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZmZ d dl	m
Z
 e
eƒ ¡ jjZeedd�ƒZdefdd„ZG d	d
„ d
ejƒZG dd„ dejƒZG dd„ dejƒZG dd„ dejƒZddd„Zdedefdd„ZdS )é    N)ÚdatetimeÚtimezoneÚ	timedelta)ÚPathéýÿÿÿ)ÚhoursÚreturnc                   C   s   t  t¡jdd�S )NÚseconds)Útimespec)r   ÚnowÚ_TZÚ	isoformat© r   r   úA/home/develop/edictos_py/central_edictos/helpers/logging_setup.pyÚ_ahora   s   r   c                   @   s   e Zd ZdZdd„ ZdS )Ú_SanitizeFilteruE   Elimina saltos de lÃ­nea de los mensajes para prevenir log injection.c                 C   sP   t |jƒ dd¡ dd¡|_|jr&tdd„ t|jtƒr|jn|jfD ƒƒ|_dS )NÚ
Ú úc                 s   s6   � | ]}t |tƒrt|ƒ d d¡ dd¡n|V  qdS )r   r   r   N)Ú
isinstanceÚstrÚreplace)Ú.0Úar   r   r   Ú	<genexpr>   s
   € $ÿ
ÿz)_SanitizeFilter.filter.<locals>.<genexpr>T)r   Úmsgr   ÚargsÚtupler   )ÚselfÚrecordr   r   r   Úfilter   s   
þz_SanitizeFilter.filterN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    r   r   r   r   r      s    r   c                       s>   e Zd ZdZdedef‡ fdd„Zdejdefdd	„Z‡  Z	S )
Ú_HybridFormatterzJ
    2026-05-29T14:23:01-03:00 [INFO ] [proceso] [run:abc123] mensaje
    ÚprocesoÚrun_idc                    ó   t ƒ  ¡  || _|| _d S ©N©ÚsuperÚ__init__r&   r'   ©r   r&   r'   ©Ú	__class__r   r   r,   "   ó   

z_HybridFormatter.__init__r   r   c              	   C   s`   |j  d¡}| ¡ }tƒ › d|› d| j› d| j› d|› �	}|jr.|d|  |j¡ ¡ d  7 }|S )Né   z [z] [z] [run:z] ú | r   )	Ú	levelnameÚljustÚ
getMessager   r&   r'   Úexc_infoÚformatExceptionÚ
splitlines)r   r   Úlevelr   Úliner   r   r   Úformat'   s   &z_HybridFormatter.format)
r!   r"   r#   r$   r   r,   ÚloggingÚ	LogRecordr;   Ú__classcell__r   r   r.   r   r%      s    r%   c                       s:   e Zd Zdedef‡ fdd„Zdejdefdd„Z‡  ZS )	Ú_JsonFormatterr&   r'   c                    r(   r)   r*   r-   r.   r   r   r,   1   r0   z_JsonFormatter.__init__r   r   c                 C   sN   t ƒ |j| j| j| ¡ t ¡ dœ}|jr |  |j¡ 	¡ d |d< t
j|dd�S )N)Útsr9   r&   r'   r   Úhostr   Ú	exceptionF)Úensure_ascii)r   r3   r&   r'   r5   ÚsocketÚgethostnamer6   r7   r8   ÚjsonÚdumps)r   r   Úentryr   r   r   r;   6   s   úz_JsonFormatter.format)	r!   r"   r#   r   r,   r<   r=   r;   r>   r   r   r.   r   r?   0   s    r?   c                       s0   e Zd ZdZ‡ fdd„Zdejfdd„Z‡  ZS )Ú
_DBHandleruó   
    Handler que inserta cada log en PRS_procesosLogs_eventos via PRS_log_evento.
    Se activa llamando a setup_logging_db(id_log) despuÃ©s de PRS_iniciar.
    Solo loguea WARNING y ERROR para no saturar la tabla con mensajes DEBUG/INFO.
    c                    s   t ƒ jtjd� t|ƒ| _d S )N)r9   )r+   r,   r<   ÚWARNINGÚintÚid_log)r   rL   r.   r   r   r,   J   s   z_DBHandler.__init__r   c                 C   sp   z-ddl m} | ¡ }|jr|d|  |j¡ ¡ d  7 }|d| j|jd |d d… gƒ W d S  ty7   Y d S w )Nr   )Úejecutar_spr2   ÚPRS_log_eventoiô  )	Ú
helpers.dbrM   r5   r6   r7   r8   rL   r3   Ú	Exception)r   r   rM   r   r   r   r   ÚemitN   s   
üÿz_DBHandler.emit)	r!   r"   r#   r$   r,   r<   r=   rQ   r>   r   r   r.   r   rI   D   s    rI   c                 C   sB   | du rdS t  ¡ }|jD ]
}t|tƒr dS q| t| ƒ¡ dS )uP  
    Agrega el handler de DB al logger raÃ­z una vez que se tiene el id_log
    devuelto por PRS_iniciar. Llamar despuÃ©s de capturar id_log.

    Ejemplo:
        run_id = setup_logging("descarga")
        result = ejecutar_sp('PRS_iniciar', [..., run_id])
        id_log = result[0].get('id_log')
        setup_logging_db(id_log)
    N)r<   Ú	getLoggerÚhandlersr   rI   Ú
addHandler)rL   ÚrootÚhr   r   r   Úsetup_logging_db^   s   

ÿrW   Únombre_procesoc                 C   sV  t  d¡}t t¡ d¡}td |  }td d }|jddd� |jddd� t| |ƒ}t	| |ƒ}t
j||› d� dd	�}| |¡ | t
j¡ t
j||› d
� dd	�}| |¡ | t
j¡ t
 tj¡}	|	 |¡ |	 t
j¡ t
 ¡ }
|
j ¡  |
 t
j¡ |
 tƒ ¡ |
 |¡ |
 |¡ |
 |	¡ t
 d| › d|› dt ¡ › dt ¡ › �¡ |S )uá   
    Configura el logger raÃ­z para el proceso indicado.
    Genera un run_id Ãºnico por ejecuciÃ³n.
    Escribe en logs/<proceso>/YYYY-MM-DD.log  y  logs/_auditoria/YYYY-MM-DD.audit.jsonl
    Retorna el run_id generado.
    é   z%Y-%m-%dÚlogsÚ
_auditoriaT)ÚparentsÚexist_okz.logzutf-8)Úencodingz.audit.jsonlzPROCESO_INICIADO | proceso=z run_id=z pid=z host=)ÚsecretsÚ	token_hexr   r   r   ÚstrftimeÚ_PROJECT_ROOTÚmkdirr%   r?   r<   ÚFileHandlerÚsetFormatterÚsetLevelÚDEBUGÚINFOÚStreamHandlerÚsysÚstdoutrR   rS   ÚclearÚ	addFilterr   rT   ÚinfoÚosÚgetpidrD   rE   )rX   r'   ÚhoyÚlogs_dirÚ	audit_dirÚ
hybrid_fmtÚjson_fmtÚfhÚahÚshrU   r   r   r   Úsetup_loggings   s4   









*ry   )r   N)rF   r<   ro   r_   rD   rj   r   r   r   Úpathlibr   Ú__file__ÚresolveÚparentrb   r   r   r   ÚFilterr   Ú	Formatterr%   r?   ÚHandlerrI   rW   ry   r   r   r   r   Ú<module>   s"    
