o
    th&                  	   @   s\  d dl Z d dlZd dlZd dlmZmZ d dlmZmZmZm	Z	m
Z
mZ d dlmZmZ d dlmZ 	dde	e j de jfdd	Zd
ede jdefddZde jddfddZde jddfddZde jddfddZdedeeeeeef f  fddZde jde
eef fddZdeddfddZedkre Ze Z e j!\Z"Z#e#e"e  dS dS )    N)datetimetimezone)IODictListOptionalTupleUnion)dumpshow)
json_dumpsparserreturnc                 C   sh  | s	t jddd} | jddd}d|_|jdd	d
}|jddddddd |jddddddd |jdtfd |jddd
}|jddddddd |jddddddd |jddddddd |jdtfd |jd d!d
}|jdddddd"d |jddddddd |jd t	fd |jd#d$d
}|jdddddd"d |jddddddd |jd#t
fd | S )%Nzcloudinit-analyzez,Devel tool: Analyze cloud-init logs and data)progdescriptionSubcommands
subcommand)titledestTblamez5Print list of executed stages ordered by time to init)helpz-iz--infilestoreinfilez/var/log/cloud-init.logzspecify where to read input.)actionr   defaultr   z-oz	--outfileoutfile-zspecify where to write output. )r   r   z.Print list of in-order events during executionz-fz--formatprint_formatz%I%D @%Es +%dszspecify formatting of output.zspecify where to write output.r
   z%Dump cloud-init events in JSON formatzspecify where to read input. bootz2Print list of boot times for kernel and cloud-init)argparseArgumentParseradd_subparsersrequired
add_parseradd_argumentset_defaultsanalyze_blameanalyze_showanalyze_dumpanalyze_boot)r   
subparsersparser_blameparser_showparser_dumpparser_boot r/   </usr/lib/python3/dist-packages/cloudinit/analyze/__init__.py
get_parser   s   r1   nameargsc              
   C   s
  t |\}}t }|\}}}}t|tj}	t|tj}
t|tj}zdd t|D d }tt|d tj}W n t	yK   d}tj
}Y nw d}d}d}tj
|tj|tj|i}|| }|| }|	|
|||||||d		}||| jdi | t|| |S )a  Report a list of how long different boot operations took.

    For Example:
    -- Most Recent Boot Record --
        Kernel Started at: <time>
        Kernel ended boot at: <time>
        Kernel time to boot (seconds): <time>
        Cloud-init activated by systemd at: <time>
        Time between Kernel end boot and Cloud-init activation (seconds):<time>
        Cloud-init start: <time>
    c                 S   s,   g | ]}|d  dkrdt |d v r|qS )r2   z
init-localzstarting searchr   )str).0er/   r/   r0   
<listcomp>   s    z analyze_boot.<locals>.<listcomp>	timestampz4Could not find init-local log-line in cloud-init.logzYour Linux distro or container does not support this functionality.
You must be running a Kernel Telemetry supported distro.
Please check https://docs.cloud-init.io/en/latest/topics/analyze.html for more information on supported distros.
a*  -- Most Recent Boot Record --
    Kernel Started at: {k_s_t}
    Kernel ended boot at: {k_e_t}
    Kernel time to boot (seconds): {k_r}
    Cloud-init activated by systemd at: {ci_sysd_t}
    Time between Kernel end boot and Cloud-init activation (seconds): {bt_r}
    Cloud-init start: {ci_start}
z-- Most Recent Container Boot Record --
    Container started at: {k_s_t}
    Cloud-init activated by systemd at: {ci_sysd_t}
    Cloud-init start: {ci_start}
)	k_s_tk_e_tk_rbt_rk_ek_sci_sysd	ci_sysd_tci_startNr/   )configure_ior   dist_check_timestampr   fromtimestampr   utc_get_eventsfloat
IndexError	FAIL_CODECONTAINER_CODESUCCESS_CODEwriteformatclean_io)r2   r3   infhoutfhkernel_infostatus_codekernel_start
kernel_endci_sysd_startkernel_start_timestampkernel_end_timestampci_sysd_start_timestamplast_init_localrB   FAILURE_MSGSUCCESS_MSGCONTAINER_MSG
status_mapkernel_runtimebetween_process_runtimekwargsr/   r/   r0   r)   v   s\   

r)   c           	      C   s   t |\}}d}tdtj}d}ttt||D ]&\}}tt	|j
|dd}|d|d   |d|d  |d q|d	|d   t|| d
S )az  Report a list of records sorted by largest time delta.

    For example:
      30.210s (init-local) searching for datasource
       8.706s (init-network) reading and applying user-data
        166ms (modules-config) ....
        807us (modules-final) ...

    We generate event records parsing cloud-init logs, formatting the output
    and sorting by record data ('delta')
    z     %ds (%n)z(^\s+\d+\.\d+)r   T)reverse-- Boot Record %02d --
   
%d boot records analyzed
N)rC   recompile	MULTILINE	enumerater   show_eventsrG   sortedfiltermatchrM   joinrO   )	r2   r3   rP   rQ   blame_formatridxrecordsrecsr/   r/   r0   r&      s   r&   c                 C   s   t |\}}ttt||jD ]!\}}|d|d   |d |d |d|d  q|d|d   t|| dS )a  Generate output records using the 'standard' format to printing events.

    Example output follows:
        Starting stage: (init-local)
          ...
        Finished stage: (init-local) 0.105195 seconds

        Starting stage: (init-network)
          ...
        Finished stage: (init-network) 0.339024 seconds

        Starting stage: (modules-config)
          ...
        Finished stage: (modules-config) 0.NNN seconds

        Starting stage: (modules-final)
          ...
        Finished stage: (modules-final) 0.NNN seconds
    rc   rd   zUThe total time elapsed since completing an event is printed after the "@" character.
z>The time the event takes is printed after the "+" character.

re   rf   N)	rC   rj   r   rk   rG   r   rM   ro   rO   )r2   r3   rP   rQ   rr   rs   r/   r/   r0   r'      s   r'   c                 C   s0   t |\}}|tt|d  t|| dS )z%Dump cloud-init events in json formatre   N)rC   rM   r   rG   rO   )r2   r3   rP   rQ   r/   r/   r0   r(     s   r(   r   c                 C   s*   d }t | \}}|stj|d\}}|S )N)rawdata)r   load_events_infiler
   dump_events)r   ru   events_r/   r/   r0   rG     s
   rG   c                 C   s   | j dkr	tj}n zt| j d}W n ty(   tjd| j   td Y nw | jdkr5tj	}||fS zt| jd}W ||fS  tyZ   tjd| j  td Y ||fS w )z.Common parsing and setup of input/output filesr   rq   zCannot open file %s
rd   w)
r   sysstdinopenOSErrorstderrrM   exitr   stdout)r3   rP   rQ   r/   r/   r0   rC     s&   

rC   file_handlesc                  G   s(   | D ]}|t jt jfv rq|  qdS )zclose filehandlesN)r{   r|   r   close)r   file_handler/   r/   r0   rO   3  s
   
rO   __main__)N)$r   rg   r{   r   r   typingr   r   r   r   r   r	   cloudinit.analyzer
   r   cloudinit.atomic_helperr   r    r1   r4   	Namespacer)   r&   r'   r(   rH   rG   rC   rO   __name__r   
parse_argsr3   r   r2   action_functorr/   r/   r/   r0   <module>   s4    
gW%&
