
    d8p                     X   d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmc m	Z	 d dl
mZ d dlmZmZ d dlmZmZmZmZ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lm Z  d d	l!m"Z"m#Z#m$Z$m%Z% d d
l&m'Z' d dl(m)Z) d dl*m+Z+ d Z, G d de-      Z. G d de+      Z/ G d de+      Z0 G d de       Z1y)    N)defaultdict)conf)get_supported_feature_by_nameSupportedFeatureNames)
EVENTS_DIRECTORYTELEMETRY_LOG_EVENT_IDTELEMETRY_LOG_PROVIDER_ID	add_eventWALAEventOperationadd_log_eventget_event_loggerCollectOrReportEventDebugInfoEVENT_FILE_REGEXparse_event)InvalidExtensionEventErrorServiceStoppedError)ustr)ThreadHandlerInterface)TelemetryEventTelemetryEventParamGuestAgentGenericLogsSchemaGuestAgentExtensionEventsSchema)textutil)HANDLER_NAME_PATTERN)PeriodicOperationc                     t        |       S N)CollectTelemetryEventsHandler)send_telemetry_events_handlers    M/usr/lib/python3/dist-packages/azurelinuxagent/ga/collect_telemetry_events.py$get_collect_telemetry_events_handlerr!   *   s    ()FGG    c                   0    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zy
)ExtensionEventSchemaa  
    Class for defining the schema for Extension Events.

    Sample Extension Event Example:
        {
           "Version":"1.0.0.23",
           "Timestamp":"2018-01-02T22:08:12.510696Z"    //(time in UTC (ISO-8601 standard),
           "TaskName":"TestRun"                         //Open for publishers,
           "EventLevel":"Critical/Error/Warning/Verbose/Informational/LogAlways",
           "Message": "Successful test"                //(max 3K, 3072 characters),
           "EventPid":"1",
           "EventTid":"2",
           "OperationId":"Guid (str)"
        }

    From next version(2.10+) we accept integer values for EventPid and EventTid fields. But we still support string type for backward compatability
    Version	TimestampTaskName
EventLevelMessageEventPidEventTidOperationIdN)__name__
__module____qualname____doc__r%   r&   r'   r(   r)   r*   r+   r,    r"   r    r$   r$   .   s1    " GIHJGHHKr"   r$   c                      e Zd ZdZ ej
                   ej                               Z e	j                  de	j                        ZdZdZdZdZ ee      D  cg c]<  }t'        t)        t$        |            s!|j+                  d      s|j-                         > c}}}}} Zfd	Zd
 Zed        Zd Zd Zed        Zd Zd Z d Z!ed        Z"xZ#S c c}}}}} w )_ProcessExtensionEventsz
    Periodic operation for collecting extension telemetry events and enqueueing them for the SendTelemetryHandler thread.
    )secondsz^(\d+)\.json$ih  i  @ i   i   __c                 V    t         t        |   t        j                         || _        y r   )superr3   __init__"_EXTENSION_EVENT_COLLECTION_PERIOD_send_telemetry_events_handlerselfr   	__class__s     r    r8   z _ProcessExtensionEvents.__init__[   s"    %t56M6p6pq.K+r"   c                    | j                   j                         r=t        j                  dj	                  | j                   j                                      y d}g }	 | j                  t        j                               }|s+t        j                  d       	 |r| j                  |       y y |D ]  }|d   }|d   }| j                  ||         	 |r| j                  |       y y # t        $ r d}Y "t        $ rJ}dj	                  t        j                  |            }t!        t"        j$                  |d       Y d }~od }~ww xY w# |r| j                  |       w w xY w)	Nz6{0} service is not running, skipping current iterationTz#No Extension events directory existr      FzBUnknown error occurred when trying to collect extension events:{0}opmessage
is_success)r:   stoppedloggerwarnformatget_thread_name+_get_extension_events_dir_with_handler_namer   get_ext_log_dirverbose$_ensure_all_events_directories_empty_capture_extension_eventsr   	Exceptionr   format_exceptionr
   r   !ExtensionTelemetryEventProcessing)r<   delete_all_event_files!extension_handler_with_event_dirs extension_handler_with_event_dirhandler_namehandler_event_dir_patherrormsgs           r    
