o
    i?Q                     @  s  d Z ddlm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
 ddlmZ ddlmZ ddlmZmZmZmZ dd	lmZmZ dd
lmZmZ ddlmZmZ ddlmZmZ ddl m!Z! ddl"m#Z#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8 ed Z9e1d Z:e1d Z;e1d Z<e=e>e?e?f  Z@e
G dd dZAG dd deZBG dd deBZCG dd  d eBZDd)d%d&ZEe
G d'd( d(eZFdS )*zConsole exporter for OpenTelemetry.

Inspired by https://opentelemetry-python.readthedocs.io/en/latest/_modules/opentelemetry/sdk/trace/export.html#ConsoleSpanExporter
    )annotationsN)MappingSequence)	dataclass)datetimeindent)AnyLiteralTextIOcast)LogData	LogRecord)LogExporterLogExportResult)EventReadableSpan)SpanExporterSpanExportResult)Columns)ConsoleGroup)Syntax)Text   )ATTRIBUTES_JSON_SCHEMA_KEYATTRIBUTES_LOG_LEVEL_NUM_KEYATTRIBUTES_MESSAGE_KEY'ATTRIBUTES_PENDING_SPAN_REAL_PARENT_KEYATTRIBUTES_SPAN_TYPE_KEYATTRIBUTES_TAGS_KEYDISABLE_CONSOLE_KEYLEVEL_NUMBERSNUMBER_TO_LEVELONE_SECOND_IN_NANOSECONDS	LevelName)json_args_value_formatter)truncate_string)autoalwaysneverinfowarnerrorc                   @  sj   e Zd ZU ded< ded< ded< ded< d	ed
< d	ed< ded< ded< edddZedddZdS )RecordMapping[str, object]
attributesint	timestampstrmessagezSequence[Event]events
int | Nonespan_idparent_span_idkindlevelspanr   returnc                 C  sZ   |j pi }| ||jpd|tp|j|j|jo|jj|jo |jj|t	d|t
tdS )Nr   r;   r0   r2   r4   r5   r7   r8   r9   r:   )r0   
start_timegetr   namer5   contextr7   parentr   r   _INFO_LEVEL)clsr;   r0    rE   i/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/logfire/_internal/exporters/console.py	from_span?   s   


zRecord.from_spanlogr   c              
   C  s   |j pi }|t}|sLg }t|dd p|d }r"|t| |j }r3|tt|dd ndd | D }|tt|dd d	|}| ||j
pU|jpUd|g d |jd	|jrd|jjd
S td
S )N
event_name
event.named   )
max_lengthc                 S  s   i | ]\}}|d kr||qS )rJ   rE   ).0kvrE   rE   rF   
<dictcomp>Z   s    z#Record.from_log.<locals>.<dictcomp>: r   rH   r=   )r0   r?   r   getattrappendr3   bodyr'   itemsjoinr2   observed_timestampr7   severity_numbervaluerC   )rD   rH   r0   r4   partsrI   rT   other_attributesrE   rE   rF   from_logM   s.   



zRecord.from_logN)r;   r   r<   r.   )rH   r   r<   r.   )__name__
__module____qualname____annotations__classmethodrG   r\   rE   rE   rE   rF   r.   4   s   
 r.   c                   @  s   e Zd ZdZ						d:d;ddZd<ddZd=ddZd>d?d!d"Zd@d$d%ZdAd)d*Z	dBd+d,Z
dCd/d0ZdCd1d2ZdDd5d6Zd>dEd8d9ZdS )FSimpleConsoleSpanExporterzThe ConsoleSpanExporter prints spans to the console.

    This simple version does not indent spans based on their parent(s), instead spans are printed as a
    flat list.
    Nr(   TFr+   outputTextIO | NonecolorsConsoleColorsValuesinclude_timestampboolinclude_tagsverbosemin_log_levelr%   r<   Nonec                 C  s   |pt j| _|dkrd }n|dk}ttjdrdnd| j|dddd| _| jjs,d | _|| _	|| _
