o
    x[h,+  ã                   @   s  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d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ ZG d'd(„ d(ƒZd)d*„ Zd+d,„ Zd-d.„ Z	/d6d0d1„Zd2d3„ Zd4d5„ ZdS )7é    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Ú	containeréÿÿÿÿc                 C   sT   t  ¡ D ]\}}|| v r!|dv r|  |d| ¡} q|  |d| ¡} q| jdi |¤ŽS )N)r   r   r   z
{%s:08.5f}z{%s}© )Ú
format_keyÚitemsÚreplaceÚformat)ÚmsgÚeventÚiÚjr   r   ú8/usr/lib/python3/dist-packages/cloudinit/analyze/show.pyÚformat_record6   s   €r   c                 C   ó   | r|   d¡S d S )Nr   ©Úget©r   r   r   r   Ú
event_nameA   ó   
r#   c                 C   r   )Nr   r    r"   r   r   r   r   G   r$   c                 C   s   | rt | ƒ d¡d S d S )Nú/r   )r#   Úsplitr"   r   r   r   Úevent_parentM   s   r'   c                 C   s   t |  d¡ƒS ©Nr   )Úfloatr!   r"   r   r   r   Úevent_timestampS   s   r*   c                 C   s   t j  t| ƒt jj¡S ©N)ÚdatetimeÚfromtimestampr*   ÚtimezoneÚutcr"   r   r   r   Úevent_datetimeW   s   ÿr0   c                 C   s   ||    ¡ S r+   )Útotal_seconds)Út1Út2r   r   r   Údelta_seconds]   s   r4   c                 C   s   t t| ƒt|ƒƒS r+   )r4   r0   )ÚstartÚfinishr   r   r   Úevent_durationa   s   r7   c              	   C   sH   |  ¡ }| t||ƒt| t|ƒƒddt|ƒ d¡d   d dœ¡ |S )Nú|ú r%   é   z`->)r   r   r	   )ÚcopyÚupdater7   r4   r0   r#   Úcount)Ú
start_timer5   r6   Úrecordr   r   r   Úevent_recorde   s   ýÿr@   c                 C   s   d|  S )NzTotal Time: %3.5f seconds
r   )r   r   r   r   Útotal_time_recordr   s   rA   c                   @   s*   e Zd ZdZd	dd„Zdd„ Zdd„ ZdS )
ÚSystemctlReaderzQ
    Class for dealing with all systemctl subp calls in a consistent manner.
    Nc                 C   sD   d | _ t d¡dg| _|r| j |¡ | j d|g¡ |  ¡ | _d S )NÚ	systemctlÚshowz-p)Úepochr   ÚwhichÚargsÚappendÚextendr   )ÚselfÚpropertyÚ	parameterr   r   r   Ú__init__{   s   zSystemctlReader.__init__c              
   C   sT   zt j | jdd�\}}|r|W S || _W dS  ty) } z|W  Y d}~S d}~w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   rG   rE   Ú	Exception)rJ   ÚvalueÚerrÚsystemctl_failr   r   r   r   †   s   €ÿzSystemctlReader.subpc                 C   s2   | j rtd | j ¡ƒ‚| j d¡d }t|ƒd 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 ({})ú=r:   i@B )r   ÚRuntimeErrorr   rE   r&   r)   )rJ   r   r   r   r   Úparse_epoch_as_float–   s   	þz$SystemctlReader.parse_epoch_as_floatr+   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rM   r   rV   r   r   r   r   rB   v   s
    
rB   c                   C   s2   t ƒ rtƒ S t ¡ sdt ¡ d  ¡ 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   r   Údist_check_timestamp«   s
   
rc   c            	      C   s°   zMt j dgdd�\} }| d  ¡ }|D ]7}| d¡ d¡dkrJ| d¡ ¡ }|d  d	¡}t|ƒ}tt ¡ ƒtt 	¡ ƒ }|| }t
|||f  W S qW tS  tyW   Y tS 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
    ÚdmesgTrN   r   zUTF-8Úuserr   r:   ú])r   Ú
splitlinesÚdecodeÚfindr&   Ústripr)   Útimer   ÚuptimeÚSUCCESS_CODErP   rb   )	ÚdataÚ_Úsplit_entriesr   ÚsplitupÚstrippedÚuser_space_timestampÚkernel_startÚ
kernel_endr   r   r   ra   Á   s$   ôÿþþra   c               
   C   s˜   t t ¡ ƒt t ¡ ƒ } z!tdƒ ¡ }tddƒ ¡ }| }t}t ¡ r$t}|| }|| }W n t	yE } zt
|ƒ tW  Y d}~S d}~ww || ||fS )z¸
    Gather timestamps that corresponds to kernel begin initialization,
    kernel finish initialization. and cloud-init systemd unit activation

    :return: the three timestamps
    ÚUserspaceTimestampMonotonicÚInactiveExitTimestampMonotoniczcloud-init-localN)r)   rk   r   rl   rB   rV   rm   Úis_containerÚCONTAINER_CODErP   Úprintrb   )rt   Údelta_k_endÚ
delta_ci_sÚ	base_timeÚstatusru   Úcloudinit_sysdÚer   r   r   r]   à   s0   ÿþÿþ€ûr]   ú(%n) %d seconds in %I%Dc              	   C   sŒ  t | dd„ d�}g }d}d}i }g }g }tt|ƒƒD ]�}	| |	 }
z| |	d  }W n ty3   d}Y nw t|
ƒdkrŽ|rU|
 d¡d	krU| t|ƒ¡ | |¡ g }d}d}|du rct|
ƒ}||t	|
ƒ< t
|
ƒt
|ƒkr~t|ƒd
kr}| t|t||
|ƒƒ¡ q| d|
 d¡ ¡ | |
¡ q| ¡ }t
|
ƒt
|ƒkr²t|||
ƒ}| td|ƒd ¡ || d¡7 }q| |¡ q| t|ƒ¡ | |¡ |S )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                 S   s   | d S r(   r   )Úxr   r   r   Ú<lambda>  s    z"generate_records.<locals>.<lambda>)ÚkeyNg        r:   r5   r   z
init-localr6   zStarting stage: %szFinished stage: (%n) %d secondsÚ
r   )ÚsortedÚrangeÚlenÚ
IndexErrorr   r!   rH   rA   r0   r'   r#   r   r@   Úpop)ÚeventsÚprint_formatÚsorted_eventsÚrecordsr>   r   Ústage_start_timeÚboot_recordsÚunprocessedr€   r   Únext_evtÚprev_evtr?   r   r   r   Úgenerate_records  sb   ÿ

þÿ€
ÿÿ
r”   c                 C   s   t | |d�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Œ   r   r   r   Úshow_eventsK  s   
r•   c                 C   sX   |   ¡ }| ¡ stj d| j ¡ t d¡ zt |¡|fW S  t	y+   d|f Y S 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
r:   N)
Úreadrj   ÚsysÚstderrÚwriter   ÚexitÚjsonÚloadsÚ
ValueError)Úinfilern   r   r   r   Úload_events_infileX  s   
ÿrŸ   )r�   )r,   r›   r—   rk   Ú	cloudinitr   r   Úcloudinit.distrosr   r   rm   Ú	FAIL_CODEry   rb   r   r#   r   r'   r*   r0   r4   r7   r@   rA   rB   rc   ra   r]   r”   r•   rŸ   r   r   r   r   Ú<module>   sP   õ5#
þJ