_operationz"_ProcessExtensionEvents._operation_   sf   ..668KKPWW33CCEG H!%,.)	]040`0`aeauauaw0x-4DE" &99:[\ & 5V U0?B)I!)L&..|=STU &99:[\ & # 	+ &+" 	nV]]))%02C+MMWZglmm	n &99:[\ &sC   :C& -#C& E &E1E 3E;A E ;E  EE Ec                    g }t        j                  |       D ]  }t         j                  j                  t         j                  j	                  | |            rt        j                  t        |      [t         j                  j	                  | |t              }t         j                  j                  |      s|j                  ||f        |S )z
        Get the full path to events directory for all extension handlers that have one
        :param extension_log_dir: Base log directory for all extensions
        :return: A list of full paths of existing events directory for all handlers
        )oslistdirpathisdirjoinrematchr   r   existsappend)extension_log_dirrR   ext_handler_nameextension_event_dirs       r    rI   zC_ProcessExtensionEvents._get_extension_events_dir_with_handler_name   s     -/) "

+< = 		b77==.?AQ!RSxx 46FGO #%'',,/@BRTd"eww~~12188:JL_9`a		b 10r"   c                 0   t        j                  |      j                  }|| j                  kD  rhd }dj	                  | ||       || j                              }t        j                  |       t        t
        j                  j                  |d       yy)Nc                     d| z  dz  S )Ng      ?i@B r1   )xs    r    <lambda>zB_ProcessExtensionEvents._event_file_size_allowed.<locals>.<lambda>   s    sQw;&? r"   zJSkipping file: {0} as its size is {1:.2f} Mb > Max size allowed {2:.1f} MbTlevelrB   forcedF)
rZ   statst_size_EXTENSION_EVENT_FILE_MAX_SIZErG   rE   rF   r   LogLevelWARNING)r<   event_file_pathevent_file_sizeconvert_to_mbrW   s        r    _event_file_size_allowedz0_ProcessExtensionEvents._event_file_size_allowed   s|    ''/2::T@@@?M^ee!?dAABDC KK 7 7TRr"   c                 :   t        j                  |      D cg c]$  }t        j                  | j                  |      |& }}|j                  d       d}t        t              }	 |D ]
  }t         j                  j                  ||      }	 t        j                  d|       | j                  |      s	 t        j                  |       c| j                  ||||      }|| j                  k\  rodj!                  || j                        }t        j"                  |       t%        t        j&                  j(                  |d       	 t        j                  |        n	 t        j                  |        |rd	j!                  |d
j                  |j3                         D 
cg c]  \  }
}dj!                  |
|       c}}
            }t        j"                  |       t%        t        j&                  j(                  |d       |dkD  r&t        j4                  dj!                  ||             yyc c}w # t*        $ r  t,        $ rk}	dj!                  |t/        j0                  |	            }t        j"                  |       t%        t        j&                  j(                  |d       Y d}	~	Pd}	~	ww xY w# t        j                  |       w xY wc c}}
w # |rd	j!                  |d
j                  |j3                         D 
cg c]  \  }
}dj!                  |
|       nc c}}
w c}}
            }t        j"                  |       t%        t        j&                  j(                  |d       |dkD  r&t        j4                  dj!                  ||             w w xY w)a  
        Capture Extension events and add them to the events_list
        :param handler_name: Complete Handler Name. Eg: Microsoft.CPlat.Core.RunCommandLinux
        :param handler_event_dir_path: Full path. Eg: '/var/log/azure/Microsoft.CPlat.Core.RunCommandLinux/events'
        NT)reverser   Processing event file: {0}zLReached max count for the extension: {0}; Max Limit: {1}. Skipping the rest.rj   z$Failed to process event file {0}:{1}z0Dropped events for Extension: {0}; Details:
	{1}z
	zReason: {0}; Dropped Count: {1}z'Collected {0} events for extension: {1})rZ   r[   r_   r`    _EXTENSION_EVENT_FILE_NAME_REGEXsortr   intr\   r^   rE   rK   ru   remove_enqueue_events_and_get_count._MAX_NUMBER_OF_EVENTS_PER_EXTENSION_PER_PERIODrG   rF   r   rp   rq   r   rN   r   rO   itemsinfo)r<   rT   rU   
