
                            S r SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKrSSK	r	SSK
r
SSKrSSKrSSKrSSKrSSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKrSr\R8                  rSrSrS\R@                  4S\RB                  4S\R8                  4S\RD                  4S\RF                  4S\RF                  S-   4/r$\%" \$5      r&Sr'\'S/r(Sr)Sr*Sr+Sr,Sr-Sr./ SQr/\" S \/ 5       5      r0 " S  S!\Rb                  \25      r3 " S" S#\25      r4 " S$ S%\25      r5 " S& S'\25      r6S( r7\Rp                  S) 5       r9 " S* S+\Rt                  5      r; " S, S-\Rt                  5      r< " S. S/\Rt                  5      r= " S0 S1\Rt                  5      r> " S2 S3\R~                  5      r@ " S4 S5\25      rA\A" 5       rB\BR                  rD\BR                  rF\FrG\BR                  rHS6 rI  SQS7 jrJSRS8 jrKS9 rLS: rMSSS; jrNS< rOS= rPS> rQS? rR " S@ SA\25      rSSB rTSC rUSD rVSE rWSF rXSG rY SSSH jrZ  STSI jr[  STSJ jr\    STSK jr]  STSL jr^  STSM jr_  STSN jr`    STSO jra    STSP jrb\R                  rc\R                  rd\R                  re\R                  rf\R                  rg\R                  rh\R                  ri\R                  rj\R                  rkg)Uz7Module with logging related functionality for calliope.    )absolute_import)division)unicode_literals)OrderedDictN)
properties)console_attr)parser)text)files)timesutf-8warningTdebuginfoerrorcriticalnone
   z.logz.sql3z)\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}z&Running \[gcloud\.([-\w\.]+)\.[-\w]+\]z%Y.%m.%dz%H.%M.%S.%fz0.0.1z%Y-%m-%dT%H:%M:%S.%3f%Ez))versionr   z3Semantic version of the message format. E.g. v0.0.1)	verbosity	levelnamezBLogging Level: e.g. debug, info, warn, error, critical, exception.)	timestampasctimezUTC time event logged)messager   zLog/Error message.)r   r   zEActual exception or error raised, if message contains exception data.c              #   *   #    U  H	  oS S v   M     g 7f)N    ).0xs     lib/googlecloudsdk/core/log.py	<genexpr>r!   Y   s      1K1I <=2A1Is   c                   *    \ rS rSrSrS rS rS rSrg)_NullHandler]   zpA replication of python2.7's logging.NullHandler.

We recreate this class here to ease python2.6 compatibility.
c                     g Nr   selfrecords     r    handle_NullHandler.handlec           c                     g r&   r   r'   s     r    emit_NullHandler.emitf   r,   r-   c                     S U l         g r&   lockr(   s    r    
createLock_NullHandler.createLocki   s	    DIr-   r2   N)	__name__
__module____qualname____firstlineno____doc__r*   r/   r5   __static_attributes__r   r-   r    r#   r#   ]   s    
		r-   r#   c                       \ rS rSrSrS rSrg)_UserOutputFilterm   zA filter to turn on and off user output.

This filter is used by the ConsoleWriter to determine if output messages
should be printed or not.
c                     Xl         g)zVCreates the filter.

Args:
  enabled: bool, True to enable output, false to suppress.
Nenabled)r(   rB   s     r    __init___UserOutputFilter.__init__t   s	     Lr-   rA   Nr7   r8   r9   r:   r;   rC   r<   r   r-   r    r>   r>   m   s    r-   r>   c                       \ rS rSrSrS rSrg)_StreamWrapper}   z8A class to hold an output stream that we can manipulate.c                     Xl         g)zGCreates the stream wrapper.

Args:
  stream: The stream to hold on to.
Nstream)r(   rK   s     r    rC   _StreamWrapper.__init__   s	     Kr-   rJ   NrE   r   r-   r    rG   rG   }   s
    @r-   rG   c                   R    \ rS rSrSrSS jrS rS rS rS r	S r
S	 rS
 rS rSrg)_ConsoleWriter   aL  A class that wraps stdout or stderr so we can control how it gets logged.

This class is a stripped down file-like object that provides the basic
writing methods.  When you write to this stream, if it is enabled, it will be
written to stdout.  All strings will also be logged at DEBUG level so they
can be captured by the log file.
c                 4    Xl         X l        X0l        X@l        g)aW  Creates a new _ConsoleWriter wrapper.

Args:
  logger: logging.Logger, The logger to log to.
  output_filter: _UserOutputFilter, Used to determine whether to write
    output or not.
  stream_wrapper: _StreamWrapper, The wrapper for the output stream,
    stdout or stderr.
  always_flush: bool, always flush stream_wrapper, default to False.
