o
    iR                     @   s  U d Z ddlZ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
 ddlmZ edi dZee	eef  ed< d4d	e
e d
dfddZd
e	eef fddZd5ddZG dd dejZded
ejfddZejdfdejdeded	e
e d
df
ddZded	ed
e	eef fddZedZd	ededed ed!ed
dfd"d#Zd	ed$ed%ed
dfd&d'Z	(d6d	ed)ed*ed+ed,ed-ed
dfd.d/Z d	ed)ed0ed1ed
df
d2d3Z!dS )7a  
Structured logging for Veena3 TTS service.

Features:
- JSON-formatted logs for structured queries
- Request ID tracking via context
- Lifecycle event helpers (request_received, first_audio_emitted, etc.)
- NO PII in logs (text content stored in Supabase, not logs)

Usage:
    from veena3modal.shared.logging import get_logger, log_event, set_request_context
    
    logger = get_logger(__name__)
    set_request_context(request_id="req-123")
    log_event(logger, "request_received", text_length=100, speaker="lipakshi")
    N)datetimetimezone)AnyDictOptional)
ContextVarrequest_contextdefault_request_context
request_idreturnc                 K   s   d| i|}t | dS )z
    Set request context for current async task.
    
    Args:
        request_id: Unique request identifier
        **kwargs: Additional context fields (user_id, etc.)
    r   Nr   set)r   kwargsctx r   5/home/ubuntu/veenaModal/veena3modal/shared/logging.pyset_request_context   s   r   c                   C   s   t  S )zGet current request context.)r   getr   r   r   r   get_request_context*   s   r   c                   C   s   t i  dS )z.Clear request context after request completes.Nr   r   r   r   r   clear_request_context/   s   r   c                   @   s,   e Zd ZdZh dZdejdefddZdS )JSONFormattera*  
    JSON log formatter for structured logging.
    
    Output format:
    {
        "timestamp": "2024-01-01T12:00:00.000Z",
        "level": "INFO",
        "logger": "veena3modal.api",
        "message": "Request received",
        "request_id": "req-123",
        ...extra fields...
    }
    >   msgargsnamemsecslinenomodulethreadasctimecreatedlevelnomessageprocessexc_infoexc_textfilenamefuncNamepathnametaskName	levelname
stack_info
threadNameprocessNamerelativeCreatedrecordr   c              
   C   s   t tj |j|j| d}t }|	dr|d |d< |j
 D ]+\}}|| jvrO|dsOzt| |||< W q$ ttfyN   t|||< Y q$w q$|jr^dtj|j |d< tj|tdS )zFormat log record as JSON.)	timestamplevelloggerr#   r   _ 	exceptionr	   )r   nowr   utc	isoformatr+   r   
getMessager   r   __dict__itemsRESERVED_ATTRS
startswithjsondumps	TypeError
ValueErrorstrr%   join	tracebackformat_exception)selfr0   	log_entryr   keyvaluer   r   r   formatL   s(   

zJSONFormatter.formatN)	__name__
__module____qualname____doc__r=   logging	LogRecordrC   rK   r   r   r   r   r   4   s    r   r   c                 C   sB   t | }|jst tj}|t  || |	t j
 |S )z
    Get a logger configured for structured JSON output.
    
    Args:
        name: Logger name (typically __name__)
    
    Returns:
        Configured logger instance
    )rP   	getLoggerhandlersStreamHandlersysstdoutsetFormatterr   
addHandlersetLevelINFO)r   r3   handlerr   r   r   
get_loggerl   s   


r\   r3   
event_typer2   c                 K   s,   d|i|}|r||d< | j |||d dS )a'  
    Log a structured event.
    
    Args:
        logger: Logger instance
        event_type: Event name (e.g., "request_received", "first_audio_emitted")
        level: Log level (default: INFO)
        request_id: Override request_id from context
        **kwargs: Event-specific fields
    eventr   )extraN)log)r3   r]   r2   r   r   r_   r   r   r   	log_event   s   ra   c                 K   s   | |t tj d|S )a'  
    Create a lifecycle event dictionary.
    
    Lifecycle events:
    - request_received: TTS request started
    - auth_validated: API key validated
    - generation_started: Model inference began
    - first_audio_emitted: First audio chunk sent (TTFB)
    - request_completed: Request finished successfully
    - request_failed: Request failed with error
    
    Args:
        event_type: Event name
        request_id: Request identifier
        **kwargs: Event-specific fields
    
    Returns:
        Event dictionary ready for logging
    )r^   r   r1   )r   r7   r   r8   r9   )r]   r   r   r   r   r   create_lifecycle_event   s   rb   zveena3modal.ttstext_lengthspeakerstreamrK   c                 K   s"   t tdf| ||||d| dS )z%Log request_received lifecycle event.request_received)r   rc   rd   re   rK   Nra   
tts_logger)r   rc   rd   re   rK   r   r   r   r   log_request_received   s   	
ri   ttfb_mschunk_size_bytesc                 K   s   t tdf| ||d| dS )z6Log first_audio_emitted lifecycle event (TTFB marker).first_audio_emitted)r   rj   rk   Nrg   )r   rj   rk   r   r   r   r   log_first_audio_emitted   s   
rm      status_codetotal_duration_msaudio_duration_secondsrtfchunks_sentc              	   K   s$   t tdf| |||||d| dS )z&Log request_completed lifecycle event.request_completed)r   ro   rp   rq   rr   rs   Nrg   )r   ro   rp   rq   rr   rs   r   r   r   r   log_request_completed   s   
	
ru   
error_codeerror_messagec                 K   s$   t tdftj| |||d| dS )z#Log request_failed lifecycle event.request_failed)r2   r   ro   rv   rw   N)ra   rh   rP   ERROR)r   ro   rv   rw   r   r   r   r   log_request_failed   s   
rz   )N)r   N)rn   )"rO   rP   r?   rU   rE   r   r   typingr   r   r   contextvarsr   r   rC   __annotations__r   r   r   	Formatterr   Loggerr\   rZ   intra   rb   rh   boolri   rm   floatru   rz   r   r   r   r   <module>   s     
8


!


