
    jJ                        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 d dlmZ d dlm	Z	m
Z
mZ d dlmZ  G d d          Z G d d	          Zed
k    r ed            ed            e            Z	 	 e                                Z edd            eded         dd            eded         dd            eded         d         dd            eded         d         dd            eded         d          dd!            ed"ed#         d$         d%d            ed&ed#         d'         d%d           ed(         rc ed)           ed(                                         D ]<\  ZZ ed*e d+ed,         d-d.ed/         dd0ed1         d2d3ed4         d-d5           =n ed6            ej        d7           a# e$ r  ed8           Y dS w xY wdS )9    N)datetime)Path)LOGGERMACOSRANK)check_requirementsc                   ~    e Zd ZdZddZd Zd Zd Zd	 Zd
 Z	d Z
 G d d          Z G d dej                  ZdS )ConsoleLoggera  Console output capture with batched streaming to file, API, or custom callback.

    Captures stdout/stderr output and streams it with intelligent deduplication and configurable batching.

    Attributes:
        destination (str | Path | None): Target destination for streaming (URL, Path, or None for callback-only).
        batch_size (int): Number of lines to batch before flushing (default: 1 for immediate).
        flush_interval (float): Seconds between automatic flushes (default: 5.0).
        on_flush (callable | None): Optional callback function called with batched content on flush.
        active (bool): Whether console capture is currently active.

    Examples:
        File logging (immediate):
        >>> logger = ConsoleLogger("training.log")
        >>> logger.start_capture()
        >>> print("This will be logged")
        >>> logger.stop_capture()

        API streaming with batching:
        >>> logger = ConsoleLogger("https://api.example.com/logs", batch_size=10)
        >>> logger.start_capture()

        Custom callback with batching:
        >>> def my_handler(content, line_count, chunk_id):
        ...     print(f"Received {line_count} lines")
        >>> logger = ConsoleLogger(on_flush=my_handler, batch_size=5)
        >>> logger.start_capture()
    N         @c                    || _         t          |t                    o|                    d          | _        || j        st          |          | _         t          d|          | _        || _        || _	        t          j        | _        t          j        | _        d| _        d| _        g | _        t%          j                    | _        d| _        d| _        d| _        d| _        d| _        d| _        dS )a  Initialize console logger with optional batching.

        Args:
            destination (str | Path | None): API endpoint URL (http/https), local file path, or None.
            batch_size (int): Lines to accumulate before flush (1 = immediate, higher = batched).
            flush_interval (float): Max seconds between flushes when batching.
            on_flush (callable | None): Callback(content: str, line_count: int, chunk_id: int) for custom handling.
        )zhttp://zhttps://Nr   Fr    g        )destination
isinstancestr
startswithis_apir   max
batch_sizeflush_intervalon_flushsysstdoutoriginal_stdoutstderroriginal_stderractive_log_handlerbuffer	threadingLockbuffer_lockflush_threadchunk_id	last_line	last_timelast_progress_linelast_was_progress)selfr   r   r   r   s        ]/home/longshao/multi-rider-rag/.venv/lib/python3.11/site-packages/ultralytics/utils/logger.py__init__zConsoleLogger.__init__-   s     ' c22f{7M7MNe7f7f"4;"#K00D a,,,   #z"z  $>++  "$!&    c                 &   | j         s	t          dvrdS d| _         |                     | j        | j                  t
          _        |                     | j        | j                  t
          _        	 | 	                    | j                  | _
        t          j        d                              | j
                   n# t          $ r Y nw xY w| j        dk    r;t!          j        | j        d          | _        | j                                         dS dS )zStart capturing console output and redirect stdout/stderr.

        Notes:
            In DDP training, only activates on rank 0/-1 to prevent duplicate logging.
        >   r   NTultralyticsr   )targetdaemon)r   r   _ConsoleCapturer   
