
    Jj$                         d Z ddlZddlZddlZddlmZ ddlZddlZddlm	Z	m
Z
mZ  G d d          Zdeded	ee         fd
ZddZ	 	 ddee         dedee         d	eee         eef         fdZdS )zProcess log management utilities.

Handles writing, reading, and capping JSONL log files for background
processes.  Extracted from ``main.py`` to keep the route module focused.
    N)Optional)MAX_PROCESS_LOG_SIZELOG_FLUSH_INTERVALLOG_FLUSH_BUFFERc                   R    e Zd ZdZdZddddededefdZd	ed
dfdZ	ddZ
ddZdS )BoundedLogWriteru  Async wrapper that rotates the log file when it exceeds a size limit.

    When the total bytes written surpass *MAX_PROCESS_LOG_SIZE*, the file
    is truncated to its newest half and a ``log_rotated`` marker is inserted.
    Writing then continues, so the most recent output is always available.

    Flushing behaviour is controlled by *flush_interval* and *flush_buffer*:

    * ``flush_interval=0`` (default) — flush after every write (original
      behaviour, safest for low-throughput commands).
    * ``flush_interval>0`` — flush at most once per *flush_interval* seconds,
      **or** when the unflushed buffer exceeds *flush_buffer* bytes (if set).
      This dramatically reduces I/O pressure for high-output commands.
    )_file	_log_path_bytes_writtenrotated_flush_interval_flush_buffer
_unflushed_last_flushr   flush_intervalflush_bufferlog_pathr   r   c                    || _         || _        d| _        d| _        || _        || _        d| _        t          j                    | _	        d S )Nr   F)
r	   r
   r   r   r   r   r   time	monotonicr   )selffiler   r   r   s        k/home/rurouni/.cache/uv/archive-v0/6mr0qdqUAO9GXgnL/lib/python3.11/site-packages/open_terminal/utils/log.py__init__zBoundedLogWriter.__init__'   sL    
!-)>++    datareturnNc                 z  K   t          |                    dd                    }| j        |z   t          k    r|                                  d {V  | j                            |           d {V  | xj        |z  c_        | xj        |z  c_        | j        dk    r(| j        	                                 d {V  d| _        d S t          j                    }|| j        z
  | j        k    }|s| j        dk    r| j        | j        k    }|r/| j        	                                 d {V  d| _        || _        d S d S )Nutf-8replaceerrorsr   )lenencoder   r   _rotater	   writer   r   flushr   r   r   r   )r   r   encoded_lennowshould_flushs        r   r'   zBoundedLogWriter.write1   sw     $++gi+@@AA,/CCC,,..       jt$$$$$$$$${*;&1$$*""$$$$$$$$$DOFnd..43GG 	A 2Q 6 6?d.@@L 	#*""$$$$$$$$$DO"D	# 	#r   c                    K   | j                                          d {V  d| _        t          j                    | _        d S )Nr   )r	   r(   r   r   r   r   )r   s    r   r(   zBoundedLogWriter.flushH   sI      j         >++r   c                 h  K   d| _         | j                                         d{V  | j                                         d{V  t	          j        | j        dd          4 d{V }|                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   |t          |          dz  d         }t	          j        | j        dd          4 d{V }|	                    t          j        dt          j                    d	          d
