3 \me. @sddlZddlZddlZddlZddlmZmZddlmZdddddd d d d d dd Z dj dde j DZ dZ dZdZed:d;dN)subputil) uses_systemddelta descriptionelapsed event_typeindentlevelnameoriginresult timestamp total_time) z%dz%Dz%Ez%ez%Iz%lz%nz%oz%rz%tz%T cCs$g|]\}}dj|jdd|qS)z{0}: {1}%z%%)formatreplace).0kvr/usr/lib/python3.6/show.py 1srZ successfulfailureZ containercCsTxFtjD]:\}}||kr |dkr4|j|d|}q |j|d|}q W|jf|S)Nrrrz {%s:08.5f}z{%s})rrr) format_keyitemsrr)msgeventijrrr format_record9s r"cCs|r|jdSdS)Nr )get)rrrr event_nameDs r$cCs|r|jdSdS)Nr)r#)rrrrrJs cCs|rt|jddSdS)N/r)r$split)rrrr event_parentPsr'cCst|jdS)Nr)floatr#)rrrrevent_timestampVsr)cCstjjt|S)N)datetimeZutcfromtimestampr))rrrrevent_datetimeZsr+cCs ||jS)N)Z total_seconds)Zt1Zt2rrr delta_seconds^sr,cCstt|t|S)N)r,r+)startfinishrrrevent_durationbsr/cCsH|j}|jt||t|t|ddt|jdddd|S)N|rr%rz`->)rrr )copyupdater/r,r+r$count) start_timer-r.recordrrr event_recordfs  $r6cCsd|S)NzTotal Time: %3.5f seconds r)rrrrtotal_time_recordssr7c@s*eZdZdZd ddZddZddZdS) SystemctlReaderzQ Class for dealing with all systemctl subp calls in a consistent manner. NcCsDd|_tjddg|_|r&|jj||jjd|g|j|_dS)NZ systemctlZshowz-p)epochrZwhichargsappendextendr)selfpropertyZ parameterrrr__init__|s  zSystemctlReader.__init__cCsLy&tj|jdd\}}|r|S||_dStk rF}z|Sd}~XnXdS)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)rr:r9 Exception)r=valueerrZsystemctl_failrrrrszSystemctlReader.subpcCs2|jrtdj|j|jjdd}t|dS)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 ({})=ri@B)r RuntimeErrorrr9r&r()r=rrrrparse_epoch_as_floats  z$SystemctlReader.parse_epoch_as_float)N)__name__ __module__ __qualname____doc__r?rrFrrrrr8ws r8cCs2tr tStjs(dtjdjkr.tStS)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. Zgentoosystem)rgather_timestamps_using_systemdrZ is_FreeBSDZ system_infolowergather_timestamps_using_dmesgTIMESTAMP_UNKNOWNrrrrdist_check_timestamps rPc Csytjdgdd\}}|dj}xp|D]h}|jdjdd kr(|jdj}|djd}t|}ttjttj }||}t |||fSq(WWnt k rYnXt 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 ZdmesgT)r@rzUTF-8userr]) r splitlinesdecodefindr&stripr(timeruptime SUCCESS_CODErArO) data_Z split_entriesr ZsplitupstrippedZuser_space_timestamp kernel_start kernel_endrrrrNs  rNc Csttjttj}ytdj}tddj}|}t}tjrttjttj}yt j d}|j }Wn2t k r}zt dj||WYdd}~XnXt}||}||}Wn(tk r} z t| tSd} ~ XnX||||fS)z Gather timestamps that corresponds to kernel begin initialization, kernel finish initialization. and cloud-init systemd unit activation :return: the three timestamps ZUserspaceTimestampMonotonicZInactiveExitTimestampMonotoniczcloud-init-localz/proc/1/cmdlinezBCould not determine container boot time from /proc/1/cmdline. ({})N)r(rXrrYr8rFrZZ is_containerZ monotonicosstatst_atimeOSErrorrErCONTAINER_CODErAprintrO) r^Z delta_k_endZ delta_ci_sZ base_timeZstatusZ file_statrCr_Zcloudinit_sysderrrrLs2     rLF(%n) %d seconds in %I%DcCst|ddd}g}d}d}i} g} g} xZtdt|D]F} || } y|| d}Wntk rpd}YnXt| dkr.|r| jd d kr|jt|| j|g}d}d}|dkrt| }|| t | <t | t |kr t|d kr,|jt |t || |n |jd | jd | j| q:q:| j }t | t |krxt ||| }|jt d |d||jd7}q:| j|q:W|jt|| 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 cSs|dS)Nrr)xrrr$sz"generate_records..)keyNgrrr-r z init-localr.zStarting stage: %szFinished stage: (%n) %d seconds r)sortedrangelen IndexErrorrr#r;r7r+r'r$r"r6pop)eventsZ blame_sort print_formatZ dump_filesZ log_datafilesZ sorted_eventsZrecordsr4rZstage_start_timeZ boot_recordsZ unprocessedrfrZnext_evtZprev_evtr5rrrgenerate_recordssV      rscCs t||dS)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)rqrrrrr show_events_s rtc Cs4|j}ytj||fStk r.d|fSXdS)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)readjsonloads ValueError)Zinfiler[rrrload_events_infilels ryrSrSrS)FrgFF)"r*rvr`rXZ cloudinitrrZcloudinit.distrosrrjoinrZformatting_helprZZ FAIL_CODErdrOr"r$rr'r)r+r,r/r6r7r8rPrNrLrsrtryrrrrsT    50 K