event_fileevent_filescaptured_extension_events_countdropped_events_with_error_countrr   rW   rV   kvs               r    rM   z1_ProcessExtensionEvents._capture_extension_events   s     57JJ?U4V `jxx E EzR^ " ` ` 	&*+'*5c*:'.	}) #/
"$'',,/Ez"R /NN#?Q88I 8 IIo.3 7;6X6XYegvYxYx7z3
 7$:m:mmlss($*]*]_C(%FOO,C,CSY]^ IIo.) n( IIo.G#/L /JQQR^`f`k`kPoPuPuPwx16==aCxaz {C FOO$;$;SQUV.2ELLMlnz{| 3k`< +    [@GG
NVNgNghmNnpCKK$!(?(?UYZZ	[ IIo.
 y /JQQR^`f`k`kPoPuPuPwx16==aCxxaz {C FOO$;$;SQUV.2ELLMlnz{| 3st   )H2'&K 'H76K A:H7K J7K #K7J4	A J/)J7/J44J77KK -NL! A:Nc           
      x   | sy | D ]x  }|d   }t         j                  j                  |      s y d}t        j                  |      D ]6  }	 t        j                  t         j                  j                  ||             8 z y # t        $ r.}|r"t        j                  d|t        |             d}Y d }~nd }~ww xY w)Nr?   Tz<Failed to completely clear the {0} directory. Exception: {1}F)
rZ   r\   ra   r[   r|   r^   rN   rE   rV   r   )extension_events_directoriesrS   event_dir_pathlog_errresidue_filerV   s         r    rL   z<_ProcessExtensionEvents._ensure_all_events_directories_empty   s    +0L 	(,=a@N77>>.1G "

> : ((IIbggll><HI(	( ! (%ces%)%[2"'(s   
3B	B9$B44B9c           	         t         j                   j                  t        j                  j	                  |            }t        |d      5 }|j                         j                  d      }d d d        t        j                        }t        |t              s|g}|D ]F  }		 | j                  j                  | j                  ||	|             |dz  }|| j.                  k\  sE |S  |S # 1 sw Y   ~xY w# t        $ r }
|t!        |
      xx   dz  cc<   Y d }
