o
    38h                     @   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Zd dlmZm	Z	m
Z
 G dd dZe ZG dd dejZdeded	ed
efddZdS )    N)DictAnyOptionalc                   @   s   e Zd ZdZddedefddZdd Zd	d
 Zdd Zde	ee
f fddZ	ddedededededee	ee
f  fddZdS )LogForwarderz
    Forwards logs to the Node.js API for real-time frontend display
    Uses a background thread to avoid blocking the main thread
    Napi_urlapi_keyc                 C   sT   |pt jdd| _|pt jd| _t | _d| _d| _	t
t| _|   dS )z
        Initialize the log forwarder
        
        Args:
            api_url: URL of the Node.js API logs endpoint
            api_key: Internal API key for authentication
        NODEJS_API_URLz"http://localhost:5000/internal-apiINTERNAL_API_KEYFN)osenvirongetr   r   queueQueue	log_queue
is_runningworker_threadlogging	getLogger__name__loggerstart)selfr   r    r   8/var/www/html/minaions-tender/ai-engine/log_forwarder.py__init__   s   
zLogForwarder.__init__c                 C   s<   | j sd| _ tj| jdd| _| j  | jd dS dS )z'Start the worker thread to process logsT)targetdaemonzLogForwarder startedN)r   	threadingThread_process_logsr   r   r   infor   r   r   r   r   "   s   
zLogForwarder.startc                 C   s.   d| _ | jr| jjdd | jd dS dS )zStop the worker threadF   timeoutzLogForwarder stoppedN)r   r   joinr   r    r!   r   r   r   stop*   s
   zLogForwarder.stopc              
   C   s   | j rEz!z	| jjdd}W n tjy   Y W q w | | | j  W n ty? } z| j	d|  W Y d}~nd}~ww | j sdS dS )z4Process logs from the queue and send them to the API   r#   zError processing log: N)
r   r   r   r   Empty	_send_log	task_done	Exceptionr   error)r   	log_entryer   r   r   r   1   s   
zLogForwarder._process_logsr-   c              
   C   s   z*t j| j d|| jdddd}|jdkr(| jd|j d|j  W d
S W d
S  tyF } z| jd	|  W Y d
}~d
S d
}~ww )za
        Send log to API
        
        Args:
            log_entry: Log entry to send
        z/logs/entryzapplication/json)zx-internal-api-keyzContent-Typer"   )jsonheadersr$      zFailed to send log to API:  zError sending log to API: N)	requestspostr   r   status_coder   warningtextr+   )r   r-   responser.   r   r   r   r)   C   s    


" zLogForwarder._send_logr    	tenant_id
process_idprocess_typemessageleveldetailsc                 C   s4   ||||||pi t dt  d}| j| dS )am  
        Add log to queue
        
        Args:
            tenant_id: Tenant ID
            process_id: Process ID (tender_id, analysis_id, etc.)
            process_type: Process type (discovery, analysis, bid_generation)
            message: Log message
            level: Log level (debug, info, warning, error)
            details: Additional details
        z%Y-%m-%dT%H:%M:%S.%fZ)r9   r:   r;   r<   r=   r>   	timestampN)timestrftimegmtimer   put)r   r9   r:   r;   r<   r=   r>   r-   r   r   r   logZ   s   
zLogForwarder.log)NN)r    N)r   
__module____qualname____doc__strr   r   r&   r   r   r   r)   r   rD   r   r   r   r   r   
   s    r   c                       s4   e Zd Zd	dededef fddZdd Z  ZS )
ApiLogHandlerNr9   r:   r;   c                    s    t    || _|| _|| _d S )N)superr   r9   r:   r;   )r   r9   r:   r;   	__class__r   r   r   x   s   

zApiLogHandler.__init__c                 C   s   | j r	| jr	| jsd S |j }| |}|j|j|jd}|j	r2t
|j	d |d< | |j	|d< tj| j | j| j|||d d S )N)logger_namepathliner'   	exception	traceback)r9   r:   r;   r<   r=   r>   )r9   r:   r;   	levelnamelowerformatnamepathnamelinenoexc_inforH   formatExceptionlog_forwarderrD   )r   recordr=   r<   r>   r   r   r   emit~   s&   


zApiLogHandler.emit)NNN)r   rE   rF   rH   r   r\   __classcell__r   r   rK   r   rI   w   s    rI   rM   r9   r:   r;   c                 C   sD   t | }t|||}|t j t d}|| || |S )z
    Set up API logging for a specific logger
    
    Args:
        logger_name: Logger name
        tenant_id: Tenant ID
        process_id: Process ID
        process_type: Process type
    
    Returns:
        logger: Configured logger
    z%(message)s)r   r   rI   setLevelINFO	FormattersetFormatter
addHandler)rM   r9   r:   r;   r   handler	formatterr   r   r   setup_api_logging   s   



re   )r
   r   r3   r/   r   r   r@   typingr   r   r   r   rZ   HandlerrI   rH   re   r   r   r   r   <module>   s    j(