z              d{V  |D ]}|	                    |           d{V  	 ddd          d{V  n# 1 d{V swxY w Y   t	          j        | j        dd           d{V | _        t          d |D                       | _        dS )z:Keep the newest half of the log file and continue writing.TNrr    encoding   wlog_rotated)typets
ac              3   ^   K   | ](}t          |                    d d                    V  )dS )r    r!   r"   N)r$   r%   ).0ls     r   	<genexpr>z+BoundedLogWriter._rotate.<locals>.<genexpr>c   s:      !Y!Yq#ahhwyh&I&I"J"J!Y!Y!Y!Y!Y!Yr   )r   r	   r(   closeaiofilesopenr
   	readlinesr$   r'   jsondumpsr   sumr   )r   flineskeeplines        r   r&   zBoundedLogWriter._rotateM   s     j         j         =wGGG 	( 	( 	( 	( 	( 	( 	(1++--''''''E	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( SZZ1_&&'=wGGG 	$ 	$ 	$ 	$ 	$ 	$ 	$1''
MEEFFM          $ $ggdmm########$		$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ $=wOOOOOOOOO
!!Y!YTX!Y!Y!YYYs%   *B
B!$B!$A%E
E&)E&r   N)__name__
__module____qualname____doc__	__slots__strfloatintr   r'   r(   r&    r   r   r   r      s         I
 HI^_ , , ,s ,u ,X[ , , , ,# # # # # #., , , ,
Z Z Z Z Z Zr   r   r   nr   c                   K   d}g }t          j        | d          4 d{V }|                    dd           d{V  |                                 d{V }d}|dk    rNt	          |          |k     r:t          ||          }||z  }|                    |           d{V  |                    |           d{V }||z   }|                    d          }	|	d         }t          |	dd                   D ]}
|
	                                }
|
s	 t          j        |
          }n# t          j        t          f$ r Y Gw xY w|                    d	          d
v r9|                    |d	         |d         d           t	          |          |k    r n|dk    rt	          |          |k     :|	                                rt	          |          |k     rm	 t          j        |          }|                    d	          d
v r$|                    |d	         |d         d           n# t          j        t          f$ r Y nw xY wddd          d{V  n# 1 d{V swxY w Y   |                                 || d         S )zRead the last *n* output entries from a JSONL log without loading the whole file.

    Uses a reverse-read strategy: read chunks from the end of the file
    until enough newline-delimited records have been collected.
    i    rbNr   r1   r      
   r4   stdoutstderroutputr   r4   r   )r=   r>   seektellr$   minreadsplitreversedstripr@   loadsJSONDecodeErrorUnicodeDecodeErrorgetappendreverse)r   rQ   CHUNKentriesrC   	remainingbuffer	read_sizechunkrD   raw_linerecords               r   tail_logrp   f   sP      EG}Xt,, " " " " " " "ffQll&&((NNNNNN	!mmGq 0 0E9--I"I&&#########&&++++++++EV^FLL''E1XF$U122Y//  #>>++ !Z11FF,.@A   H::f%%)GGGNNF6NF6N#S#STTT7||q(() !mmGq 0 0. <<>> 	c'llQ..F++::f%%)GGGNNF6NF6N#S#STTT(*<=   C" " " " " " " " " " " " " " " " " " " " " " " " " " "H OOA233<s\   C1ID)(I)E?IEBIAH('I(I>I II
I #I c                 J  K   d}d}	 | j         rt          j                            t          j                            | j                   d           d{V  t          j        | j         dd           d{V }|                    t          j	        d| j
        | j        j        t          j                    d	          d
z              d{V  |                                 d{V  n# t          $ r d}Y nw xY w|r"t!          || j         t"          t$                    nd}	 | j                            |           d{V  |r|j        nd}| j                                         d{V }|| _        d| _        t          j                    | _        | j                                         |r|                                 d{V  |rg|                    t          j	        d| j        |t          j                    d          d
z              d{V  |                                 d{V  dS dS # |r|j        nd}| j                                         d{V }|| _        d| _        t          j                    | _        | j                                         |r|                                 d{V  |rf|                    t          j	        d| j        |t          j                    d          d
z              d{V  |                                 d{V  w w xY w)zRead process output and persist to a log file.

    When the file exceeds *MAX_PROCESS_LOG_SIZE*, the oldest half is
    discarded so the most recent output is always available.
    NFT)exist_okr7   r    r/   start)r4   commandpidr5   r6   r   doneend)r4   	exit_coder3   r5   )r   r=   osmakedirspathdirnamer>   r'   r@   rA   rt   runnerru   r   r(   OSErrorr   r   r   read_outputr   waitrx   statusfinished_atr<   )background_processlog_filer3   writerrx   s        r   log_processr      s>      HK& 	#+&& 2 ;<<t '          &]+=+FV]^^^^^^^^^H..
 '#5#=18<"ikk	   
 
 
 
 
 
 
 
 
 .."""""""""    	'-)		
 	
 	
 	
  # '33F;;;;;;;;;(.9fnnE,388::::::::	'0$$*!)-&!''))) 	!,,..        	#..
 %%7%A'2"ikk	   
 
 
 
 
 
 
 
 
 .."""""""""""	# 	# )/9fnnE,388::::::::	'0$$*!)-&!''))) 	!,,..        	#..
 %%7%A'2"ikk	   
 
 
 
 
 
 
 
 
 ..""""""""""	#s   C!C* *C98C9# H3 3C/L"offsettailc                 .  K   g }| r*t           j        j                            |            d{V s|ddfS |A|dk    r;t	          | |           d{V }t          |          |k    }|t          |          |fS t          j        | d          4 d{V }|                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   |D ]}|                                }|s	 t          j
        |          }	n# t          j        $ r Y @w xY w|	                    d          dv r$|                    |	d         |	d         d	           t          |          }
||d         }d}| t          |          |k    r|| d         }d
}||
|fS )u"  Read output entries from a JSONL log file.

    Returns ``(entries, next_offset, truncated)``.

    When *tail* is specified and *offset* is 0, the file is read from the
    end to avoid loading the entire file into memory — preventing the
    memory spike that caused the OOM issue.
    Nr   Fr    r/   r4   rV   r   rZ   T)r=   ry   r{   isfilerp   r$   r>   r?   ra   r@   rb   rc   re   rf   )r   r   r   ri   tail_entries	truncatedrC   rD   rF   ro   totals              r   read_logr      s|      G !!1!8!8!B!BBBBBBB !5   FaKK%h55555555%%-	S..	99 }X888 $ $ $ $ $ $ $Akkmm######$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $  	M 	Mzz|| 		Z%%FF# 	 	 	H	::f!???NNF6NF6NKKLLLLLEfggGICLL4//4%&&/	E9$$s$   C
CC/DDDrG   )r   N)rK   r@   ry   r   typingr   r=   aiofiles.osopen_terminal.envr   r   r   r   rM   rO   listdictrp   r   tupleboolr   rP   r   r   <module>r      sX     				             X X X X X X X X X XQZ QZ QZ QZ QZ QZ QZ QZh.S .S .T$Z . . . .bA# A# A# A#L .% .%sm.%.% 3-.% 4:sD !	.% .% .% .% .% .%r   