_queue_logr   r   r   r   _LogHandlerr   logging	getLogger
addHandler	Exceptionr   r    Thread_flush_workerr#   startr)   s    r*   start_capturezConsoleLogger.start_captureR   s    ; 	$g--F))$*>PP
))$*>PP
	 $ 0 0 A ADm,,778IJJJJ 	 	 	D	 ?Q ) 08JSW X X XD##%%%%% s   /AB; ;
CCc                 *   | j         sdS d| _         | j        t          _        | j        t          _        | j        rE	 t          j        d          	                    | j                   n# t          $ r Y nw xY wd| _        |                                  dS )z9Stop capturing console output and flush remaining buffer.NFr/   )r   r   r   r   r   r   r   r5   r6   removeHandlerr8   _flush_bufferr<   s    r*   stop_capturezConsoleLogger.stop_capturek   s    { 	F)
)
  	%!-00>>t?PQQQQ    $D 	s   ,A( (
A54A5c                    | j         sdS t          j                    }d|v r|                    d          d         }|                    d          }|r |d         dk    r|                                 |D ]}|                                }d|v rd|v rd|v }|s'|                                }d}|rd	|d
         v r7|d
                             d	d                                          r	|d
         }nE|d
         dk    r't          |          dk    r|d
          d|d          }n|d
         dv r|d
         }|r| j        | dk    r|r
| d| _        d| _	        n|s| j	        rd| _	        d| _	        || j
        k    r|| j        z
  dk     r|| _
        || _        |                    d          s.t          j                                        d          }d| d| }d}	| j        5  | j                            |           t          | j                  | j        k    rd}	ddd           n# 1 swxY w Y   |	r|                                  dS )z?Queue console text with deduplication and timestamp processing.Nr.   
