
    h;                     r   S SK r S SKrS SKrS SKrS SKrS SKrS SKJr  S SKJr  S SK	J
r
Jr  S SKJr  \" S5      r\S;   a$  \R                  5       (       a  \R!                  SS	9   " S
 S5      r " S S5      r\S:X  Ga$  \" S5        \" S5        \" 5       r  \R-                  5       r\" SSS9  \" S\S   S S35        \" S\S   S S35        \" S\S   S   S S35        \" S\S   S    S! S35        \" S"\S   S#   S S$35        \" S%\S&   S'   S( S35        \" S)\S&   S*   S( S35        \S+   (       aN  \" S,5        \S+   R1                  5        H.  u  rr\" S-\ S.\S/   S0 S1\S2   S S3\S4   S5 S6\S7   S0 S835        M0     O\" S95        \R6                  " S:5        GM  g! \ a    \" S;5         gf = f)<    N)datetime)Path)MACOSRANK)check_requirementsz	train.log>   r   T)
missing_okc                       \ rS rSrSrS rS rS rS rS r	S r
S	 r " S
 S5      r " S S\R                  5      rSrg)ConsoleLogger   a  
Console output capture with API/file streaming and deduplication.

Captures stdout/stderr output and streams it to either an API endpoint or local file, with intelligent
deduplication to reduce noise from repetitive console output.

Attributes:
    destination (str | Path): Target destination for streaming (URL or Path object).
    is_api (bool): Whether destination is an API endpoint (True) or local file (False).
    original_stdout: Reference to original sys.stdout for restoration.
    original_stderr: Reference to original sys.stderr for restoration.
    log_queue (queue.Queue): Thread-safe queue for buffering log messages.
    active (bool): Whether console capture is currently active.
    worker_thread (threading.Thread): Background thread for processing log queue.
    last_line (str): Last processed line for deduplication.
    last_time (float): Timestamp of last processed line.
    last_progress_line (str): Last progress bar line for progress deduplication.
    last_was_progress (bool): Whether the last line was a progress bar.

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

    API streaming:
    >>> logger = ConsoleLogger("https://api.example.com/logs")
    >>> logger.start_capture()
    >>> # All output streams to API
    >>> logger.stop_capture()
c                    Xl         [        U[        5      =(       a    UR                  S5      U l        U R                  (       d  [        U5      U l         [        R                  U l        [        R                  U l
        [        R                  " SS9U l        SU l        SU l        SU l        SU l        SU l        SU l        g)z
Initialize with API endpoint or local file path.

Args:
    destination (str | Path): API endpoint URL (http/https) or local file path for streaming output.
)zhttp://zhttps://  )maxsizeFN g        )destination
isinstancestr
startswithis_apir   sysstdoutoriginal_stdoutstderroriginal_stderrqueueQueue	log_queueactiveworker_thread	last_line	last_timelast_progress_linelast_was_progress)selfr   s     R/home/james-whalen/.local/lib/python3.13/site-packages/ultralytics/utils/logger.py__init__ConsoleLogger.__init__7   s     ' c2f{7M7MNe7f{{#K0D  #zz"zzT2! "$!&    c                    U R                   (       a  gSU l         U R                  U R                  U R                  5      [        l        U R                  U R                  U R                  5      [        l         U R                  U R                  5      n[        R                  " S5      R                  U5        [        R                  " U R                  SS9U l        U R                   R#                  5         g! [         a     NKf = f)zTStart capturing console output and redirect stdout/stderr to custom capture objects.NTultralytics)targetdaemon)r   _ConsoleCapturer   
_queue_logr   r   r   r   _LogHandlerlogging	getLogger
addHandler	Exception	threadingThread_stream_workerr   start)r$   handlers     r%   start_captureConsoleLogger.start_captureP   s    ;;))$*>*>P
))$*>*>P
	&&t7Gm,77@ '--T5H5HQUV  "	  		s   9A C8 8
DDc                     U R                   (       d  gSU l         U R                  [        l        U R                  [        l        U R                  R                  S5        g)zAStop capturing console output and restore original stdout/stderr.NF)r   r   r   r   r   r   r   putr$   s    r%   stop_captureConsoleLogger.stop_capturec   s?    {{))
))
4 r(   c                 H   U R                   (       d  g[        R                  " 5       nSU;   a  UR                  S5      S   nUR                  S5      nU(       a  US   S:X  a  UR                  5         U GH)  nUR	                  5       nSU;   a  M  SU;   aR  UR                  S5      S   R                  5       nXPR                  :X  a  U R                  (       a  Mf  XPl        S	U l        O(U(       d  U R                  (       a	  S
U l        M  S
U l        X@R                  :X  a  X R                  -
  S:  a  M  X@l        X l	        UR                  S5      (       d,  [        R                  " 5       R                  S5      nSU SU 3nU R                  U S35      (       a  GM)  GM,     g)z?Queue console text with deduplication and timestamp processing.Nr   
r   u   ─u    ━━r   TFg?z[20z%Y-%m-%d %H:%M:%S[z] )r   timesplitpoprstripstripr"   r#   r    r!   r   r   nowstrftime	_safe_put)r$   textcurrent_timelineslineprogress_core	timestamps          r%   r.   ConsoleLogger._queue_logm   s_   {{yy{ 4<::d#B'D

4 U2Y"_IIKD;;=D } D  $

9 5a 8 > > @ $;$;;@V@V*7')-&  6 6-2D*).& ~~%,*G#*M!N)N ??5))$LLN334GH	9+Rv. >>TF"+..G r(   c                     U R                   R                  U5        g! [        R                   aT     U R                   R	                  5         U R                   R                  U5         g! [        R
                   a      gf = ff = f)z0Safely put item in queue with overflow handling.TF)r   
put_nowaitr   Full
get_nowaitEmpty)r$   items     r%   rK   ConsoleLogger._safe_put   so    		NN%%d+zz 	))+))$/;; 	s&    B5A**B>BBBc                     U R                   (       aC   U R                  R                  SS9nUc  gU R                  U5        U R                   (       a  MB  gg! [        R
                   a     Ml  f = f)z4Background worker for streaming logs to destination.   )timeoutN)r   r   get