|r6dnd	| _|| _t| | _d S )
Nr(   r)   PYTEST_VERSIONstandardFT)color_systemfileforce_terminal	highlightmarkup	soft_wrap   r   )sysstdout_outputr   osenvironr?   _consoleis_terminal_include_timestamp_include_tags_timestamp_indent_verboser"   _min_log_level_num)selfrc   re   rg   ri   rj   rk   rq   rE   rE   rF   __init__p   s&   	z"SimpleConsoleSpanExporter.__init__spansSequence[ReadableSpan]r   c                 C  s    |D ]
}|  t| qtjS )z Export the spans to the console.)export_recordr.   rG   r   SUCCESS)r   r   r;   rE   rE   rF   export   s   z SimpleConsoleSpanExporter.exportr;   r.   c                 C  s   |  | dS )zPrint a summary of the span, this method can be overridden to customize how spans are displayed.

        In this simple case we just print the span if its type is not "span" - e.g. the message at the end of a span.
        N)_print_spanr   r;   rE   rE   rF   r      s   z'SimpleConsoleSpanExporter.export_recordr   r   r1   c                 C  s   |  ||\}}|jdks|jtrdS |j| jk rdS | j|d  d }| ||}|r5|dg| 7 }| j	rB| j	
tj|  nt
ddd |D | jd	 | || td
d |jp_g D d}| || dS )zMBuild up a summary of the span, including formatting for rich, then print it.r;   Nr    )
 r   c                 s  s    | ]\}}|V  qd S NrE   )rM   text_stylerE   rE   rF   	<genexpr>   s    z8SimpleConsoleSpanExporter._print_span.<locals>.<genexpr>rp   c                 s  s    | ]
}|j d kr|V  qdS )	exceptionN)r@   )rM   eventrE   rE   rF   r      s    )_span_text_partsr9   r0   r?   r!   r:   r   r   _details_partsr{   printr   assemblerV   rx   _print_argumentsnextr5   _print_exc_info)r   r;   r   _msgrZ   
indent_strdetails_parts	exc_eventrE   rE   rF   r      s   z%SimpleConsoleSpanExporter._print_spantuple[str, TextParts]c           
      C  s   g }| j rt|jt }|ddd }||dfdg7 }|r(||d dfg7 }|j}|j}|tkr:||dfg7 }n|tkrF||d	fg7 }n||dfg7 }| j	rl|j
t }rld
td|}	|dd|	 ddfg7 }||fS )a<  Return the formatted message or span name and parts containing basic span information.

        The following information is included:
        * timestamp
        * message (maybe indented)
        * tags (if `self._include_tags` is True)

        The log level may be indicated by the color of the message.
        z%H:%M:%S.%fNgreen)r   r   z  r   redyellow,z	list[str][]cyan)r}   r   fromtimestampr2   r$   r4   r:   _ERROR_LEVEL_WARN_LEVELr~   r0   r?   r    rV   r   )
r   r;   r   rZ   tsts_strmsgr:   tagstags_strrE   rE   rF   r      s&   
z*SimpleConsoleSpanExporter._span_text_partsr   r3   	TextPartsc           	      C  s   | j r|jsg S |jd}|dv rdnt|}|r+|jd}|dvr+|d| 7 }|jt}t|}|s:|rZ|dfdg}|rL|d| d	f |rX|d| df |S g S )
zReturn parts containing details for the span if `self._verbose` is True.

        The following details are returned:
        * filename and line number
        * the log level name
        zcode.filepath)NnullNzcode.lineno:r   )u   │bluer   r   )r   r0   r?   r3   r   r#   rS   )	r   r;   r   file_location_rawfile_locationlinenolog_level_num	log_levelrZ   rE   rE   rF   r      s$   
z(SimpleConsoleSpanExporter._details_partsc              	   C  s   | j r|jsdS i }tdt|jtd}|di  D ]/\}}|j|}|rDt|t	rDzt|}W n tj
yC   d}Y nw t||d}|||< q|sSdS | jr^| || dS | || dS )zQPretty-print formatted logfire arguments for the span if `self._verbose` is True.Ndict[str, Any]z{}
properties)schema)r   r0   r   jsonloadsr?   r   rU   
isinstancer3   JSONDecodeErrorr&   r{   _print_arguments_rich_print_arguments_plain)r   r;   r   	argumentsjson_schemakeyr   rY   rE   rE   rF   r      s&   
z*SimpleConsoleSpanExporter._print_argumentsr   r   c           	      C  s   | j dusJ g }| D ]<\}}t| ddd}t|ddd}td|d	d
  dd dd}|tg |gt| |||R dd q| j t	|  dS )zSPrint logfire arguments in color using rich, particularly with syntax highlighting.N=r   )stylepythondefaultbackground_coloru   │ 
