U
    JcW                     @   s   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 d dl	m
Z
mZmZ ddgZe eZeeeeedd	dZG d
d dZdS )    N)Future)ThreadPoolExecutorEvent)DictListTextIOtail_logfileTailLogheaderfiledstfinishedinterval_secc              	   C   sv   t j|s$| rd S t| q t|d>}| }|rP||  |  q0| r\qhq0t| q0W 5 Q R X d S )Nr)	ospathexistsis_settimesleepopenreadlinewrite)r   r   r   r   r   fpline r   V/tmp/pip-unpacked-wheel-gikjz4vx/torch/distributed/elastic/multiprocessing/tail_log.pyr	      s    c                   @   sX   e Zd ZdZdeeeef eedddZ	d dddZ
d	dd
dZedddZd	S )r
   a8  
    Tails the given log files. The log files do not have to exist when the
    ``start()`` method is called. The tail-er will gracefully wait until the
    log files are created by the producer and will tail the contents of the
    log files until the ``stop()`` method is called.

    .. warning:: ``TailLog`` will wait indefinitely for the log file to be created!

    Each log file's line will be suffixed with a header of the form: ``[{name}{idx}]:``,
    where the ``name`` is user-provided and ``idx`` is the index of the log file
    in the ``log_files`` mapping.

    Usage:

    ::

     log_files = {0: "/tmp/0_stdout.log", 1: "/tmp/1_stdout.log"}
     tailer = TailLog("trainer", log_files, sys.stdout).start()
     # actually run the trainers to produce 0_stdout.log and 1_stdout.log
     run_trainers()
     tailer.stop()

     # once run_trainers() start writing the ##_stdout.log files
     # the tailer will print to sys.stdout:
     # >>> [trainer0]:log_line1
     # >>> [trainer1]:log_line1
     # >>> [trainer0]:log_line2
     # >>> [trainer0]:log_line3
     # >>> [trainer1]:log_line2

    .. note:: Due to buffering log lines between files may not necessarily
              be printed out in order. You should configure your application's
              logger to suffix each log line with a proper timestamp.

    皙?)name	log_filesr   r   c                 C   sn   t |}d | _|dkr2t|| jj d| d| _|| _|| _|| _dd | D | _	g | _
|| _d| _d S )Nr   _)max_workersZthread_name_prefixc                 S   s   i | ]}|t  qS r   r   ).0
local_rankr   r   r   
<dictcomp>f   s     z$TailLog.__init__.<locals>.<dictcomp>F)len_threadpoolr   	__class____qualname___name_dst
_log_fileskeys_finished_events_futs_interval_sec_stopped)selfr    r!   r   r   nr   r   r   __init__T   s     zTailLog.__init__)returnc                 C   sZ   | j s
| S | j D ]@\}}| j| j jtd| j | d|| j| j	| | j
d q| S )N[z]:r   )r(   r-   itemsr0   appendZsubmitr	   r+   r,   r/   r1   )r3   r%   r   r   r   r   startm   s    
zTailLog.startNc                 C   s   | j  D ]}|  q
t| jD ]^\}}z|  W q" tk
r~ } z*td| j	 | d|j
j d|  W 5 d }~X Y q"X q"| jr| jjdd d| _d S )Nzerror in log tailor for z. z: T)wait)r/   valuesset	enumerater0   result	Exceptionlogerrorr+   r)   r*   r(   shutdownr2   )r3   r   r%   fer   r   r   stop~   s    
zTailLog.stopc                 C   s   | j S )N)r2   )r3   r   r   r   stopped   s    zTailLog.stopped)r   )__name__
__module__r*   __doc__strr   intr   floatr5   r:   rF   boolrG   r   r   r   r   r
   /   s   ) 
)loggingr   r   Zconcurrent.futures._baser   Zconcurrent.futures.threadr   	threadingr   typingr   r   r   __all__	getLoggerrH   rA   rK   rM   r	   r
   r   r   r   r   <module>	   s   
    