
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
\me.                 @   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j
dd e	j 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d0d1 Zd=d4d5Zd6d7 Z d8d9 Z!dS )>    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 c             C   s$   g | ]\}}d j |jdd|qS )z{0}: {1}%z%%)formatreplace).0kv r   /usr/lib/python3.6/show.py
<listcomp>1   s    r   Z
successfulfailureZ	container   c             C   sT   xFt j D ]:\}}|| kr
|dkr4| j|d| } q
| j|d| } q
W | jf |S )Nr   r   r   z
{%s:08.5f}z{%s})r   r   r   )
format_keyitemsr   r   )msgeventijr   r   r   format_record9   s    r"   c             C   s   | r| j dS d S )Nr   )get)r   r   r   r   
event_nameD   s    
r$   c             C   s   | r| j dS d S )Nr   )r#   )r   r   r   r   r   J   s    
c             C   s   | rt | jdd S d S )N/r   )r$   split)r   r   r   r   event_parentP   s    r'   c             C   s   t | jdS )Nr   )floatr#   )r   r   r   r   event_timestampV   s    r)   c             C   s   t j jt| S )N)datetimeZutcfromtimestampr)   )r   r   r   r   event_datetimeZ   s    r+   c             C   s   ||  j  S )N)Ztotal_seconds)Zt1Zt2r   r   r   delta_seconds^   s    r,   c             C   s   t t| t|S )N)r,   r+   )startfinishr   r   r   event_durationb   s    r/   c             C   sH   |j  }|jt||t| t|ddt|jdd   d d |S )N|r   r%   r   z`->)r   r   r	   )copyupdater/   r,   r+   r$   count)
start_timer-   r.   recordr   r   r   event_recordf   s    $r6   c             C   s   d|  S )NzTotal Time: %3.5f seconds
r   )r   r   r   r   total_time_records   s    r7   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jddg| _|r&| jj| | jjd|g | j | _d S )NZ	systemctlZshowz-p)epochr   Zwhichargsappendextendr   )selfpropertyZ	parameterr   r   r   __init__|   s    zSystemctlReader.__init__c             C   sL   y&t j | jdd\}}|r|S || _dS  tk
rF } z|S d}~X nX dS )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   r:   r9   	Exception)r=   valueerrZsystemctl_failr   r   r   r      s    zSystemctlReader.subpc             C   s2   | j rtdj| j | 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   r9   r&   r(   )r=   r   r   r   r   parse_epoch_as_float   s    	
z$SystemctlReader.parse_epoch_as_float)N)__name__
__module____qualname____doc__r?   r   rF   r   r   r   r   r8   w   s   
r8   c               C   s2   t  rt S tj s(dtj d j k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.
    Zgentoosystem)r   gather_timestamps_using_systemdr   Z
is_FreeBSDZsystem_infolowergather_timestamps_using_dmesgTIMESTAMP_UNKNOWNr   r   r   r   dist_check_timestamp   s
    
rP   c        	      C   s   yt j dgdd\} }| d j }xp|D ]h}|jdjdd	kr(|jdj }|d jd}t|}ttj ttj	  }|| }t
|||fS q(W W n tk
r   Y nX tS )
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
    ZdmesgT)r@   r   zUTF-8userr   ])r   
splitlinesdecodefindr&   stripr(   timer   uptimeSUCCESS_CODErA   rO   )	data_Zsplit_entriesr    ZsplitupstrippedZuser_space_timestampkernel_start
kernel_endr   r   r   rN      s    
rN   c        
      C   s   t tj t tj  } ytdj }tddj }| }t}tj rt tj t tj  }yt	j
d}|j} W n2 tk
r } ztdj||W Y dd}~X nX t}|| }|| }W n( tk
r }	 zt|	 tS d}	~	X nX || ||fS )z
    Gather timestamps that corresponds to kernel begin initialization,
    kernel finish initialization. and cloud-init systemd unit activation

    :return: the three timestamps
    ZUserspaceTimestampMonotonicZInactiveExitTimestampMonotoniczcloud-init-localz/proc/1/cmdlinezBCould not determine container boot time from /proc/1/cmdline. ({})N)r(   rX   r   rY   r8   rF   rZ   Zis_containerZ	monotonicosstatst_atimeOSErrorrE   r   CONTAINER_CODErA   printrO   )
r^   Zdelta_k_endZ
delta_ci_sZ	base_timeZstatusZ	file_statrC   r_   Zcloudinit_sysder   r   r   rL      s2    


rL   F(%n) %d seconds in %I%Dc             C   s  t | dd d}g }d}d}i }	g }
g }xZtdt|D ]F}| | }y| |d  }W n tk
rp   d}Y nX t|dkr.|r|jd	d
kr|jt| |
j| g }d}d}|dkrt|}||	t	|< t
|t
|krt|dkr,|jt|t||| n |jd|jd	  |j| q:q:|j }t
|t
|krxt|||}|jtd|d  ||jd7 }q:|j| q:W |jt| |
j| |
S )a2  
    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 blame_sort: whether to sort by timestamp or by time taken.
    :param print_format: formatting to represent event, time stamp,
    and time taken by the event in one line
    :param dump_files: whether to dump files into JSONs
    :param log_datafiles: whether or not to log events generated

    :return: boot records ordered chronologically
    c             S   s   | d S )Nr   r   )xr   r   r   <lambda>$  s    z"generate_records.<locals>.<lambda>)keyNg        r   r   r-   r   z
init-localr.   zStarting stage: %szFinished stage: (%n) %d seconds
r   )sortedrangelen
IndexErrorr   r#   r;   r7   r+   r'   r$   r"   r6   pop)eventsZ
blame_sortprint_formatZ
dump_filesZlog_datafilesZsorted_eventsZrecordsr4   r   Zstage_start_timeZboot_recordsZunprocessedrf   r   Znext_evtZprev_evtr5   r   r   r   generate_records  sV    



rs   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
    )rr   )rs   )rq   rr   r   r   r   show_events_  s    
rt   c             C   s4   | j  }ytj||fS  tk
r.   d|fS X dS )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
    N)readjsonloads
ValueError)Zinfiler[   r   r   r   load_events_infilel  s
    ry   rS   rS   rS   )Frg   FF)"r*   rv   r`   rX   Z	cloudinitr   r   Zcloudinit.distrosr   r   joinr   Zformatting_helprZ   Z	FAIL_CODErd   rO   r"   r$   r   r'   r)   r+   r,   r/   r6   r7   r8   rP   rN   rL   rs   rt   ry   r   r   r   r   <module>   sT   50   
K