
    gJ                       d Z ddlmZ ddlZddlZddlZddlmZ ddlmZm	Z	 ddl
mZ ddlmZmZmZ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 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-m.Z.m/Z/m0Z0m1Z1m2Z2 ddl3m4Z4 ed   Z5e/d   Z6e/d   Z7e/d   Z8eee9e9f      Z: G d de      Z; G d de;      Z< G d de;      Z=ddZ>y)zConsole exporter for OpenTelemetry.

Inspired by https://opentelemetry-python.readthedocs.io/en/latest/_modules/opentelemetry/sdk/trace/export.html#ConsoleSpanExporter
    )annotationsN)Sequence)datetimetimezoneindent)AnyListLiteralMappingTextIOTuplecast)EventReadableSpan)SpanExporterSpanExportResult)types)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)autoalwaysneverinfowarnerrorc                      e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 ddZddZddZdddZddZddZ	dd	Z
dd
ZddZddZdddZy)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.
    Nc                Z   |xs t         j                  | _        |dk(  rd }n|dk(  }t        t        j
                  j                  d      rdnd| j                  |ddd      | _        | j                  j                  sd | _        || _	        |rdnd	| _
        || _        t        |   | _        y )
Nr'   r(   PYTEST_VERSIONstandardFT)color_systemfileforce_terminal	highlightmarkup	soft_wrap   r   )sysstdout_outputr   osenvironget_consoleis_terminal_include_timestamp_timestamp_indent_verboser"   _min_log_level_num)selfoutputcolorsinclude_timestampverbosemin_log_levelr4   s          X/var/www/openai/venv/lib/python3.12/site-packages/logfire/_internal/exporters/console.py__init__z"SimpleConsoleSpanExporter.__init__8   s     +V!N#x/N')zz~~6F'GV)
 }}(( DM"3'8a"/">    c                    |D ]S  }|j                   r4|j                   j                  t        t              }|| j                  k  rC| j                  |       U t        j                  S )z Export the spans to the console.)
attributesr>   r   _INFO_LEVELrD   	_log_spanr   SUCCESS)rE   spansspan	log_levels       rK   exportz SimpleConsoleSpanExporter.exportW   sV    D!%!4!45QS^!_	t666NN4    '''rM   c                    |j                   rE|j                   j                  t        d      }|dk(  s|j                   j                  t              ry| j	                  |       y)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.
        rT   N)rO   r>   r   r!   _print_span)rE   rT   	span_types      rK   rQ   z#SimpleConsoleSpanExporter._log_spanb   sM    
 ??++,DfMIF"doo&9&9:M&NrM   c                   | j                  ||      \  }}| j                  |dz  z   dz  }| j                  ||      }|r	|dg|z   z  }| j                  r,| j                  j	                  t        j                  |        n-t	        dj                  d |D              | j                         | j                  ||       t        d |j                  xs g D        d      }| j                  ||       y)	zMBuild up a summary of the span, including formatting for rich, then print it.r    )
 r]   c              3  &   K   | ]	  \  }}|  y wN ).0text_styles      rK   	<genexpr>z8SimpleConsoleSpanExporter._print_span.<locals>.<genexpr>{   s     95<4$5s   r3   c              3  @   K   | ]  }|j                   d k(  s|  yw)	exceptionN)name)ra   events     rK   rd   z8SimpleConsoleSpanExporter._print_span.<locals>.<genexpr>   s     \->E%**P[B[%->s   N)_span_text_partsrB   _details_partsr?   printr   assemblejoinr;   _print_argumentsnextevents_print_exc_info)rE   rT   r   _msgparts
indent_strdetails_parts	exc_events           rK   rX   z%SimpleConsoleSpanExporter._print_spano   s    ++D&9e,,vz9S@
++D*=j\M11E==MMu 56"''9599M 	dJ/\T[[->B->\^bc	Y
3rM   c                   g }| j                   rJt        j                  |j                  xs dt        z  t
        j                        }|ddd }||dfdgz  }|r||dz  d	fgz  }|j                  rS|j                  j                  t              }|xs |j                  }|j                  j                  t              xs d}n|j                  }d}|t        k\  r	||d
fgz  }n|t        k\  r	||dfgz  }n||d	fgz  }|j                  xr |j                  j                  t              x}	r(dj                  t!        d|	            }
|dd|
 ddfgz  }||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

        The log level may be indicated by the color of the message.
        r   )tzz%H:%M:%S.%fNgreenr[   r]   z  r]   redyellow,z	list[str][]cyan)rA   r   fromtimestamp
start_timer$   r   utcrO   r>   r   rh   r   _ERROR_LEVEL_WARN_LEVELr    rn   r   )rE   rT   r   rt   tsts_strformatted_messagemsgleveltagstags_strs              rK   rj   z*SimpleConsoleSpanExporter._span_text_parts   sk    ""'')=AAZ(Z_g_k_klB;'"-Fvw'33Ev}b)**E??,0OO,?,?@V,W#0tyyC,,-IJOaE))CEL sEl^#Ek!sHo&&EsBi[ E??Ot':':;N'OO4Oxx[$ 78HiAhZq/6!:;;EEzrM   c                P   | j                   r|j                  sg S |j                  j                  d      }|r%|j                  j                  d      }|r|d| z  }|j                  j                  t              }t	        j                  |d      }|s|r|dfdd|dfd| dfg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.filepathzcode.lineno:r]   )u   │bluer|   r   r[   )rC   rO   r>   r   r#   )rE   rT   ru   file_locationlinenolog_level_numrU   s          rK   rk   z(SimpleConsoleSpanExporter._details_parts   s     }}DOOI!__00A__((7F1VH-!__001MN#''r:	IR 'YK"%  IrM   c           	        | j                   r|j                  syi }t        dt        j                  |j                  j                  t        d                  }|j                  di       j                         D ]W  \  }}|j                  j                  |      }|r#t        j                  t        t        |            }t        ||      }|||<   Y |sy| j                  r| j                  ||       y| j                  ||       y)zQPretty-print formatted logfire arguments for the span if `self._verbose` is True.Ndict[str, Any]z{}
properties)schema)rC   rO   r   jsonloadsr>   r   itemsstrr&   r?   _print_arguments_rich_print_arguments_plain)rE   rT   ru   	argumentsjson_schemakeyr   values           rK   ro   z*SimpleConsoleSpanExporter._print_arguments   s    }}DOO$&	+TZZ8K8KLfhl8m-no&??<<BBDKCOO'',E

4U#34-eFCE"IcN E ==&&y*=''	:>rM   c           
        | j                   J g }|j                         D ]z  \  }}t        | dd      }t        |dd      }t        d|j	                  d	      d
z   z  dd d      }|j                  t        g |gt        |      z  |||d             | | j                   j                  t        |        y)zSPrint logfire arguments in color using rich, particularly with syntax highlighting.N=r   )stylepythondefaultbackground_coloru   │ 
r\      )r   r   )padding)
r?   r   r   r   countappendr   boolrl   r   )	rE   r   ru   chunksk
value_coder   r   barriers	            rK   r   z/SimpleConsoleSpanExporter._print_arguments_rich   s    }}((( "&__.MAz!Awf-C:x)LEH
(8(8(>(BCSbIQWXGMM$Z(88   	
  #		 /" 	E6N+rM   c                   g }|j                         D ]N  \  }}|j                         }|| d| d|d    gz  }| ddt        |      z   d}|dd D ]  }|| | gz  } P t        dj	                  |      | j
                         y)	zJPrint logfire arguments without color using the built-in `print` function.   │ r   r   r[   r   Nr\   re   )r   
splitlineslenrl   rn   r;   )	rE   r   ru   outr   r   value_linesprefixlines	            rK   r   z0SimpleConsoleSpanExporter._print_arguments_plain   s    &__.MAz$//1Kzl$qc;q>*:;<<C"|4c!f~Q7F#AB6(4&)** (	 / 	diin4<<0rM   c                   ||j                   syt        t        |j                   j                  d            }t        t        |j                   j                  d            }t        t        |j                   j                  d            }| j                  rrt        |dz   dd      }t        | d	dd
      }t        |      }t        ||dz         }t        |dd      }| j                  j                  t        |||      |       y| d| d	| g}|t        ||dz         gz  }t        dj                  |      | j                         y)z=Print exception information if an exception event is present.Nzexception.typezexception.messagezexception.stacktracer   r   r]   )r   endz: zbold red)r   r   r   r   r   r\   re   )rO   r   r   r>   r?   r   indent_textr   rl   r   rn   r;   )	rE   rw   ru   exc_typeexc_msgexc_tbr   indented_coder   s	            rK   rr   z)SimpleConsoleSpanExporter._print_exc_info  s(   I$8$8Y11556FGHsI00445HIJc9//334JKL==:.f"EGxjO:FH7mG'
V0CDMM8iPFMMgx A6J \hZr';<CK
V(;<==C$))C.t||4rM   c                     y)z6Force flush all spans, does nothing for this exporter.Tr`   )rE   timeout_milliss     rK   force_flushz%SimpleConsoleSpanExporter.force_flush  s    rM   Nr'   TFr*   rF   zTextIO | NonerG   ConsoleColorsValuesrH   r   rI   r   rJ   r%   returnNone)rS   zSequence[ReadableSpan]r   r   rT   r   r   r   )r   )rT   r   r   intrT   r   r   r   r   ztuple[str, TextParts])rT   r   ru   r   r   	TextParts)rT   r   ru   r   )r   r   ru   r   r   r   )rw   zEvent | Noneru   r   r   r   )r   r   r   r   )__name__
__module____qualname____doc__rL   rV   rQ   rX   rj   rk   ro   r   r   rr   r   r`   rM   rK   r.   r.   1   s     !%&,"&#)?? $?  	?
 ? !? 
?>	(4*)V<?,,0	15*rM   r.   c                  N     e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 d fdZddZ x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.
    c                :    t         |   |||||       i | _        y r_   )superrL   _indent_levelrE   rF   rG   rH   rI   rJ   	__class__s         rK   rL   z$IndentedConsoleSpanExporter.__init__'  s#     	):G]S-/rM   c                ~   |j                   xs i }|j                  t        d      }|dk(  r=|j                  r0| j                  j                  |j                  j                  d       y|j                  t              ry|dk(  rdt        |      }|r| j                  j                  |d      nd}|j                  r|j                  j                  ndx}rW|dz   | j                  |<   nD|j                  r|j                  j                  nd}|r| j                  j                  |d      nd}| j                  ||       y)zXGet the span indent based on `self._indent_level`, then print the span with that indent.rT   Npending_spanr   r   )rO   r>   r   contextr   popspan_idr!   _pending_span_parentparentrX   )rE   rT   rO   rY   	parent_idr   block_span_ids          rK   rQ   z%IndentedConsoleSpanExporter._log_span3  s	   __*
NN#;VD	||""&&t||';';TB>>-.&,Z8I=FT''++Iq9AF 8<{{ 3 3L}L4:QJ""=1 04{{++I=FT''++Iq9AFv&rM   r   r   r   )r   r   r   r   rL   rQ   __classcell__r   s   @rK   r   r      s]     !%&,"&#)
0
0 $
0  	
0
 
0 !
0 

0'rM   r   c                  b     e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 d fdZddZd	 fdZd
dZ x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.
    c                H    t         |   |||||       i | _        g | _        y r_   )r   rL   _span_history_span_stackr   s         rK   rL   z'ShowParentsConsoleSpanExporter.__init__W  s.     	):G]S ?A&(rM   c                   |j                   xs i }|j                  t        d      }|dk(  r|j                  r|| j                  j                  |j                  j                  d       | j                  r@| j                  d   |j                  j                  k(  r| j                  j                          y|j                  t              ry| j                  |       y)zbPrint any parent spans which aren't in the current stack of displayed spans, then print this span.rT   Nr   )
rO   r>   r   r   r   r   r   r   r!   rX   )rE   rT   rO   rY   s       rK   rQ   z(ShowParentsConsoleSpanExporter._log_spanf  s    __*
NN#;VD	||""&&t||';';TB##(8(8(<@T@T(T$$((*>>-.rM   c                |   |j                   xs i }|j                  t        d      }g }|dk(  rt        |      }|| j	                  |      z  }t        | j                        }t        
| !  ||      \  }}||z  }|j                  xr |j                  j                  x}	r1|||xs df| j                  |	<   | j                  j                  |	       ||fS |j                  r|j                  j                  nd}|| j	                  |      z  }t        
| !  |t        | j                              \  }}||z  }||fS )zjParts for any parent spans which aren't in the current stack of displayed spans, then parts for this span.rT   r   r   Nr   )rO   r>   r   r   _parent_stack_text_partsr   r   r   rj   r   r   r   r   )rE   rT   r   rO   rY   rt   r   r   
span_partsr   r   s             rK   rj   z/ShowParentsConsoleSpanExporter._span_text_partsw  s;   __*
NN#;VD	&,Z8IT229==E))*F#g6tVDOCZE $ C0C0CC}C5;S).q4Q""=1  ''6 Ez	 04{{++IT229==E#g6tCHXHXDY6ZOCZEEzrM   c                   g }d}|rJ	 | j                   |   \  }}}	 | j                  j                  |      }| j                  d|dz    | _        d}	 |r| j                  j                          g }t        |      D ]F  \  }}	}| j                  |dz  z   }
|d|
z   |	 ddfgz  }|s,| j                  j	                  |       H |S # t        $ r |j	                  |||f       |}Y nw xY w# t
        $ r Y w xY w|r)	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   r   index
ValueErrorr   KeyErrorclearreversedrB   )rE   r   parentsclear_stackr   r   grand_parent_idstack_indexrt   r   total_indents              rK   r   z7ShowParentsConsoleSpanExporter._parent_stack_text_parts  s7    /1040B0B90M-o"&"2"2"8"8"CK
 (,'7'78I+/'JD$"'K ""$ '/w&7"FC11FQJ>L#,-cU"5u=>>E  ''	2	 '8
 ) " 0NNFD)#<= /I0   s"   C* C C'&C'*	C65C6r   r   r   r   )r   
int | Noner   r   )	r   r   r   r   rL   rQ   rj   r   r   r   s   @rK   r   r   O  sg     !%&,"&#))) $)  	)
 ) !) 
)"2%rM   r   c                J    | j                  t              x}rt        |d      S y)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   r   )rO   parent_id_strs     rK   r   r     s,     #'NOO}O="%% PrM   )rO   z'Mapping[str, otel_types.AttributeValue]r   r   )?r   
__future__r   r   r<   r9   collections.abcr   r   r   textwrapr   r   typingr	   r
   r   r   r   r   r   opentelemetry.sdk.tracer   r   opentelemetry.sdk.trace.exportr   r   opentelemetry.utilr   
otel_typesrich.columnsr   rich.consoler   r   rich.syntaxr   	rich.textr   	constantsr   r   r   r   r   r    r!   r"   r#   r$   r%   json_formatterr&   r   rP   r   r   r   r   r.   r   r   r   r`   rM   rK   <module>r     s   
 #  	 
 $ ' * C C C 7 I 2   '      778 F#F#W% sCx!	l l^,'"; ,'^f%> fR
&rM   