r      )r   r   )padding)
r{   rU   r   r   countrS   r   rh   r   r   )	r   r   r   chunksrN   
value_coder   rY   barrierrE   rE   rF   r     s*   "z/SimpleConsoleSpanExporter._print_arguments_richc           	      C  s   g }|  D ]5\}}| }|| d| d|d  g7 }| ddt|  d}|dd D ]}|| | g7 }q/qtd|| jd dS )	zJPrint logfire arguments without color using the built-in `print` function.   │ r   r   r   r   Nr   r   )rU   
splitlineslenr   rV   rx   )	r   r   r   outrN   r   value_linesprefixlinerE   rE   rF   r   /  s   z0SimpleConsoleSpanExporter._print_arguments_plainr   Event | Nonec           	      C  s   |du s|j s	dS tt|j d}tt|j d}tt|j d}| jrYt|d ddd}t| d	dd
d}t|}t||d }t|ddd}| jt	|||| dS | d| d	| g}|t||d g7 }td
|| jd dS )z=Print exception information if an exception event is present.Nzexception.typezexception.messagezexception.stacktracer   r   r   )r   endrQ   zbold red)r   r   r   r   r   r   r   )r0   r   r3   r?   r{   r   indent_textr   r   r   rV   rx   )	r   r   r   exc_typeexc_msgexc_tbr   indented_coder   rE   rE   rF   r   :  s   z)SimpleConsoleSpanExporter._print_exc_infotimeout_millisc                 C  s   dS )z6Force flush all spans, does nothing for this exporter.TrE   )r   r   rE   rE   rF   force_flushO  s   z%SimpleConsoleSpanExporter.force_flushNr(   TTFr+   rc   rd   re   rf   rg   rh   ri   rh   rj   rh   rk   r%   r<   rl   )r   r   r<   r   r;   r.   r<   rl   )r   )r;   r.   r   r1   r;   r.   r   r1   r<   r   )r;   r.   r   r3   r<   r   )r;   r.   r   r3   )r   r   r   r3   r<   rl   )r   r   r   r3   r<   rl   )r   r1   r<   rh   )r]   r^   r_   __doc__r   r   r   r   r   r   r   r   r   r   r   rE   rE   rE   rF   rb   i   s&    
!


&



rb   c                      s:   e Zd ZdZ						dd fddZdddZ  ZS )IndentedConsoleSpanExportera  The ConsoleSpanExporter exports spans to the console, indented.

    Spans are intended based simply on how many parents they have. This will work well when spans don't overlap,
    but will be hard to understand when multiple spans are in progress at the same time.
    Nr(   TFr+   rc   rd   re   rf   rg   rh   ri   rj   rk   r%   r<   rl   c                   s    t  |||||| i | _d S r   )superr   _indent_levelr   rc   re   rg   ri   rj   rk   	__class__rE   rF   r   [  s   	
z$IndentedConsoleSpanExporter.__init__r;   r.   c                 C  s   |j dkr|jdur| j|jd dS |j}|j dkr8t|j}|r*| j|dnd}|dur7|d | j|< n|rA| j|dnd}| || dS )zXGet the span indent based on `self._indent_level`, then print the span with that indent.r;   Npending_spanr   r   )	r9   r7   r   popr8   _pending_span_parentr0   r?   r   )r   r;   block_span_id	parent_idr   rE   rE   rF   r   h  s   



z)IndentedConsoleSpanExporter.export_recordr   r   r   )r]   r^   r_   r   r   r   __classcell__rE   rE   r   rF   r   T  s    r   c                      sR   e Zd ZdZ						d#d$ fddZd%ddZd& fddZd'd!d"Z  ZS )(ShowParentsConsoleSpanExportera  The ConsoleSpanExporter exports spans to the console, indented with parents displayed where necessary.

    Spans are intended based on how many parents they have, where multiple concurrent spans overlap and therefore
    the previously displayed span is not the parent or sibling of a span, parents are printed (with "dim" color)
    so it's easy (or as easy as possible in a terminal) to understand how nested spans are related.
    Nr(   TFr+   rc   rd   re   rf   rg   rh   ri   rj   rk   r%   r<   rl   c                   s&   t  |||||| i | _g | _d S r   )r   r   _span_history_span_stackr   r   rE   rF   r     s   	