r   u   ─u    ━━z100%/r   Classr   _)ztrain:zval:z:doneTF皙?z[20z%Y-%m-%d %H:%M:%S[z] )r   timesplitpoprstripreplaceisdigitlenr'   r(   r%   r&   r   r   nowstrftimer"   r   appendr   r@   )
r)   textcurrent_timelineslineis_completepartsseq_key	timestampshould_flushs
             r*   r3   zConsoleLogger._queue_log   s   { 	Fy{{ 4<<::d##B'D

4   	U2Y"__IIKKK @	% @	%D;;==D }} D  $n #  

 +eAh58+;+;C+D+D+L+L+N+N"'(qW,,Ua%*1X":":a":":q%777"'(  t6W:K:K:KKK  @18.?.?.?D+)-&&   6 -2D*).& t~%%,*G#*M*M!DN)DN ??5)) /$LNN334GHH	.9.... !L! ( (""4(((t{##t66#'L( ( ( ( ( ( ( ( ( ( ( ( ( ( (  %""$$$A@	% @	%s   ,:H22H6	9H6	c                     | j         r=t          j        | j                   | j         r|                                  | j         ;dS dS )z3Background worker that flushes buffer periodically.N)r   rJ   sleepr   r@   r<   s    r*   r:   zConsoleLogger._flush_worker   s[    k 	%Jt*+++{ %""$$$ k 	% 	% 	% 	% 	%r,   c                    | j         5  | j        s	 ddd           dS | j                                        }| j                                         | xj        dz  c_        | j        }ddd           n# 1 swxY w Y   d                    |          }t          |          }| j        r)	 |                     |||           n# t          $ r Y nw xY w| j	        | 
                    |           dS dS )z4Flush buffered lines to destination and/or callback.Nr   rD   )r"   r   copyclearr$   joinrP   r   r8   r   _write_destination)r)   rV   r$   content
line_counts        r*   r@   zConsoleLogger._flush_buffer   sj    	% 	%; 	% 	% 	% 	% 	% 	% 	% 	% K$$&&EKMMQMM}H	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% ))E""ZZ
 = 	gz8<<<<    '##G,,,,, ('s)   	A3A	A33A7:A7*C 
CCc                    	 | j         rXddl}t          j                                                    |d}|                    t          | j                  |d           dS | j        j        	                    dd           | j        
                    dd	
          5 }|                    |dz              ddd           dS # 1 swxY w Y   dS # t          $ r$}t          d| | j                   Y d}~dS d}~ww xY w)z)Write content to file or API destination.r   N)r[   message   )jsontimeoutT)parentsexist_okazutf-8)encodingrD   zConsole logger write error: )file)r   requestsr   rQ   	isoformatpostr   r   parentmkdiropenwriter8   printr   )r)   rd   rp   payloadfes         r*   rc   z ConsoleLogger._write_destination   si   	Q{ ,(0(@(@(B(BwWWc$"233'1MMMMM '--dT-JJJ%**3*AA ,QGGGdN+++, , , , , , , , , , , , , , , , , , 	Q 	Q 	Q4444;OPPPPPPPPPP	QsB   AC !=C C7C CC CC 
C?C::C?c                   (    e Zd ZdZdZd Zd Zd ZdS )ConsoleLogger._ConsoleCapturez"Lightweight stdout/stderr capture.)callbackoriginalc                 "    || _         || _        dS )z^Initialize a stream wrapper that redirects writes to a callback while preserving the original.N)r~   r}   )r)   r~   r}   s      r*   r+   z&ConsoleLogger._ConsoleCapture.__init__  s    $DM$DMMMr,   c                 d    | j                             |           |                     |           dS )zIWrite text to the original stream and forward it to the capture callback.N)r~   rv   r}   )r)   rT   s     r*   rv   z#ConsoleLogger._ConsoleCapture.write  s0    M%%%MM$r,   c                 8    | j                                          dS )zVFlush the wrapped stream to propagate buffered output promptly during console capture.N)r~   flushr<   s    r*   r   z#ConsoleLogger._ConsoleCapture.flush  s    M!!!!!r,   N)__name__
__module____qualname____doc__	__slots__r+   rv   r    r,   r*   r2   r|      sL        00,		% 	% 	%
	  	  	 
	" 	" 	" 	" 	"r,   r2   c                   ,     e Zd ZdZdZ fdZd Z xZS )ConsoleLogger._LogHandlerzLightweight logging handler.)r}   c                 V    t                                                       || _        dS )z\Initialize a lightweight logging.Handler that forwards log records to the provided callback.N)superr+   r}   )r)   r}   	__class__s     r*   r+   z"ConsoleLogger._LogHandler.__init__  s$    GG$DMMMr,   c                 \    |                      |                     |          dz              dS )zXFormat and forward LogRecord messages to the capture callback for unified log streaming.rD   N)r}   format)r)   records     r*   emitzConsoleLogger._LogHandler.emit  s+    MM$++f--455555r,   )r   r   r   r   r   r+   r   __classcell__)r   s   @r*   r4   r     sR        **!		% 	% 	% 	% 	%
	6 	6 	6 	6 	6 	6 	6r,   r4   )Nr   r   N)r   r   r   r   r+   r=   rA   r3   r:   r@   rc   r2   r5   Handlerr4   r   r,   r*   r
   r
      s         :#' #' #' #'J& & &2  (O% O% O%b% % %- - -0Q Q Q" " " " " " " "&6 6 6 6 6go 6 6 6 6 6r,   r
   c                   ,    e Zd ZdZd Zd ZddZd ZdS )	SystemLoggeru  Log dynamic system metrics for training monitoring.

    Captures real-time system metrics including CPU, RAM, disk I/O, network I/O, and NVIDIA GPU statistics for training
    performance monitoring and analysis.

    Attributes:
        pynvml: NVIDIA pynvml module instance if successfully imported, None otherwise.
        nvidia_initialized (bool): Whether NVIDIA GPU monitoring is available and initialized.
        net_start: Initial network I/O counters for calculating cumulative usage.
        disk_start: Initial disk I/O counters for calculating cumulative usage.

    Examples:
        Basic usage:
        >>> logger = SystemLogger()
        >>> metrics = logger.get_metrics()
        >>> print(f"CPU: {metrics['cpu']}%, RAM: {metrics['ram']}%")
        >>> if metrics["gpus"]:
        ...     gpu0 = metrics["gpus"]["0"]
        ...     print(f"GPU0: {gpu0['usage']}% usage, {gpu0['temp']}°C")

        Training loop integration:
        >>> system_logger = SystemLogger()
        >>> for epoch in range(epochs):
        ...     # Training code here
        ...     metrics = system_logger.get_metrics()
        ...     # Log to database/file
    c                    ddl }d| _        |                                 | _        |                                | _        |                                | _        | j        | _        | j        | _	        t          j
                    | _        dS )zInitialize the system logger.r   N)psutilpynvml_init_nvidianvidia_initializednet_io_counters	net_startdisk_io_counters