~
Fd }
~
wt"        $ r3}t%        j&                  dj)                  t!        |                    d }~wt*        $ r.}t%        j,                  dj)                  |             Y d }~d }~ww xY w)Nrbutf-8r?   zVUnable to enqueue events as service stopped: {0}. Stopping collecting extension eventsz.Unable to parse and transmit event, error: {0})datetimefromtimestamprZ   r\   getmtimeopenreaddecodejsonloads
isinstancelistr:   enqueue_event_parse_telemetry_eventr   r   r   rE   rV   rG   rN   rF   r~   )r<   rT   rr   captured_events_countr   event_file_timeevent_file_descriptor
event_dataeventseventinvalid_errorstopped_errorrV   s                r    r}   z5_ProcessExtensionEvents._enqueue_events_and_get_count   sz    #++99"'':J:J?:[\ /4( 	F,A.335<<WEJ	F J' &$'XF 	E\33AA//e_U &*% %([([[$$/	. %$E	F 	F" . J
 0]0CDIDD& lss]+-.  \LSSTYZ[[\s<   	 C&1C2&C/2	F
;DF
".EF
$FF
c                    | j                  |      }t        t        t              }d|_        t
        j                  ||       t        j                  dj                  ||t        j                  j                                  t        j                  |t        j                  j                            t        j                  |t        j                  j                            t        j                   |t        j"                  j                            t        j$                  |t        j&                  j                            t        j(                  |t        j*                  j                            t        j,                  |t        j,                  j                            t        j.                  |t        j.                  j                            i}| j1                  ||       |S )z
        Parse the Json event file and convert it to TelemetryEvent object with the required data.
        :return: Complete TelemetryEvent with all required fields filled up properly. Raises if event breaches contract.
        r   z{0}-{1})#_parse_event_and_ensure_it_is_validr   r   r	   	file_typer   $add_common_params_to_telemetry_eventr   	EventNamerG   r$   r%   lowerCapabilityUsedr(   r'   Context1r)   Context2r&   Context3r,   r*   r+   _replace_or_add_param_in_event)r<   rT   extension_unparsed_eventr   extension_eventr   replace_or_add_paramss          r    r   z._ProcessExtensionEvents._parse_telemetry_event%  sr    BBC[\
 57PQ %JJ5Rab (1193C3CLRa$,,224S6 47'66H\HgHgHmHmHo8p'00/BVB_B_BeBeBg2h'00/BVB^B^BdBdBf2g'00/BVB`B`BfBfBh2i'00/BVBbBbBhBhBj2k'00/BVB_B_BeBeBg2h'00/BVB_B_BeBeBg2h
!
 	++E3HIr"   c                     d d}d}t         fd|j                         D              }t        j                  j	                         }||v r||   d j
                   ||<   n7t        |j                  t        j                  t        j                              ||   s7t        dj                  t        j                  t        j                               j                  D ]  }||vr)t        |j                  t        j                  |            | j                  kD  r3t        dj                  t        j                   j                              |t        ||         z  } |S )z
        Parse the Json event from file. Raise InvalidExtensionEventError if the event breaches pre-set contract.
        :param extension_event: The json event from file
        :return: Verified Json event that qualifies the contract.
        c                     |wt        |t              rW| j                         t        j                  j                         t        j
                  j                         fv rt        |      S |j                         S |S r   )r   r{   r   r$   r*   r+   strstrip)r   r   s     r    _clean_valuezQ_ProcessExtensionEvents._parse_event_and_ensure_it_is_valid.<locals>._clean_valueH  s^    }a%wwy%9%B%B%H%H%JL`LiLiLoLoLq$rr"1vwwy Hr"   r   z{0}: {1} not foundc              3      K   | ]<  \  }}|j                         j                  v r|j                          ||      f > y wr   )r    _EXTENSION_EVENT_REQUIRED_FIELDS).0r   r   r   r<   s      r    	<genexpr>zN_ProcessExtensionEvents._parse_event_and_ensure_it_is_valid.<locals>.<genexpr>U  sD      IAWWY$"G"GG ggia!34 Is   AANz{0}: {1} should not be emptyz {0}: max event size allowed: {1})dictr   r$   r)   r   _EXTENSION_EVENT_MAX_MSG_LENr   rG   MissingKeyErrorEmptyMessageErrorr   _EXTENSION_EVENT_MAX_SIZEOversizeEventErrorlen)r<   r   
event_sizekey_err_msgr   message_keyrequired_keyr   s   `      @r    r   z;_ProcessExtensionEvents._parse_event_and_ensure_it_is_validB  s}   	 
*  IAVAVAX I I +2288:%!&{!34VT5V5V!WE+,""#=#M#MOcOkOkln n [!,.556P6b6b5I5Q5QST T !AA 	3L5(0&&'A'Q'QS_`b b D:::06==>X>k>k>B>\>\^_ _ #eL122J	3 r"   c                     | j                   D ]1  }|j                  |v s|j                  |j                        |_        3 |sy |D ]*  }| j                   j	                  t        |||                , y r   )
parametersnamepopvaluerb   r   )r   r   param
param_names       r    r   z6_ProcessExtensionEvents._replace_or_add_param_in_eventu  sz    %% 	DEzz22377

C	D % 0 	hJ##$7
DYZdDe$fg	hr"   )$r-   r.   r/   r0   r   	timedeltar   get_etp_collection_periodr9   r_   compile
IGNORECASEry   r~   ro   r   r   dirr$   callablegetattr
startswithr   r   r8   rX   staticmethodrI   ru   rM   rL   r}   r   r   r   __classcell__)r   attrr   r   r$   r=   s   00000@r    r3   r3   J   s    *<););DbDDbDbDd)e&'1rzz2BBMM'R$ 692%4" (#+ ADEYAZ (y (y,4W=QSW5X,Ybfbqbqrvbw )-

 (y$L!]F 1 1*>}@ ( (*(%T:1f h h}(ys   ACr3   c                   t     e Zd ZdZ ej
                  d      Z fdZd Zd Z	e
d        Ze
d        Z xZS )	_CollectAndEnqueueEventsz
    Periodic operation to collect telemetry events located in the events folder and enqueue them for the
    SendTelemetryHandler thread.
    r?   )minutesc                 V    t         t        |   t        j                         || _        y r   )r7   r   r8   _EVENT_COLLECTION_PERIODr:   r;   s     r    r8   z!_CollectAndEnqueueEvents.__init__  s"    &67O7h7hi.K+r"   c                 l   	 | j                   j                         r=t        j                  dj	                  | j                   j                                      y| j                          y# t        $ r@}dj	                  t        |            }t        t        j                  |d       Y d}~yd}~ww xY w)zK
        Periodically send any events located in the events folder
        z/{0} service is not running, skipping iteration.Nz+Failure in collecting telemetry events: {0}Fr@   )r:   rD   rE   rF   rG   rH   process_eventsrN   r   r
   r   UnhandledError)r<   rV   err_msgs      r    rX   z#_CollectAndEnqueueEvents._operation  s    	_22::<MTT77GGIK L! 	_CJJ4PU;WG+::GX]^^	_s   AA* A* *	B336B..B3c           	      (   t         j                  j                  t        j                         t
              }t        j                  |      }t        t        j                        }|D ]g  }	 t        j                  |      }|t         j                  j                  ||      }	 t        j                  d|       t        |d      5 }|j                         j                  d      }ddd       t!              }	|j#                  d      du }
