
    쑛h1                         d dl Z d dlZd dlZd dlZd dlmZmZ d dlmZ dddddd	d
dddddZ	dZ
dZdZedddfZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z G d d      Zd  Zd! Zd" Z	 d&d#Zd$ Zd% Zy)'    N)subputil)uses_systemddeltadescriptionelapsed
event_typeindentlevelnameoriginresult	timestamp
total_time)z%dz%Dz%Ez%ez%Iz%lz%nz%oz%rz%tz%T
successfulfailure	containerc                     t         j                         D ]9  \  }}|| v s|dv r| j                  |d|z        } %| j                  |d|z        } ;  | j                  di |S )N)r   r   r   z
{%s:08.5f}z{%s} )
format_keyitemsreplaceformat)msgeventijs       8/usr/lib/python3/dist-packages/cloudinit/analyze/show.pyformat_recordr    6   sm      " 11855kk!\A%56kk!VaZ01 3::    c                 *    | r| j                  d      S y )Nr   getr   s    r   
event_namer&   A   s    yy  r!   c                 *    | r| j                  d      S y )Nr	   r#   r%   s    r   r	   r	   G   s    yy&&r!   c                 B    | rt        |       j                  d      d   S y )N/r   )r&   splitr%   s    r   event_parentr+   M   s#    % &&s+A..r!   c                 6    t        | j                  d            S Nr   )floatr$   r%   s    r   event_timestampr/   S   s    ;'((r!   c                     t         j                   j                  t        |       t         j                  j                        S N)datetimefromtimestampr/   timezoneutcr%   s    r   event_datetimer6   W   s1    ** 1 1 5 5 r!   c                 (    || z
  j                         S r1   )total_seconds)t1t2s     r   delta_secondsr;   ]   s    G""$$r!   c                 >    t        t        |       t        |            S r1   )r;   r6   )startfinishs     r   event_durationr?   a   s    .v0FGGr!   c           	          |j                         }|j                  t        ||      t        | t	        |            ddt        |      j                  d      dz
  z  z   dz   d       |S )N| r)      z`->)r   r   r
   )copyupdater?   r;   r6   r&   count)
start_timer=   r>   records       r   event_recordrI   e   se    [[]F
MM#E62$Z1FGC:e#4#:#:3#?!#CDDuL	
 Mr!   c                     d| z  S )NzTotal Time: %3.5f seconds
r   )r   s    r   total_time_recordrK   r   s    (:55r!   c                   $    e Zd ZdZddZd Zd Zy)SystemctlReaderzQ
    Class for dealing with all systemctl subp calls in a consistent manner.
    Nc                     d | _         t        j                  d      dg| _        |r| j                  j	                  |       | j                  j                  d|dg       | j                         | _        y )N	systemctlshowz-pz--timestamp=us+utc)stdoutr   whichargsappendextendr   )selfproperty	parameters      r   __init__zSystemctlReader.__init__{   s^    ZZ,f5	IIY' 			$*>?@
 yy{r!   c                     	 t        j                   | j                  d      \  }}|r|S || _        y# t        $ r}|cY d}~S d}~ww xY w)z
        Make a subp call based on set args and handle errors by setting
        failure code

        :return: whether the subp call failed or not
        TcaptureN)r   rS   rQ   	Exception)rV   valueerrsystemctl_fails       r   r   zSystemctlReader.subp   sG    	"499d;JE3
DK 	"!!	"s   '2 2 	AAAAc                    | j                   r$t        dj                  | j                               | j                  j	                  d      d   j                         }|j                         rt        |      dz  }|S t        j                  j                  |d      j                  t        j                  j                        j                         }|S )z{
        If subp call succeeded, return the timestamp from subp as a float.

        :return: timestamp as a float
        zBSubprocess call to systemctl has failed, returning error code ({})=rC   i@B z%a %Y-%m-%d %H:%M:%S.%f %Z)tzinfo)r   RuntimeErrorr   rQ   r*   strip	isnumericr.   r2   strptimer   r4   r5   r   )rV   valr   s      r   convert_val_to_floatz$SystemctlReader.convert_val_to_float   s     <<,,2F4<<,@ 
 kk$Q'--/==? c
W,I  !!**30LM 1 1 5 56  r!   r1   )__name__
__module____qualname____doc__rY   r   ri   r   r!   r   rM   rM   v   s    #"" #r!   rM   c                      t               r
t               S t        j                         s'dt        j                         d   j                         v r
t               S t        S )a)  
    Determine which init system a particular linux distro is using.
    Each init system (systemd, etc) has a different way of
    providing timestamps.

    :return: timestamps of kernelboot, kernelendboot, and cloud-initstart
    or TIMESTAMP_UNKNOWN if the timestamps cannot be retrieved.
    gentoosystem)r   gather_timestamps_using_systemdr   
is_FreeBSDsystem_infolowergather_timestamps_using_dmesgTIMESTAMP_UNKNOWNr   r!   r   dist_check_timestamprw      sM     ~.00 H(8(8(:8(D(J(J(LL,.. r!   c                     	 t        j                   dgd      \  } }| d   j                         }|D ]  }|j                  d      j                  d      dk7  s'|j                  d      j	                         }|d   j                  d	      }t        |      }t        t        j                               t        t        j                               z
  }||z   }t        |||fc S  	 t        S # t        $ r Y t        S w xY w)
a  
    Gather timestamps that corresponds to kernel begin initialization,
    kernel finish initialization using dmesg as opposed to systemctl

    :return: the two timestamps plus a dummy timestamp to keep consistency
    with gather_timestamps_using_systemd
    dmesgTr[   r   zUTF-8userr   rC   ])r   
splitlinesdecodefindr*   re   r.   timer   uptimeSUCCESS_CODEr]   rv   )	data_split_entriesr   splitupstrippeduser_space_timestampkernel_start
kernel_ends	            r   ru   ru      s    ))WIt4aQ**, 	JAxx %%f-3((7+113"1:++C0 (-X$$TYY[1E$++-4HH),@@
 $\:zII	J"   s   AC+ B	C+ #C+ +	C<;C<c                     	 t        j                         r3t        d      j                         } t        d      j                         }n2t        d      j                         } t        d      j                         }t        d      j                         |z
  }t        dd      j                         |z
  }t        j                         rt        nt        }|| | |z   | |z   fS # t        $ r}t        |       t        cY d}~S d}~ww xY w)z
    Gather timestamps that corresponds to kernel begin initialization,
    kernel finish initialization. and cloud-init systemd unit activation

    :return: the three timesread_propertystamps
    UserspaceTimestampUserspaceTimestampMonotonicKernelTimestampKernelTimestampMonotonicInactiveExitTimestampMonotoniczcloud-init-localN)	r   is_containerrM   ri   r]   printrv   CONTAINER_CODEr   )r   monotonic_offsetr   cloudinit_sysdestatuss         r   rq   rq      s!   &!  +$""$   /- ""$  +!""$   /* ""$  -""$ 	 02D""$ 	  $002^F 	z!~%	   ! 	a  !s   B2C   	D)C?9D?Dc                    t        | d       }g }d}d}i }g }g }t        t        |            D ]}  }	| |	   }
	 | |	dz      }t	        |
      dk(  r|rE|
j                  d      dk(  r1|j                  t        |             |j                  |       g }d}d}|t        |
      }||t        |
      <   t        |
      t        |      k(  r6t	        |      d	k(  s|j                  t        |t        ||
|                   |j                  d
|
j                  d      z         |j                  |
       |j                         }t        |
      t        |      k(  rAt        |||
      }|j                  t        d|      dz          ||j                  d      z  }m|j                  |        |j                  t        |             |j                  |       |S # t        $ r d}Y w xY w)as  
    Take in raw events and create parent-child dependencies between events
    in order to order events in chronological order.

    :param events: JSONs from dump that represents events taken from logs
    :param print_format: formatting to represent event, time stamp,
    and time taken by the event in one line

    :return: boot records ordered chronologically
    c                     | d   S r-   r   )xs    r   <lambda>z"generate_records.<locals>.<lambda>?  s
    ; r!   )keyNg        rC   r=   r   z
init-localr>   zStarting stage: %szFinished stage: (%n) %d seconds
r   )sortedrangelen
IndexErrorr	   r$   rT   rK   r6   r+   r&   r    rI   pop)eventsprint_formatsorted_eventsrecordsrG   r   stage_start_timeboot_recordsunprocessedr   r   next_evtprev_evtrH   s                 r   generate_recordsr   0  s    6'?@MGJJLK3}%& ,-q		a!e}H e'599V,<0<=##G,!
 
!+E2
8B e!45 % Jx$88h'83NN%((UHE 3eii6GGH""5)"(H% Jx$88%j(EB!"CVL fjj11
 ""8,Y,-\ NN$Z01 Y  	H	s   GG,+G,c                     t        | |      S )a<  
    A passthrough method that makes it easier to call generate_records()

    :param events: JSONs from dump that represents events taken from logs
    :param print_format: formatting to represent event, time stamp,
    and time taken by the event in one line

    :return: boot records ordered chronologically
    )r   )r   )r   r   s     r   show_eventsr   z  s     F>>r!   c                    | j                         }|j                         sAt        j                  j	                  d| j
                  z         t        j                  d       	 t        j                  |      |fS # t        $ r d|fcY S w xY w)z
    Takes in a log file, read it, and convert to json.

    :param infile: The Log file to be read

    :return: json version of logfile, raw file
    zEmpty file %s
rC   N)
readre   sysstderrwriter   exitjsonloads
ValueError)infiler   s     r   load_events_infiler     sq     ;;=D::<

*V[[89zz$%% Tzs   #A: :B
	B
)z(%n) %d seconds in %I%D)r2   r   r   r   	cloudinitr   r   cloudinit.distrosr   r   r   	FAIL_CODEr   rv   r    r&   r	   r+   r/   r6   r;   r?   rI   rK   rM   rw   ru   rq   r   r   r   r   r!   r   <module>r      s      
    *, 










 	B+ )%H
6I IX,>6v +GT
?r!   