a 'Dg,+ @sddlZddlZddlZddlZddlmZmZddlmZdddddd d d d d dd Z dZ dZ dZ e dddfZ ddZddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&ZGd'd(d(Zd)d*Zd+d,Zd-d.Zd6d0d1Zd2d3Zd4d5ZdS)7N)subputil) uses_systemddelta descriptionelapsed event_typeindentlevelnameoriginresult timestamp total_time) z%dz%Dz%Ez%ez%Iz%lz%nz%oz%rz%tz%TZ successfulfailure containercCsTtD]:\}}||vr|dvr2||d|}q||d|}q|jfi|S)N)rrrz {%s:08.5f}z{%s}) format_keyitemsreplaceformat)msgeventijr:/usr/lib/python3.9/site-packages/cloudinit/analyze/show.py format_record6s rcCs|r|dSdS)Nr getrrrr event_nameAs r!cCs|r|dSdS)Nrrr rrrrGs cCs|rt|ddSdS)N/r)r!splitr rrr event_parentMsr$cCst|dSNr)floatrr rrrevent_timestampSsr'cCstjt|tjjSN)datetimeZ fromtimestampr'timezoneZutcr rrrevent_datetimeWs r+cCs ||Sr()Z total_seconds)t1t2rrr delta_seconds]sr.cCstt|t|Sr()r.r+)startfinishrrrevent_durationasr1c CsH|}|t||t|t|ddt|dddd|S)N| r"z`->)rrr )copyupdater1r.r+r!count) start_timer/r0recordrrr event_recordes r:cCsd|S)NzTotal Time: %3.5f seconds r)rrrrtotal_time_recordrsr;c@s*eZdZdZd ddZddZddZdS) SystemctlReaderzQ Class for dealing with all systemctl subp calls in a consistent manner. NcCsDd|_tddg|_|r&|j||jd|g||_dS)NZ systemctlZshowz-p)epochrwhichargsappendextendr)selfpropertyZ parameterrrr__init__{s  zSystemctlReader.__init__c CsXz*tj|jdd\}}|r |WS||_WdStyR}z|WYd}~Sd}~00dS)z Make a subp call based on set args and handle errors by setting failure code :return: whether the subp call failed or not TZcaptureN)rr?r= Exception)rBvalueerrZsystemctl_failrrrrszSystemctlReader.subpcCs2|jrtd|j|jdd}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 ({})=r4i@B)r RuntimeErrorrr=r#r&)rBrrrrparse_epoch_as_floats z$SystemctlReader.parse_epoch_as_float)N)__name__ __module__ __qualname____doc__rDrrKrrrrr<vs r<cCs2tr tSts(dtdvr.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 rUc Csztjdgdd\}}|d}|D]n}|dddkr&|d}|dd }t|}tttt }||}t |||fWSq&Wnt yYn0t 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 ZdmesgTrErzUTF-8userrr4]) r splitlinesdecodefindr#stripr&timeruptime SUCCESS_CODErFrT) data_Z split_entriesrZsplitupstrippedZuser_space_timestamp kernel_start kernel_endrrrrSs  rSc Cstttt}zBtd}tdd}|}t}trHt}||}||}Wn0t y}zt |t WYd}~Sd}~00||||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-localN) r&r\rr]r<rKr^Z is_containerCONTAINER_CODErFprintrT)rbZ delta_k_endZ delta_ci_sZ base_timestatusrcZcloudinit_sysderrrrQs$ rQ(%n) %d seconds in %I%Dc Cst|ddd}g}d}d}i}g}g}tt|D]D} || } z|| d} Wntyhd} Yn0t| dkr&|r| dd kr|t|||g}d}d}|durt| }||t | <t | t | krt| d kr$|t |t || | n |d | d|| q4q4| } t | t | krpt || | } |t d | d || d7}q4|| q4|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 cSs|dSr%r)xrrrz"generate_records..)keyNgr4r/r z init-localr0zStarting stage: %szFinished stage: (%n) %d seconds r)sortedrangelen IndexErrorrrr@r;r+r$r!rr:pop)events print_formatZ sorted_eventsZrecordsr8rZstage_start_timeZ boot_recordsZ unprocessedrgrZnext_evtZprev_evtr9rrrgenerate_recordss^         rucCs 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 )rt)ru)rsrtrrr show_eventsKs rvcCs\|}|s,tjd|jtdzt||fWSt yVd|fYS0dS)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 zEmpty file %s r4N) readr[sysstderrwriter exitjsonloads ValueError)Zinfiler_rrrload_events_infileXs  r)rh)r)r|rxr\Z cloudinitrrZcloudinit.distrosrrr^Z FAIL_CODErdrTrr!rr$r'r+r.r1r:r;r<rUrSrQrurvrrrrrsN    5# J