disk_start	_prev_net
_prev_diskrJ   
_prev_time)r)   r   s     r*   r+   zSystemLogger.__init__=  sq    "&"3"3"5"5//11 1133 /)++r,   c                 *   t           rdS 	 t          d           t          d          | _        | j                                         dS # t
          $ r?}ddl}|j                                        rt          j
        d|            Y d}~dS d}~ww xY w)z-Initialize NVIDIA GPU monitoring with pynvml.Fznvidia-ml-py>=12.0.0r   Tr   NzSystemLogger NVML init failed: )r   r   
__import__r   nvmlInitr8   torchcudais_availabler   warning)r)   rz   r   s      r*   r   zSystemLogger._init_nvidiaK  s     	5
	5666$X..DKK  """4 	 	 	LLLz&&(( FDDDEEE55555	s   <A	 	
B4BBFc                 b   ddl }|                                }|                                }|                                }t	          j        d          }t          j                    }t          |                                d          t          |j	        d          i d}t          d|| j        z
            }	|rt          t          d|j        | j        j        z
  dz  |	z            d          t          t          d|j        | j        j        z
  dz  |	z            d          t          |j        dz  d          d	|d
<   t          t          d|j        | j        j        z
  dz  |	z            d          t          t          d|j        | j        j        z
  dz  |	z            d          d|d<   nt          |j        | j        j        z
  dz  d          t          |j        | j        j        z
  dz  d          t          |j        dz  d          d|d
<   t          |j        | j        j        z
  dz  d          t          |j        | j        j        z
  dz  d          d|d<   || _        || _        || _        | j        r-|d                             |                                            |S )a	  Get current system metrics including CPU, RAM, disk, network, and GPU usage.

        Collects comprehensive system metrics including CPU usage, RAM usage, disk I/O statistics, network I/O
        statistics, and GPU metrics (if available).

        Example output (rates=False, default):
        ```python
        {
            "cpu": 45.2,
            "ram": 78.9,
            "disk": {"read_mb": 156.7, "write_mb": 89.3, "used_gb": 256.8},
            "network": {"recv_mb": 157.2, "sent_mb": 89.1},
            "gpus": {
                "0": {"usage": 95.6, "memory": 85.4, "temp": 72, "power": 285},
                "1": {"usage": 94.1, "memory": 82.7, "temp": 70, "power": 278},
            },
        }
        ```

        Example output (rates=True):
        ```python
        {
            "cpu": 45.2,
            "ram": 78.9,
            "disk": {"read_mbs": 12.5, "write_mbs": 8.3, "used_gb": 256.8},
            "network": {"recv_mbs": 5.2, "sent_mbs": 1.1},
            "gpus": {
                "0": {"usage": 95.6, "memory": 85.4, "temp": 72, "power": 285},
            },
        }
        ```

        Args:
            rates (bool): If True, return disk/network as MB/s rates instead of cumulative MB.

        Returns:
            (dict): Metrics dictionary with cpu, ram, disk, network, and gpus keys.

        Examples:
            >>> logger = SystemLogger()
            >>> logger.get_metrics()["cpu"]  # CPU percentage
            >>> logger.get_metrics(rates=True)["network"]["recv_mbs"]  # MB/s download rate
        r   NrE      )cpuramgpusrH   i   i   @)read_mbs	write_mbsused_gbdisk)recv_mbssent_mbsnetwork)read_mbwrite_mbr   )recv_mbsent_mbr   )r   r   r   virtual_memoryshutil
disk_usagerJ   roundcpu_percentpercentr   r   
read_bytesr   write_bytesused
bytes_recvr   
bytes_sentr   r   r   update_get_nvidia_metrics)
r)   ratesr   netr   memoryr   rQ   metricselapseds
             r*   get_metricszSystemLogger.get_metrics\  s   X 	$$&&&&((&&((&s++
ikk ++--q11++
 
 c3011 	 "#a$/DO<V*V[b)cfm)m"n"npqrr"3q4+;do>Y+Y^e*fip*p#q#qstuu G!<a@@ GFO "#a#.4>;T*TY`)adk)k"l"lnopp!#a#.4>;T*TY`)adk)k"l"lnopp" "GI !$/DO4N"NSZ![]^__!4#3do6Q#QV]"^`abb G!<a@@ GFO !#.4>3L"LQX!Y[\]] #.4>3L"LQX!Y[\]]" "GI  " 	?FO""4#;#;#=#=>>>r,   c                 T   i }| j         r| j        s|S 	 | j                                        }t          |          D ]}| j                            |          }| j                            |          }| j                            |          }| j                            || j        j                  }| j        	                    |          dz  }t          |j        d          t          |j        |j        z  dz  d          ||d|t          |          <   n# t          $ r Y nw xY w|S )zMGet NVIDIA GPU metrics including utilization, memory, temperature, and power.i  r   d   )usager   temppower)r   r   nvmlDeviceGetCountrangenvmlDeviceGetHandleByIndexnvmlDeviceGetUtilizationRatesnvmlDeviceGetMemoryInfonvmlDeviceGetTemperatureNVML_TEMPERATURE_GPUnvmlDeviceGetPowerUsager   gpur   totalr   r8   )	r)   r   device_countihandleutilr   r   r   s	            r*   r   z SystemLogger._get_nvidia_metrics  s:   & 	dk 	K	;99;;L<((  ??BB{@@HH<<VDD{;;FDKDdee;;FCCtK #48Q//#V[6<%?3$FJJ "	   SVV  	 	 	D	s   DD 
D%$D%N)F)r   r   r   r   r+   r   r   r   r   r,   r*   r   r      sd         8& & &  "] ] ] ]~    r,   r   __main__z&SystemLogger Real-time Metrics MonitorzPress Ctrl+C to stop
Tz[H[Jr   )endzCPU: r   z5.1f%zRAM: r   zDisk Read: r   r   z8.1fz MBzDisk Write: r   z7.1fzDisk Used: r   z GBz
Net Recv: r   r   z9.1fz
Net Sent: r   r   z
GPU Metrics:z  GPU z: r   3z	% | Mem: r   z
% | Temp: r   2u   °C | Power: r   Wz
GPU: No NVIDIA GPUs detectedr   z

Stopped monitoring.)r5   r   r   r    rJ   r   pathlibr   ultralytics.utilsr   r   r   ultralytics.utils.checksr   r
   r   r   rw   loggerr   r   itemsgpu_idgpu_datar^   KeyboardInterruptr   r,   r*   <module>r      s     



                  1 1 1 1 1 1 1 1 1 1 7 7 7 7 7 7N6 N6 N6 N6 N6 N6 N6 N6bq q q q q q q qh z	E
2333	E
"###\^^F )	((**G E.b)))) E0'%.0000111E0'%.0000111ED	 :DDDDEEEEF!<FFFFGGGED	 :DDDDEEEEFwy1)<FFFFGGGEFwy1)<FFFFGGG v 
8&'''(/(=(=(?(?  $FHE9 9 98G+<D 9 9 ( 2=9 9!)&!1;9 9 #+7"389 9 9    6777DJqMMM9	<  ) ) )'(((((()K s   3E"G G)(G)