N)_ConsoleWriter__logger_ConsoleWriter__filter_ConsoleWriter__stream_wrapper_ConsoleWriter__always_flush)r(   loggeroutput_filterstream_wrapperalways_flushs        r    rC   _ConsoleWriter.__init__   s     M!M*&r-   c                 6   Xp2[        U[        R                  5      (       aB  [        R                  " 5       nUR                  USS9nUR                  XR                  5       S9n[        R                  " U[        SS9n[        R                  " U[        SS9nX#4$ )a  Converts msg to a console safe pair of plain and ANSI-annotated strings.

Args:
  msg: str or text.TypedText, the message to parse into plain and
    ANSI-annotated strings.
Returns:
  str, str: A plain text string and a string that may also contain ANSI
    constrol sequences. If ANSI is not supported or color is disabled,
    then the second string will be identical to the first.
Fstylizeencodingescape)

isinstancer
   	TypedTextstyle_parserGetTypedTextParserParseTypedTextToStringisattyr   SafeTextLOG_FILE_ENCODING)r(   msg
plain_textstyled_texttyped_text_parsers        r    ParseMsg_ConsoleWriter.ParseMsg   s     "#t~~&&&99;$;;C;Oj%<<
{{} = &k&&.u>J''/?K""r-   c                     / / p2U H8  nU R                  U5      u  pVUR                  U5        UR                  U5        M:     SR                  U5      S-   nSR                  U5      S-   nU R                  XV5        g)a<  Writes the given tokens to the output stream, and adds a newline.

This method has the same output behavior as the builtin print method but
respects the configured verbosity.

Args:
  *tokens: str or text.TypedTextor any object with a str() or unicode()
    method, The messages to print, which are joined with ' '.
 
N)rl   appendjoin_Write)r(   tokensplain_tokensstyled_tokenstokenri   rj   s          r    Print_ConsoleWriter.Print   sv     #%b- $e 4j*%;' 
 ,'$.J((=)D0KKK
(r-   c                 .    U R                   R                  $ )z)Returns the console writer output stream.)rS   rK   r4   s    r    GetConsoleWriterStream%_ConsoleWriter.GetConsoleWriterStream   s      '''r-   c                    U R                   R                  U5        U R                  R                  (       a  [        R
                  " 5       R                  5       n[        R                  " X#SS9n[        R                  (       a  UR                  U=(       d    SS5      nU R                  R                  R                  U5        U R                  (       a  U R                  5         ggg)a  Just a helper so we don't have to double encode from Print and write.

Args:
  msg: A text string that only has characters that are safe to encode with
    utf-8.
  styled_msg: A text string with the same properties as msg but also
    contains ANSI control sequences.
Fr]   r   replaceN)rQ   r   rR   rB   r   GetConsoleAttrGetEncodingrf   sixPY2encoderS   rK   writerT   flush)r(   rh   
styled_msgstream_encoding
stream_msgs        r    rs   _ConsoleWriter._Write   s     	MMs}} %335AACo((
u>j	&&'A'9M

""((4			

 
 r-   c                 L    U R                  U5      u  p#U R                  X#5        g r&   )rl   rs   )r(   rh   ri   rj   s       r    r   _ConsoleWriter.write   s    "mmC0JKK
(r-   c                 8    U H  nU R                  U5        M     g r&   )r   )r(   lineslines      r    
writelines_ConsoleWriter.writelines   s    
jj r-   c                     U R                   R                  (       a%  U R                  R                  R	                  5         g g r&   )rR   rB   rS   rK   r   r4   s    r    r   _ConsoleWriter.flush   s,    }}
""((* r-   c                 d    [        U R                  R                  SS 5      nU(       a  U" 5       $ S$ )Nre   F)getattrrS   rK   )r(   re   s     r    re   _ConsoleWriter.isatty   s+    T**118TBF68(5(r-   )__always_flush__filter__logger__stream_wrapperN)F)r7   r8   r9   r:   r;   rC   rl   rx   r{   rs   r   r   r   re   r<   r   r-   r    rN   rN      s4    ' #.)((4)

+)r-   rN   c                 R    [         R                  (       a  U R                  S5      $ U $ )zGets the correct format string to use based on the Python version.

Args:
  fmt: text string, The format string to convert.

Returns:
  A byte string on Python 2 or the original string on Python 3.
r   )r   r   r   fmts    r    
_FmtStringr      s     	WW::g	*r-   c              #      #    U R                   n [        R                  " U R                   USS9U l         Sv   X l         g! X l         f = f7f)a}  Temporarily modifies a log record to make the message safe to print.

Python logging creates a single log record for each log event. Each handler
is given that record and asked format it. To avoid unicode issues, we decode
all the messages in case they are byte strings. Doing this we also want to
ensure the resulting string is able to be printed to the given output target.

Some handlers target the console (which can have many different encodings) and
some target the log file (which we always write as utf-8. If we modify the
record, depending on the order of handlers, the log message could lose
information along the way.

For example, if the user has an ascii console, we replace non-ascii characters
in the string with '?' to print. Then if the log file handler is called, the
original unicode data is gone, even though it could successfully be printed
to the log file. This context manager changes the log record briefly so it can
be formatted without changing it for later handlers.

Args:
  record: The log record.
  encoding: The name of the encoding to SafeDecode with.
Yields:
  None, yield is necessary as this is a context manager.
Fr]   N)rh   r   rf   )r)   r^   original_msgs      r    _SafeDecodedLogRecordr     s?     4 ,&&

Xe5FJ	JJs   A)A  A AAc                   H   ^  \ rS rSrSr\" S5      rU 4S jrU 4S jrSr	U =r
$ )_LogFileFormatteri3  z"A formatter for log file contents.z3%(asctime)s %(levelname)-8s %(name)-15s %(message)sc                 D   > [         [        U ]  [        R                  S9  g )Nr   )superr   rC   FORMAT)r(   	__class__s    r    rC   _LogFileFormatter.__init__9  s    	
T+0A0H0H+Ir-   c                   > [         R                   " U5      n[        UR                  [        R                  5      (       a2  [
        R                  " 5       R                  UR                  SS9Ul        [        UR                  [        5      (       ax  / nUR                   HV  n[        U[        R                  5      (       a#  [
        R                  " 5       R                  USS9nUR                  U5        MX     [        U5      Ul        [        U[        5         [        [        U ]?  U5      nS S S 5        U$ ! , (       d  f       W$ = f)NFr[   )copyr`   rh   r
   ra   rb   rc   rd   argstuplerq   r   rg   r   r   format)r(   r)   new_argsargrh   r   s        r    r   _LogFileFormatter.format<  s    YYvF&**dnn--224KK
**e L %fj &++u%%h#c4>>**//1HH5 I "#	 
 (Ofk 
v'8	9#T1&9c 
:J 
:	9Js   D88
Er   )r7   r8   r9   r:   r;   r   r   rC   r   r<   __classcell__r   s   @r    r   r   3  s#    * KL&J r-   r   c                     ^  \ rS rSrSr\" S5      r\" S5      r\" S5      r\" S5      r	\" S5      r
\" S5      r\\-   rS	\\-   \-   0r\R                  \
\-   \-   \-   \R                   \	\-   \-   \-   \R"                  \	\-   \-   \-   0\R                  \\
-   \-   \-   \-   \R                   \\	-   \-   \-   \-   \R"                  \	\-   \-   \-   \-   0S
.rU 4S jrU 4S jrSrU =r$ )_ConsoleFormatteriS  z@A formatter for the console logger, handles colorizing messages.z%(asctime)s z%(levelname)s:z %(message)sz[1;31mz[1;33mz[0mdetailed)standardr   c                 *  > [         [        U ]  5         [        R                  R
                  R                  R                  5       n[        R                  R
                  R                  R                  SS9(       + nX1R                  5       -  nU[        R                  " 5       R                  5       -  nU(       a  [        R                  R                  U5      O0 U l        [        R"                  R                  U[        R$                  5      U l        g )NFvalidate)r   r   rC   r   VALUEScoreconsole_log_formatGetdisable_colorGetBoolre   r   r   SupportsAnsiCOLOR_FORMATSget_formatsDEFAULT_FORMATSDEFAULT_FORMAT_default_format)r(   
out_streamr   	use_colorr   s       r    rC   _ConsoleFormatter.__init__p  s    	
T+-#**//BBFFH%%**88@@ A  I""$$I,,.;;==I  	''++,>? 	M -<<@@-<<>Dr-   c                   > U R                   R                  UR                  U R                  5      nX l        [
        R                  (       a  X R                  l        [        R                  " 5       R                  5       n[        X5         [        [        U ];  U5      nS S S 5        [
        R                  (       a  WR!                  U=(       d    SS5      nW$ ! , (       d  f       N@= f)Nr   r~   )r   r   levelnor   _fmtr   PY3_styler   r   r   r   r   r   r   r   r   )r(   r)   r   r   rh   r   s        r    r   _ConsoleFormatter.format  s    
--

FNND,@,@
AC I
wwkk
 #113??AO	v	7#T1&9c 
8
wwJJ1'9=cJ	 
8	7s   C
C')r   r   r   )r7   r8   r9   r:   r;   r   	TIMESTAMPLEVELMESSAGEREDYELLOWENDr   r   loggingWARNINGERRORFATALr   rC   r   r<   r   r   s   @r    r   r   S  s    H()
%
&%~&'< #l#&9#7?.)e#g-/ //6E>C/'9
--us*W4
--uw.4 //9v-5;gE
--S5036@
--y507:S@-> r-   r   c                   V   ^  \ rS rSrSr  S
U 4S jjrS rS rS rSS jr	S r
S	rU =r$ )_JsonFormatteri  z9A formatter that handles formatting log messages as JSON.c                    > [         [        U ]  5         Xl        X0l        U=(       d    [
        R                  U l        [        U l	        g r&   )
r   r   rC   required_fieldsjson_encoderjsondumpsjson_serializerSTRUCTURED_TIME_FORMATdefault_time_format)r(   r   r   r   r   s       r    rC   _JsonFormatter.__init__  s7    
 
.$(**$*8djjD5Dr-   c                    [        5       nUR                  (       GaI  UR                  (       d   U R                  UR                  5      Ul        [	        [        UR                  5      [        5      (       aa  [        UR                  5      R                  US'   [        R                  " UR                  5      US'   [        UR                  SS5      US'   U$ [	        [        UR                  S   5      [        5      (       a5  UR                  S   US'   UR                  US'   UR                  S   US'   U$ UR                  US'   UR                  US'   UR                  US'   U$ g)zBExtract exception info from a logging.LogRecord as an OrderedDict.typedetails__traceback__N
stacktracer   r   )r   exc_infoexc_textformatException
issubclassr   rh   BaseExceptionr7   r   	text_typer   )r(   
log_record
error_dicts      r    GetErrorDict_JsonFormatter.GetErrorDict  s<   J  "22:3F3FG
	D(-	8	8!*..1::
6 #jnn =
9#*:>>+:D$B
<   d:..q12MBB'003
6 * 3 3
9#-#6#6q#9
< 
  (00
6 * 3 3
9#-#6#6
< r-   c                     [        5       n[        R                  " U R                  5       H2  u  p4US:X  a
  [        X#'   M  UR
                  R                  U5      X#'   M4     U$ )a  Converts a logging.LogRecord object to a JSON serializable OrderedDict.

Utilizes supplied set of required_fields to determine output fields.

Args:
  log_record: logging.LogRecord, log record to be converted

Returns:
  OrderedDict of required_field values.
r   )r   r   	iteritemsr   STRUCTURED_RECORD_VERSION__dict__r   )r(   r   message_dictoutfieldlogfields        r    BuildLogMsg_JsonFormatter.BuildLogMsg  sY     =L!mmD,@,@A	Y	!:!+!4!4!8!8!B	 B
 r-   c                     U R                  U5      nUR                  S5      (       d  UR                  S5        U R                  UU R                  S9$ )z)Returns a json string of the log message.r   )cls)r   r   popr   r   )r(   r   log_messages      r    LogRecordToJson_JsonFormatter.LogRecordToJson  sP    "":.K??7##oog$($5$5   7 7r-   c                     [         R                  " [         R                  " UR                  5      U[         R                  S9$ )N)r   tzinfo)r   FormatDateTimeGetDateTimeFromTimeStampcreatedUTC)r(   r)   datefmts      r    
formatTime_JsonFormatter.formatTime  s1    &&v~~6yy r-   c                     U R                  U5      UR                  S'   UR                  5       Ul        U R	                  XR
                  5      Ul        U R                  U5      $ )z,Formats a log record and serializes to json.r   )r   r   
getMessager   r	  r   r   r   r'   s     r    r   _JsonFormatter.format  sR    #008FOOG&&(FN__V-E-EFFN''r-   )r   r   r   r   NNr&   )r7   r8   r9   r:   r;   rC   r   r   r   r	  r   r<   r   r   s   @r    r   r     s1    A  $ 	6.(7( (r-   r   c                   0    \ rS rSrSr SS jrS rS rSrg)	_ConsoleLoggingFormatterMuxeri  z/Logging Formatter Composed of other formatters.Nc                     [         R                  R                  U 5        U=(       d    [         R                  U l        Xl        UR                  5       U l        g r&   )r   	FormatterrC   default_formatterstructured_formatterre   terminal)r(   r  stream_writterr  s       r    rC   &_ConsoleLoggingFormatterMuxer.__init__  sA     t$.C'2C2CD 4"))+DMr-   c                     [         R                  R                  R                  R	                  5       n[        US:H  =(       a    U R                  US:H  =(       a    U R                  (       + US:H  /5      (       a  gg)z=Returns True if output should be Structured, False otherwise.r  logalwaysTF)r   r   r   show_structured_logsr   anyr  )r(   show_messagess     r    ShowStructuredOutput2_ConsoleLoggingFormatterMuxer.ShowStructuredOutput  sh    %%**??CCEM
MZ'9DMMU"84=='8X%' ( ( r-   c                    U R                  5       nU R                  =(       a    U(       + n[        R                  " U5      n[        UR                  [
        R                  5      (       a2  [        R                  " 5       R                  UR                  US9Ul        [        UR                  [        5      (       aw  / nUR                   HU  n[        U[
        R                  5      (       a"  [        R                  " 5       R                  XSS9nUR                  U5        MW     [        U5      Ul
        U(       a  U R                  R                  U5      $ U R                  R                  U5      $ )z.Formats the record using the proper formatter.r[   )r  r  r   r`   rh   r
   ra   rb   rc   rd   r   r   rq   r  r   r  )r(   r)   show_structured_outputr\   r   r   s         r    r   $_ConsoleLoggingFormatterMuxer.format  s   !668 mm:$: :GYYvF&**dnn--224KK
**g L 'fj &++u%%h#c4>>**//1HH I $#	 
 (Ofk&&--f55!!((00r-   )r  r  r  r&   )	r7   r8   r9   r:   r;   rC   r  r   r<   r   r-   r    r  r    s    7
 "&,1r-   r  c                       \ rS rSrSrS rSrg)NoHeaderErrorFilteri  zgFilter out urllib3 Header Parsing Errors due to a urllib3 bug.

See https://bugs.python.org/issue36226
c                 (    SUR                  5       ;  $ )z!Filter out Header Parsing Errors.zFailed to parse headers)r  r'   s     r    filterNoHeaderErrorFilter.filter  s    $F,=,=,???r-   r   N)r7   r8   r9   r:   r;   r&  r<   r   r-   r    r$  r$    s    
@r-   r$  c                   p    \ rS rSrSrSrS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rSrg)_LogManageri  zA class to manage the logging handlers based on how calliope is being used.

We want to always log to a file, in addition to logging to stdout if in CLI
mode.  This sets up the required handlers to do this.
___FILE_ONLY___c                 6   [        5       U l        [        R                  " 5       U l        U R                  R                  [        R                  5        [        R                  " [        R                  5      U l	        U R                  R                  [        R                  5        SU R                  l
        / U l        S U l        [        [        5      U l        [!        S 5      U l        [!        S 5      U l        ['        U R                  U R                  U R"                  5      U l        ['        U R                  U R                  U R$                  SS9U l        S U l        S U l        S U l        U R3                  [4        R6                  [4        R8                  5        g )NFT)rX   )r   _file_formatterr   	getLogger_root_loggersetLevelNOTSETr)  FILE_ONLY_LOGGER_NAMEfile_only_logger	propagate
_logs_dirs_console_formatterr>   DEFAULT_USER_OUTPUT_ENABLED_user_output_filterrG   stdout_stream_wrapperstderr_stream_wrapperrN   stdout_writerstderr_writerr   user_output_enabledcurrent_log_fileResetsysstdoutstderrr4   s    r    rC   _LogManager.__init__'  s3   ,.D  ))+Dw~~.
 $--k.O.OPD""7>>2&+D#DO"D01LMD!/!5D!/!5D'(=(=(,(@(@(,(B(BDD ((=(=(,(@(@(,(B(B59;D
 DN#D DJJszz3::&r-   c                    / U R                   R                  SS& XR                  l        X R                  l        [        [        5      n[        U5      n[        UU R                  US9nXPl
        [        R                  " U5      U l        U R                  R                  U R                  5        U R                  R                  [         5        U R                   R#                  U R                  5        U R$                  R                   H  nUR'                  5         M     / U R$                  R                  SS& U R$                  R#                  [)        5       5        U R$                  R                  [        R*                  5        U R-                  S5        U R/                  S5        SU l        [        R2                  " S5      R5                  [7        5       5        g)z6Resets all logging functionality to its default state.N)r  zurllib3.connectionpool)r.  handlersr8  rK   r9  r   !REQUIRED_STRUCTURED_RECORD_FIELDSr   r  r;  r5  r   StreamHandlerstderr_handlersetFormatterr/  DEFAULT_VERBOSITY
addHandlerr2  closer#   r0  SetVerbositySetUserOutputEnabledr=  r-  	addFilterr$  )r(   r@  rA  json_formatterstd_console_formatterconsole_formatterfs          r    r>  _LogManager.ResetJ  su    %'Dq! )/%(.% $$EFN-f55/1
 0!//7D$$T%<%<=  !23  !4!45 ""++ggi ,(*D""1%$$\^4""7>>2 	dd# D./99r-   c                 `   UcX  [         R                  R                  R                  R	                  5       nUb#  [
        R                  UR                  5       5      nUc  [        nU R                  U:X  a  U R                  $ U R                  R                  U5        U R                  nXl        U$ a  Sets the active verbosity for the logger.

Args:
  verbosity: int, A verbosity constant from the logging module that
    determines what level of logs will show in the console. If None, the
    value from properties or the default will be used.

Returns:
  int, The current verbosity.
)r   r   r   r   r   VALID_VERBOSITY_STRINGSr   lowerrI  rG  r/  )r(   r   verbosity_stringold_verbositys       r    rL  _LogManager.SetVerbosityq  s     #**//99==?		%+//0@0F0F0HI	#i~~"^^  +NNMNr-   c                     Uc1  [         R                  R                  R                  R	                  SS9nUc  [
        nXR                  l        U R                  nXl        U$ )zSets whether user output should go to the console.

Args:
  enabled: bool, True to enable output, False to suppress.  If None, the
    value from properties or the default will be used.

Returns:
  bool, The old value of enabled.
Fr   )r   r   r   r<  r   r6  r7  rB   )r(   rB   old_enableds      r    rM   _LogManager.SetUserOutputEnabled  sa     !!&&::BB C g+g'.$**K&r-   c                 f    [         R                  R                  R                  R	                  5       $ )zmGets the max log days for the logger.

Returns:
  max_log_days: int, the maximum days for log file retention
)r   r   r   max_log_daysGetIntr4   s    r    _GetMaxLogDays_LogManager._GetMaxLogDays  s%     !!..5577r-   c                 (    SU R                  5       -  $ )z$Gets max_log_day's worth of seconds.iQ )ra  r4   s    r    
_GetMaxAge_LogManager._GetMaxAge  s    $--///r-   c                 F    [         R                  " U R                  5       S9$ )N)days)datetime	timedeltara  r4   s    r    _GetMaxAgeTimeDelta_LogManager._GetMaxAgeTimeDelta  s    4#6#6#899r-   c                     [         R                   R                  [        R                  R	                  U5      [
        5      $ r&   )rh  strptimeospathbasenameDAY_DIR_FORMAT)r(   ro  s     r    _GetFileDatetime_LogManager._GetFileDatetime  s/    %%bgg&6&6t&<&46 6r-   c           	         U(       a  XR                   ;   a  gU R                   R                  U5        U R                  U5        [        R                  R
                  R                  R                  5       (       a  g U R                  U5      n[        R                  " U[        S9nX l        UR+                  [        R,                  5        UR/                  U R0                  5        U R2                  R5                  U5        U R6                  R5                  U5        g! [        [        [        R                  4 a9  n[!        SR#                  U[%        U5      R&                  U5      5         SnAgSnAff = f)zAdds a new logging directory and configures file logging.

Args:
  logs_dir: str, Path to a directory to store log files under.  This method
    has no effect if this is None, or if this directory has already been
    registered.
N)r^   zCould not setup log file in {0}, ({1}: {2}.
The configuration directory may not be writable. To learn more, see https://cloud.google.com/sdk/docs/configurations#creating_a_configuration)r4  rq   _CleanUpLogsr   r   r   disable_file_loggingr   _SetupLogsDirr   FileHandlerrg   OSErrorIOErrorr   Errorr   r   r   r7   r=  r/  r0  rH  r,  r.  rJ  r2  )r(   logs_dirlog_filefile_handlerexps        r    
AddLogsDir_LogManager.AddLogsDir  s(    x??2OO8$
 	h
 22::<<##H-h((
.0l %'..)d223  .$$\2 Wekk*  ) *0DI..*5	6 s   =*D E6=/E11E6c                 t    U R                  5       (       a   U R                  U5        gg! [         a     gf = f)z7Clean up old log files if log cleanup has been enabled.N)ra  _CleanLogsDirry  )r(   r|  s     r    ru  _LogManager._CleanUpLogs  s=    8$   s   * 
77c                 h   [         R                   R                  5       n[        R                  " 5       n [        R                  " U5      nU H  n[        R                  R                  X5      nU R                  X&5      (       d  M:  [        R                  " U5       HP  n[        R                  R                  Xg5      nU R                  X85      (       d  M:  [        R                  " U5        MR      [        R                  " U5        M     g! [
        [        4 a     gf = f! [
         a     M  f = f)zoCleans up old log files form the given logs directory.

Args:
  logs_dir: str, The path to the logs directory.
N)rh  nowtimern  listdirry  UnicodeErrorro  rr   _ShouldDeleteDir_ShouldDeleteFileremovermdir)	r(   r|  r  now_secondsdirnamesdirnamedir_pathfilenamelog_file_paths	            r    r  _LogManager._CleanLogsDir  s     




!C))+KH%h
 h0h			s	-	-

8,H'',,x:-##K??IIm$ -	
((8
 	 \"    	 	s#   D 2D#D D #
D10D1c                     [         R                  R                  U5      (       d  g U R                  U5      nX-
  nX@R                  5       [        R                  " S5      -   :  $ ! [         a     gf = f)a  Determines if the directory should be deleted.

True iff:
* path is a directory
* path name is formatted according to DAY_DIR_FORMAT
* age of path (according to DAY_DIR_FORMAT) is slightly older than the
  MAX_AGE of a log file

Args:
  now: datetime.datetime object indicating the current date/time.
  path: the full path to the directory in question.

Returns:
  bool, whether the path is a valid directory that should be deleted
F   )rn  ro  isdirrr  
ValueErrorrj  rh  ri  )r(   r  ro  dir_datedir_ages        r    r  _LogManager._ShouldDeleteDir	  sp      77==&&t,h nG --/(2D2DQ2GGGG  s   A% %
A21A2c                     [         R                  R                  U5      S   [        ;  a  g[         R                  " U5      nXR
                  -
  U R                  5       :  $ )a  Determines if the file is old enough to be deleted.

If the file is not a file that we recognize, return False.

Args:
  now_seconds: int, The current time in seconds.
  path: str, The file or directory path to check.

Returns:
  bool, True if it should be deleted, False otherwise.
r  F)rn  ro  splitext_KNOWN_LOG_FILE_EXTENSIONSstatst_mtimerd  )r(   r  ro  	stat_infos       r    r  _LogManager._ShouldDeleteFile&  sL     
wwa (BBI+++doo.???r-   c                 b   [         R                   R                  5       nUR                  [        5      n[        R
                  R                  X5      n[        R                  " U5        SR                  UR                  [        5      [        S9n[        R
                  R                  XE5      nU$ )a  Creates the necessary log directories and get the file name to log to.

Logs are created under the given directory.  There is a sub-directory for
each day, and logs for individual invocations are created under that.

Deletes files in this directory that are older than MAX_AGE.

Args:
  logs_dir: str, Path to a directory to store log files under

Returns:
  str, The path to the file to log to
z{timestamp}{ext})r   ext)rh  r  strftimerq  rn  ro  rr   r   MakeDirr   FILENAME_FORMATLOG_FILE_EXTENSION)r(   r|  r  day_dir_nameday_dir_pathr  r}  s          r    rw  _LogManager._SetupLogsDir8  s     




!C<</L77<<7L	MM,!((,,/5G ) IHww||L3HOr-   )r5  r,  r4  r.  r7  r=  r2  rG  r9  r;  r8  r:  r<  r   N)r7   r8   r9   r:   r;   r1  rC   r>  rL  rM  ra  rd  rj  rr  r  ru  r  r  r  rw  r<   r   r-   r    r)  r)    sZ    
 ,!'F%N:,80:6*3X:H:@$r-   r)  c                  *    [         R                  " U 6   g)zWrites the given message to the output stream, and adds a newline.

This method has the same output behavior as the builtin print method but
respects the configured user output setting.

Args:
  *msg: str, The messages to print.
N)outrx   )rh   s    r    rx   rx   l  s     ))S/r-   c                    U S:X  aC  U(       a&  [         R                  " [        R                  U5        g[        R                  U5        gU(       a  [         R                  " XUXES9  g[         R                  " U UUUUS9  g)a  Writes content to the specified file or stdout if path is '-'.

Args:
  path: str, The path of the file to write.
  content: str, The content to write to the file.
  overwrite: bool, Whether or not to overwrite the file if it exists.
  binary: bool, True to open the file in binary mode.
  private: bool, Whether to write the file in private mode.
  create_path: bool, True to create intermediate directories, if needed.

Raises:
  Error: If the file cannot be written.
-)	overwriteprivatecreate_pathN)r   WriteStreamBytesr?  r@  r  r   WriteBinaryFileContentsWriteFileContents)ro  contentr  binaryr  r  s         r    WriteToFileOrStdoutr  x  sf     
S[SZZ1	ii	!!$9*1L 
!r-   c                     [         R                  U =(       d    [        R                  U=(       d    [        R                  5        g)ar  Reinitialize the logging system.

This clears all loggers registered in the logging module, and reinitializes
it with the specific loggers we want for calliope.

This will set the initial values for verbosity or user_output_enabled to their
values saved in the properties.

Since we are using the python logging module, and that is all statically
initialized, this method does not actually turn off all the loggers.  If you
hold references to loggers or writers after calling this method, it is
possible they will continue to work, but their behavior might change when the
logging framework is reinitialized.  This is useful mainly for clearing the
loggers between tests so stubs can get reset.

Args:
  stdout: the file-like object to restore to stdout. If not given, sys.stdout
    is used
  stderr: the file-like object to restore to stderr. If not given, sys.stderr
    is used
N)_log_managerr>  r?  r@  rA  )r@  rA  s     r    r>  r>    s&    , V)szz6+?SZZ@r-   c                 ,    [         R                  U 5      $ rU  )r  rL  r   s    r    rL  rL    s     
	"	"9	--r-   c                  "    [         R                  $ )zLGets the current verbosity setting.

Returns:
  int, The current verbosity.
)r  r   r   r-   r    GetVerbosityr    s     
		r-   c                 v    U c
  [        5       n [        R                  " [        5       H  u  pX:X  d  M  Us  $    g)zGets the name for the current verbosity setting or verbosity if not None.

Args:
  verbosity: int, Returns the name for this verbosity if not None.

Returns:
  str, The verbosity name or None if the verbosity is unknown.
N)r  r   r   rV  )r   namenums      r    GetVerbosityNamer    s7     I==!89idk : 
r-   c                  D    [          V Vs/ s H  u  pU PM	     snn $ s  snn f )zFGets all the valid verbosity names from most verbose to least verbose.)_VERBOSITY_LEVELS)r  _s     r    OrderedVerbosityNamesr    s    /	0/74$/	00	0s   c                 4    U =(       d    [         R                  $ )zFReturns the effective verbosity for verbosity. Handles None => NOTSET.)r   r0  r  s    r    _GetEffectiveVerbosityr    s    		$gnn$r-   c                 R    [        [        R                  R                  U 5      5      $ )zSets the log file verbosity.

Args:
  verbosity: int, A verbosity constant from the logging module that
    determines what level of logs will be written to the log file. If None,
    the default will be used.

Returns:
  int, The current verbosity.
)r  r  r2  r/  r  s    r    SetLogFileVerbosityr    s%     
 ##,,Y7
9 9r-   c                  P    [        [        R                  R                  5       5      $ )z^Gets the current log file verbosity setting.

Returns:
  int, The log file current verbosity.
)r  r  r2  getEffectiveLevelr   r-   r    GetLogFileVerbosityr    s#     
 ##557
9 9r-   c                   *    \ rS rSrSrS rS rS rSrg)LogFileVerbosityi  a  A log file verbosity context manager.

Attributes:
  _context_verbosity: int, The log file verbosity during the context.
  _original_verbosity: int, The original log file verbosity before the
    context was entered.

Returns:
  The original verbosity is returned in the "as" clause.
c                     Xl         g r&   )_context_verbosity)r(   r   s     r    rC   LogFileVerbosity.__init__  s    'r-   c                 N    [        U R                  5      U l        U R                  $ r&   )r  r  _original_verbosityr4   s    r    	__enter__LogFileVerbosity.__enter__  s!    243J3JKD###r-   c                 .    [        U R                  5        g)NF)r  r  )r(   exc_type	exc_value	tracebacks       r    __exit__LogFileVerbosity.__exit__  s    001r-   )r  r  N)	r7   r8   r9   r:   r;   rC   r  r  r<   r   r-   r    r  r    s    	($r-   r  c                 ,    [         R                  U 5      $ )zSets whether user output should go to the console.

Args:
  enabled: bool, True to enable output, false to suppress.

Returns:
  bool, The old value of enabled.
)r  rM  rA   s    r    rM  rM    s     
	*	*7	33r-   c                  "    [         R                  $ )zoGets whether user output is enabled or not.

Returns:
  bool, True if user output is enabled, False otherwise.
)r  r<  r   r-   r    IsUserOutputEnabledr     s     
	)	))r-   c                 *    [         R                  U S9  g)zqAdds a new logging file handler to the root logger.

Args:
  logs_dir: str, The root directory to store logs in.
r|  N)r  r  r  s    r    AddFileLoggingr  )  s     8,r-   c                  p    [         R                  n U (       d  g[        R                  R	                  U 5      $ )zbGets the path to the currently in use log directory.

Returns:
  str, The logging directory path.
N)r  r=  rn  ro  r  )r}  s    r    	GetLogDirr  2  s(     **(			""r-   c                     [         R                  nU(       d  g[        R                  R	                  U5      nUS[        [        5      *  nX0-   $ )zReturns a new log file name based on the currently active log file.

Args:
  suffix: str, A suffix to add to the current log file name.

Returns:
  str, The name of a log file, or None if file logging is not on.
N)r  r=  rn  ro  rp  lenr  )suffixr}  log_filenamelog_file_root_names       r    GetLogFileNamer  >  sI     **(	!!(+,#$=c*<&=%=>		$$r-   c                  "    [         R                  $ )z~Return the path to the currently active log file.

Returns:
  str, The name of a log file, or None if file logging is not on.
)r  r=  r   r-   r    GetLogFilePathr  O  s     
	&	&&r-   c                    / nU(       a#  UR                  S5        UR                  U 5        OU(       a1  UR                  U R                  5       5        UR                  S5        OHU=(       d    SR                  U 5      nUR                  SR                  UR                  5       5      5        U(       a"  UR                  S5        UR                  U5        U(       aS  UR                  S5        UR                  [        R                  R                  [        R                  " U5      5      5        U(       a"  UR                  S5        UR                  U5        U(       a"  UR                  S5        UR                  U5        [        US   5      R                  S5      (       a  S	OSn	UR                  U	5        [        R                  " U5      nU(       a  [        O[        R                  n
U
" U5        g
)a  Prints a status message for operation on resource.

The non-failure status messages are disabled when user output is disabled.

Args:
  operation: str, The completed operation name.
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message. For commands that operate on multiple
    resources and report all successes and failures before exiting. Failure
    messages use log.error. This will display the message on the standard
    error even when user output is disabled.
  operation_past_tense: str, The past tense version of the operation verb.
    If None assumes operation + 'd'
z
Failed to z in progress forz{0}dz{0}ro   z: . N)rq   
capitalizer   r
   	TextTypesRESOURCE_NAMEr   r   strendswithra   r   statusrx   )	operationresourcekindis_asyncr   failedoperation_past_tenserh   verbperiodwriters              r    _PrintResourceChanger   X  sF   0 	#JJ|JJyJJy##%&JJ!";6==#;DJJu||DOO-./	JJsOJJtJJsOJJt~~++CMM(,CDEJJsOJJwJJtJJvSW&&s++2&**Vs#5&+r-   c                      [        SXX#U5        g)aO  Prints a status message indicating that a resource was created.

Args:
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message.
createNr   r  r  r  r   r  s        r    CreatedResourcer         xFKr-   c                      [        SXX#U5        g)aO  Prints a status message indicating that a resource was deleted.

Args:
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message.
deleteNr  r  s        r    DeletedResourcer	    r  r-   c           
      "    [        SU UUUUSS9  g)aP  Prints a status message indicating that a resource was detached.

Args:
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message.
detachdetachedr  Nr  r  s        r    DetachedResourcer    !     
%'r-   c                      [        SXX#U5        g)aP  Prints a status message indicating that a resource was restored.

Args:
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message.
restoreNr  r  s        r    RestoredResourcer    s     y((VLr-   c                      [        SXX#U5        g)aO  Prints a status message indicating that a resource was updated.

Args:
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message.
updateNr  r  s        r    UpdatedResourcer    r  r-   c           
          [        SXX#USS9  g)aM  Prints a status message indicating that a resource was reset.

Args:
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message.
resetr  Nr  r  s        r    ResetResourcer    s     w6,35r-   c           
      "    [        SU UUUUSS9  g)aP  Prints a status message indicating that a resource was imported.

Args:
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message.
importimportedr  Nr  r  s        r    ImportResourcer    r  r-   c           
      "    [        SU UUUUSS9  g)aP  Prints a status message indicating that a resource was exported.

Args:
  resource: str, The resource name.
  kind: str, The resource kind (instance, cluster, project, etc.).
  is_async: bool, True if the operation is in progress.
  details: str, Extra details appended to the message. Keep it succinct.
  failed: str, Failure message.
exportexportedr  Nr  r  s        r    ExportResourcer     r  r-   )TFFFr  r&   )NFNN)lr;   
__future__r   r   r   collectionsr   
contextlibr   rh  r   r   rn  r?  r  googlecloudsdk.corer   googlecloudsdk.core.consoler   !googlecloudsdk.core.console.styler	   rb   r
   googlecloudsdk.core.utilr   r   r   rg   r   rI  DEFAULT_VERBOSITY_STRINGr6  DEBUGINFOr   CRITICALr  dictrV  r  r  LOG_PREFIX_PATTERNUSED_SURFACE_PATTERNrq  r  r   r   STRUCTURED_RECORD_FIELDSrE  Handlerobjectr#   r>   rG   rN   r   contextmanagerr   r  r   r   r   r  Filterr$  r)  r  r:  r  r;  errr  r2  rx   r  r>  rL  r  r  r  r  r  r  r  rM  r  r  r  r  r  r   r  r	  r  r  r  r  r  r   r-  r  r   r   r   r   r   fatal	exceptionr   r-   r    <module>r7     s|    > &  ' #      	 
  * 4 D 2 * * 
  OO $ "  gmmW\\ gmm!!"W"#%  01  0': 
 B @   $ 3 
	  %0 1K1I1K %L !7??F    	V 	r)V r)j$  D)) @>)) >BM(W&& M(`-1G$5$5 -1`@'.. @o& od	 }       
  00 	 ?D38!@A2. "1
%
99v 0	4*-	#%"' /34n BFL BFL #! 	'0 CG M BFL @D5  !	'2 !	'4 	kk||
//	r-   