|
rt         j                  j%                  |      }t&        j&                  j)                  |      }|	j+                         r,t,        j/                  |	       t0        j3                  |	|       nt,        j5                  |	|       | j6                  j9                  |	       t        j:                  |       j |jM                          y# 1 sw Y   xY w# t        j:                  |       w xY w# t<        $ r8}t        j>                  djA                  tC        |                   Y d}~d}~wtD        $ r}|jG                  |       Y d}~d}~wtH        $ r}|jK                  |       Y d}~$d}~ww xY w)z
        Returns a list of events that need to be sent to the telemetry pipeline and deletes the corresponding files
        from the events directory.
        )	operationNrx   r   r   agent_eventzLUnable to enqueue events as service stopped: {0}, skipping events collection)'rZ   r\   r^   r   get_lib_dirr   r[   r   
OP_COLLECTr   searchrE   rK   r   r   r   r   groupr   r   r   is_extension_eventr   '_trim_legacy_extension_event_parametersr   r   _update_legacy_agent_eventr:   r   r|   r   rV   rG   r   UnicodeErrorupdate_unicode_errorrN   update_op_errorreport_debug_info)r<   event_directory_full_pathr   
debug_infor   r`   rr   event_fdr   r   is_legacy_eventevent_file_creation_time_epochevent_file_creation_timer   uni_errrV   s                   r    r   z'_CollectAndEnqueueEvents.process_events  s   
 %'GGLL1A1A1CEU$V!jj!:;2=Z=e=ef
% .	2J-2(//
;="$'',,/H*"U/NN#?Qot4 E%-]]_%;%;G%D
E (
3E ',kk-&@D&HO&9;9I9I/9Z63;3D3D3R3RSq3r0 3354\\]bc9^^_d_wy 5OOPUPhj 77EEeL
 IIo.M.	2` 	$$&KE E6 IIo.& .bii]+-. .   9//88 2**5112sg   -H
 H
&"G0 G$(CG0;H
$G-	)G00HH

	J-IJI))J5JJc                 L   t               }g |_        t        j                  ||       t	        | j                  D cg c]  }|j
                  |j                  f c}      }t	        |j                  D cg c]  }|j
                  |j                  f c}      }t        |j                               j                  t        |j                                     }g }|D ]   }|j                  t        |||                " | j                  j                  |       y c c}w c c}w r   )r   r   r   r   r   r   r   setkeys
differencerb   r   extend)	r   event_creation_time	new_eventr   event_paramsnew_event_paramsmissing_paramsparams_to_addr   s	            r    r   z3_CollectAndEnqueueEvents._update_legacy_agent_event  s     #$	!	%JJ9VijEDTDTU5ejj%++6UV	H\H\ ]u%**ekk!: ]^-2245@@\EVEVEXAYZ( 	`J  !4ZAQR\A]!^_	` 	. V ]s   D4D!c                 ^   t               j                  t        j                  t        j                  t        j
                  t        j                  t        j                  t        j                  g      }g }| j                  D ]"  }|j                  |v s|j                  |       $ || _	        y)a  
        This method is called for extension events before they are sent out. Per the agreement with extension
        publishers, the parameters that belong to extensions and will be reported intact are Name, Version, Operation,
        OperationSuccess, Message, and Duration. Since there is nothing preventing extensions to instantiate other
        fields (which belong to the agent), we call this method to ensure the rest of the parameters are trimmed since
        they will be replaced with values coming from the agent.
        :param event: Extension event to trim.
        :return: Trimmed extension event; containing only extension-specific parameters.
        N)r   fromkeysr   Namer%   	OperationOperationSuccessr)   Durationr   r   rb   )r   params_to_keeptrimmed_paramsr   s       r    r   z@_CollectAndEnqueueEvents._trim_legacy_extension_event_parameters  s     +00+33+55+<<+33+44*
  %% 	-Ezz^+%%e,	- *r"   )r-   r.   r/   r0   r   r   r   r8   rX   r   r   r   r   r   )r=   s   @r    r   r     sW    
  2x11!<L_9'v / /" * *r"   r   c                   ^    e Zd ZdZdZd Zed        Zd Zd Z	d Z