_write_logr   rW   )r$   log_texts     r%   r6   ConsoleLogger._stream_worker   s]    kk>>--a-8#) kkk ;; s   A A A.-A.c                     U R                   (       a]  SSKn[        R                  " 5       R	                  5       UR                  5       S.nUR                  [        U R                  5      USS9  gU R                  R                  R                  SSS9  U R                  R                  SS	S
9 nUR                  U5        SSS5        g! , (       d  f       g= f! [         a!  n[        SU 3U R                  S9   SnAgSnAff = f)z4Write log to API endpoint or local file destination.r   N)rQ   message   )jsonr\   T)parentsexist_okazutf-8)encodingzPlatform logging error: )file)r   requestsr   rI   	isoformatrH   postr   r   parentmkdiropenwriter3   printr   )r$   rL   rj   payloadfes         r%   r^   ConsoleLogger._write_log   s    	M{{(0(@(@(Btzz|\c$"2"23'1M  ''--dT-J%%**3*AQGGDM BAA 	M,QC0t7K7KL	Ms<   A-C 0>C .C	 C 	
CC C 
D$D  Dc                   .    \ rS rSrSrSrS rS rS rSr	g)	ConsoleLogger._ConsoleCapture   z"Lightweight stdout/stderr capture.originalcallbackc                     Xl         X l        g Nry   )r$   rz   r{   s      r%   r&   &ConsoleLogger._ConsoleCapture.__init__   s    $M$Mr(   c                 \    U R                   R                  U5        U R                  U5        g r}   )rz   rp   r{   )r$   rL   s     r%   rp   #ConsoleLogger._ConsoleCapture.write   s     MM%MM$r(   c                 8    U R                   R                  5         g r}   )rz   flushr=   s    r%   r   #ConsoleLogger._ConsoleCapture.flush   s    MM!r(   )r{   rz   N)
__name__
__module____qualname____firstlineno____doc__	__slots__r&   rp   r   __static_attributes__ r(   r%   r-   rw      s    0,		%	 	"r(   r-   c                   6   ^  \ rS rSrSrSrU 4S jrS rSrU =r	$ )ConsoleLogger._LogHandler   zLightweight logging handler.)r{   c                 .   > [         TU ]  5         Xl        g r}   )superr&   r{   )r$   r{   	__class__s     r%   r&   "ConsoleLogger._LogHandler.__init__   s    G$Mr(   c                 J    U R                  U R                  U5      S-   5        g )NrB   )r{   format)r$   records     r%   emitConsoleLogger._LogHandler.emit   s    MM$++f-45r(   )
r   r   r   r   r   r   r&   r   r   __classcell__)r   s   @r%   r/   r      s    *!		%	6 	6r(   r/   )r   r   r   r    r"   r!   r#   r   r   r   r   N)r   r   r   r   r   r&   r9   r>   r.   rK   r6   r^   r-   r0   Handlerr/   r   r   r(   r%   r   r      sG    B'2#&!2h	M" " 
6goo 
6r(   r   c                   0    \ rS rSrSrS rS rS rS rSr	g)	SystemLogger   u4  
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                     SSK nSU l        U R                  5       U l        UR	                  5       U l        UR                  5       U l        g)zInitialize the system logger.r   N)psutilpynvml_init_nvidianvidia_initializednet_io_counters	net_startdisk_io_counters
disk_start)r$   r   s     r%   r&   SystemLogger.__init__  s=    "&"3"3"5//1 113r(   c                      [         (       a   e[        S5        [        S5      U l        U R                  R	                  5         g! [
         a     gf = f)z-Initialize NVIDIA GPU monitoring with pynvml.znvidia-ml-py>=12.0.0r   TF)r   r   