z'ShowParentsConsoleSpanExporter.__init__r;   r.   c                 C  sV   |j dkr$|jdur"| j|jd | jr"| jd |jkr"| j  dS | | dS )zbPrint any parent spans which aren't in the current stack of displayed spans, then print this span.r;   Nr   )r9   r7   r   r   r   r   r   rE   rE   rF   r     s   


z,ShowParentsConsoleSpanExporter.export_recordr   r1   r   c                   s   g }|j }|jdkr@t|j}|| |7 }t| j}t ||\}}||7 }|dur<|||p1df| j	|< | j
| ||fS || |7 }t j|t| jd\}}||7 }||fS )zjParts for any parent spans which aren't in the current stack of displayed spans, then parts for this span.r   Nr   r   )r8   r9   r   r0   _parent_stack_text_partsr   r   r   r   r   rS   )r   r;   r   rZ   r   r   r   
span_partsr   rE   rF   r     s    


z/ShowParentsConsoleSpanExporter._span_text_partsr   r6   r   c                 C  s   g }d}|rEz
| j | \}}}W n	 ty   Y n,w z| j|}W n ty5   ||||f |}Y nw | jd|d  | _d}n|s|rL| j  g }t|D ]"\}}	}| j|d  }
|d|
  |	 ddfg7 }|rt| j| qR|S )	zParts for "intermediate" parent spans - e.g., spans which are not parents of the currently displayed span.

        Also build up `self._span_stack` to correctly represent the path to the current span.
        TNr   Fr   r   r   dim)	r   KeyErrorr   index
ValueErrorrS   clearreversedr   )r   r   parentsclear_stackr   r   grand_parent_idstack_indexrZ   r   total_indentrE   rE   rF   r     s8   
z7ShowParentsConsoleSpanExporter._parent_stack_text_partsr   r   r   r   )r   r6   r<   r   )	r]   r^   r_   r   r   r   r   r   r   rE   rE   r   rF   r     s    	
r   r0   r/   r<   r6   c                 C  s   |  t }rt|dS dS )aq  Pending span marks the start of a span.

    Since they're nested within another span we haven't seen yet,
    we have to do a trick of getting the 'logfire.pending_parent_id' attribute to get the parent indent.

    Note that returning `0` is equivalent to returning `None` since top level spans get
    `ATTRIBUTES_PENDING_SPAN_REAL_PARENT_KEY` encoded from `0`.
       N)r?   r   r1   )r0   parent_id_strrE   rE   rF   r     s   	
r   c                   @  s(   e Zd ZU ded< dddZd	d
 ZdS )ConsoleLogExporterrb   span_exporterbatchSequence[LogData]r<   r   c                 C  s$   |D ]}| j t|j qtjS r   )r  r   r.   r\   
log_recordr   r   )r   r  log_datarE   rE   rF   r     s   zConsoleLogExporter.exportc                 C  s   | j   d S r   )r  shutdown)r   rE   rE   rF   r    s   zConsoleLogExporter.shutdownN)r  r	  r<   r   )r]   r^   r_   r`   r   r  rE   rE   rE   rF   r    s   
 
r  )r0   r/   r<   r6   )Gr   
__future__r   r   ry   rv   collections.abcr   r   dataclassesr   r   textwrapr   r   typingr	   r
   r   r   opentelemetry.sdk._logsr   r   opentelemetry.sdk._logs.exportr   r   opentelemetry.sdk.tracer   r   opentelemetry.sdk.trace.exportr   r   rich.columnsr   rich.consoler   r   rich.syntaxr   	rich.textr   	constantsr   r   r   r   r   r    r!   r"   r#   r$   r%   json_formatterr&   utilsr'   rf   rC   r   r   listtupler3   r   r.   rb   r   r   r   r  rE   rE   rE   rF   <module>   sF    44 l+
b