d Zd	 Zd
 Zed        Zy)r   z
    This Handler takes care of fetching the Extension Telemetry events from the {extension_events_dir} and sends it to
    Kusto for advanced debuggability.
    TelemetryEventsCollectorc                 .    d| _         d | _        || _        y )NT)
should_runthreadr:   )r<   r   s     r    r8   z&CollectTelemetryEventsHandler.__init__  s    .K+r"   c                  "    t         j                  S r   )r   _THREAD_NAMEr1   r"   r    rH   z-CollectTelemetryEventsHandler.get_thread_name  s    ,999r"   c                 N    t        j                  d       | j                          y )Nz"Start Extension Telemetry service.)rE   r   startr<   s    r    runz!CollectTelemetryEventsHandler.run  s    89

r"   c                 V    | j                   d uxr | j                   j                         S r   )r  is_aliver  s    r    r  z&CollectTelemetryEventsHandler.is_alive  s#    {{$&A4;;+?+?+AAr"   c                    t        j                  | j                        | _        | j                  j	                  d       | j                  j                  t        j                                | j                  j                          y )N)targetT)		threadingThreaddaemonr  	setDaemonsetNamer   rH   r  r  s    r    r  z#CollectTelemetryEventsHandler.start  sV    &&dkk:d#9IIKLr"   c                 h    d| _         | j                         r| j                  j                          yy)zO
        Stop server communication and join the thread to main thread.
        FN)r  r  r  r^   r  s    r    stopz"CollectTelemetryEventsHandler.stop%  s)      ==?KK r"   c                     | j                    S r   )r  r  s    r    rD   z%CollectTelemetryEventsHandler.stopped-  s    ??""r"   c                    t        | j                        g}t        t        j                        j
                  }t        j                  dj                  |             |r$|j                  t        | j                               t        j                  dj                  | j                                      | j                         s@	 |D ]  }|j                           	 t#        j$                  |       | j                         s?y y # t        $ r)}t        j                  dt!        |             Y d }~Ud }~ww xY w# t#        j$                  |       w xY w)Nz)Extension Telemetry pipeline enabled: {0}z#Successfully started the {0} threadzcAn error occurred in the Telemetry Extension thread main loop; will skip the current iteration.
{0})r   r:   r   r   ExtensionTelemetryPipelineis_supportedrE   r   rG   rb   r3   rH   rD   r  rN   rF   r   r   sleep_until_next_operation)r<   periodic_operationsis_etp_enabledperiodic_oprV   s        r    r  z$CollectTelemetryEventsHandler.daemon0  s
   $T%H%HI
 77L7g7ghuu?FF~VW&&'>t?b?b'cd9@@AUAUAWXY,,.	R#6 &KOO%& "<<=PQ ,,.
  !zK! !!
 "<<=PQs0   D D< 	D9D4/D< 4D99D< <Ec                 <    t               }|j                  | |       y r   )r   add_common_event_parameters)r   
event_timereporters      r    r   zBCollectTelemetryEventsHandler.add_common_params_to_telemetry_eventG  s    #%,,UJ?r"   N)r-   r.   r/   r0   r  r8   r   rH   r  r  r  r  rD   r  r   r1   r"   r    r   r     s^    
 .LL
 : :B#R. @ @r"   r   )2r   r   rZ   r_   r  collectionsr   azurelinuxagent.common.loggercommonrE   azurelinuxagent.commonr   .azurelinuxagent.common.agent_supported_featurer   r   azurelinuxagent.common.eventr   r   r	   r
   r   r   r   r   r   r    azurelinuxagent.common.exceptionr   r   azurelinuxagent.common.futurer   !azurelinuxagent.common.interfacesr   %azurelinuxagent.common.telemetryeventr   r   r   r   azurelinuxagent.common.utilsr   azurelinuxagent.ga.exthandlersr   %azurelinuxagent.ga.periodic_operationr   r!   objectr$   r3   r   r   r1   r"   r    <module>r8     s   &   	 	  # . . ' oA A A ] . DA A 1 ? CH 6  8wh/ wht	@*0 @*FC@$: C@r"   