__import__r   nvmlInitr3   r=   s    r%   r   SystemLogger._init_nvidia  sK    	u956$X.DKKK  " 		s   AA 
AAc                    SSK nUR                  5       nUR                  5       nUR                  5       n[        R
                  " S5      n[        UR                  5       S5      [        UR                  S5      [        UR                  U R                  R                  -
  S-  S5      [        UR                  U R                  R                  -
  S-  S5      [        UR                  S-  S5      S.[        UR                  U R                  R                  -
  S-  S5      [        UR                  U R                  R                  -
  S-  S5      S.0 S	.nU R                   (       a"  US
   R#                  U R%                  5       5        U$ )a  
Get current system metrics.

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

```python
metrics = {
    "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},
    },
}
```

- cpu (float): CPU usage percentage (0-100%)
- ram (float): RAM usage percentage (0-100%)
- disk (dict):
    - read_mb (float): Cumulative disk read in MB since initialization
    - write_mb (float): Cumulative disk write in MB since initialization
    - used_gb (float): Total disk space used in GB
- network (dict):
    - recv_mb (float): Cumulative network received in MB since initialization
    - sent_mb (float): Cumulative network sent in MB since initialization
- gpus (dict): GPU metrics by device index (e.g., 0, 1) containing:
    - usage (int): GPU utilization percentage (0-100%)
    - memory (float): CUDA memory usage percentage (0-100%)
    - temp (int): GPU temperature in degrees Celsius
    - power (int): GPU power consumption in watts

Returns:
    metrics (dict): System metrics containing 'cpu', 'ram', 'disk', 'network', 'gpus' with respective usage data.
r   N/   i   i   @)read_mbwrite_mbused_gb)recv_mbsent_mb)cpuramdisknetworkgpusr   )r   r   r   virtual_memoryshutil
disk_usageroundcpu_percentpercent
read_bytesr   write_bytesused
bytes_recvr   
bytes_sentr   update_get_nvidia_metrics)r$   r   netr   memoryr   metricss          r%   get_metricsSystemLogger.get_metrics  sM   L 	$$&&&(&&(&&s+
 ++-q1+ $//DOO4N4N"NSZ![]^_!4#3#3doo6Q6Q#QV]"^`ab G!<a@ !#..4>>3L3L"LQX!Y[\] #..4>>3L3L"LQX!Y[\] 
  ""FO""4#;#;#=>r(   c                    0 nU R                   (       a  U R                  (       d  U$  U R                  R                  5       n[        U5       H  nU R                  R	                  U5      nU R                  R                  U5      nU R                  R                  U5      nU R                  R                  X@R                  R                  5      nU R                  R                  U5      S-  n[        UR                  S5      [        UR                  UR                  -  S-  S5      UUS.U[        U5      '   M     U$ ! [         a     U$ f = f)zMGet NVIDIA GPU metrics including utilization, memory, temperature, and power.r   r   d   )usager   temppower)r   r   nvmlDeviceGetCountrangenvmlDeviceGetHandleByIndexnvmlDeviceGetUtilizationRatesnvmlDeviceGetMemoryInfonvmlDeviceGetTemperatureNVML_TEMPERATURE_GPUnvmlDeviceGetPowerUsager   gpur   totalr   r3   )	r$   r   device_countihandleutilr   r   r   s	            r%   r    SystemLogger._get_nvidia_metricsY  s   &&dkkK	;;99;L<(??B{{@@H<<VD{{;;FKKDdDde;;FCtK #488Q/#V[[6<<%?3$FJ "	 SV )   		s   DD? ?
EE)r   r   r   r   N)
r   r   r   r   r   r&   r   r   r   r   r   r(   r%   r   r      s    :4	@Dr(   r   __main__z&SystemLogger Real-time Metrics MonitorzPress Ctrl+C to stop
z[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.)r0   r   r   r   r4   rD   r   pathlibr   ultralytics.utilsr   r   ultralytics.utils.checksr   DEFAULT_LOG_PATHexistsunlinkr   r   r   rq   loggerr   r   itemsgpu_idgpu_datasleepKeyboardInterruptr   r(   r%   <module>r      sB      
     ) 7 $ 7?'..00t,M6 M6`J JZ z	
23	
"#^F )((*G .b) E'%..a01E'%..a01K	 :4@DEL!<T B#FGK	 :4@DEJwy1)<TB#FGJwy1)<TB#FG v&'(/(=(=(?$FH 8G+<Q*? @  ( 248 9!!)&!1! 4 5""*7"3A!6a9 )@ 67JJqM9  J  )'()s   DF% %F65F6