
    gI.                         d Z 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	Z	m
Z
 ddlmZmZmZmZmZmZ dZ	 dZ	 dZ	  ej*                  e      Z G d	 d
e      ZddZddZd Zd Zd Zy)aw  
Easy to use UNIX system logging for Python's :mod:`logging` module.

Admittedly system logging has little to do with colored terminal output, however:

- The `coloredlogs` package is my attempt to do Python logging right and system
  logging is an important part of that equation.

- I've seen a surprising number of quirks and mistakes in system logging done
  in Python, for example including ``%(asctime)s`` in a format string (the
  system logging daemon is responsible for adding timestamps and thus you end
  up with duplicate timestamps that make the logs awful to read :-).

- The ``%(programname)s`` filter originated in my system logging code and I
  wanted it in `coloredlogs` so the step to include this module wasn't that big.

- As a bonus this Python module now has a test suite and proper documentation.

So there :-P. Go take a look at :func:`enable_system_logging()`.
    N)coerce_boolean)on_macos
on_windows)DEFAULT_LOG_LEVELProgramNameFilteradjust_levelfind_program_namelevel_to_numberreplace_handlerz/var/run/syslogz/dev/logz7%(programname)s[%(process)d]: %(levelname)s %(message)sc                   $    e Zd ZdZd Zd ZddZy)SystemLoggingz)Context manager to enable system logging.c                 .    || _         || _        d| _        y)z
        Initialize a :class:`SystemLogging` object.

        :param args: Positional arguments to :func:`enable_system_logging()`.
        :param kw: Keyword arguments to :func:`enable_system_logging()`.
        N)argskwhandler)selfr   r   s      G/var/www/openai/venv/lib/python3.12/site-packages/coloredlogs/syslog.py__init__zSystemLogging.__init__N   s     	    c                 z    | j                   $t        | j                  i | j                  | _         | j                   S )z0Enable system logging when entering the context.)r   enable_system_loggingr   r   )r   s    r   	__enter__zSystemLogging.__enter__Y   s/    <<0$))GtwwGDL||r   Nc                     | j                   k|t        j                  dd       | j                  j	                  d      xs t        j                         j                  | j                          d| _         yy)a	  
        Disable system logging when leaving the context.

        .. note:: If an exception is being handled when we leave the context a
                  warning message including traceback is logged *before* system
                  logging is disabled.
        Nz4Disabling system logging due to unhandled exception!T)exc_infologger)r   r   warningr   getlogging	getLoggerremoveHandler)r   exc_type	exc_value	tracebacks       r   __exit__zSystemLogging.__exit___   s_     <<##U`deWW[["9g&7&7&9HHVDL	 $r   NNN)__name__
__module____qualname____doc__r   r   r$    r   r   r   r   J   s    3	 r   r   c                    t               sy| xs
 t               } |xs t        j                         }|xs t        }t        |j                  dt                    }t        |t        |      \  }}|r|rft        di |}|rYt        j                  |||        |j                  t        j                  |             |j                  |       t!        ||       |S )au  
    Redirect :mod:`logging` messages to the system log (e.g. ``/var/log/syslog``).

    :param programname: The program name to embed in log messages (a string, defaults
                         to the result of :func:`~coloredlogs.find_program_name()`).
    :param fmt: The log format for system log messages (a string, defaults to
                :data:`DEFAULT_LOG_FORMAT`).
    :param logger: The logger to which the :class:`~logging.handlers.SysLogHandler`
                   should be connected (defaults to the root logger).
    :param level: The logging level for the :class:`~logging.handlers.SysLogHandler`
                  (defaults to :data:`.DEFAULT_LOG_LEVEL`). This value is coerced
                  using :func:`~coloredlogs.level_to_number()`.
    :param reconfigure: If :data:`True` (the default) multiple calls to
                        :func:`enable_system_logging()` will each override
                        the previous configuration.
    :param kw: Refer to :func:`connect_to_syslog()`.
    :returns: A :class:`~logging.handlers.SysLogHandler` object or
              :data:`None`. If an existing handler is found and `reconfigure`
              is :data:`False` the existing handler object is returned. If the
              connection to the system logging daemon fails :data:`None` is
              returned.

    As of release 15.0 this function uses :func:`is_syslog_supported()` to
    check whether system logging is supported and appropriate before it's
    enabled.

    .. note:: When the logger's effective level is too restrictive it is
              relaxed (refer to `notes about log levels`_ for details).
    Nlevel)r   fmtprogramnamer*   )is_syslog_supportedr	   r   r   DEFAULT_LOG_FORMATr
   r   r   r   match_syslog_handlerconnect_to_syslogr   installsetFormatter	Formatter
addHandlerr   )r.   r-   r   reconfigurer   r,   r   s          r   r   r   n   s    >  4!2!4K*w((*F

##CBFF7,=>?E%f.BKPOGVK#)b)%%g3KX  !2!23!78g&'Nr   c                    | s
t               } |$t        j                  j                  j                  }|t
        }t        j                  t        j                  dfD ]S  }t        ||       }|||d<   	 t        j                  j                  di |}|j                  t        |             |c S  y# t        $ r Y bw xY w)ae  
    Create a :class:`~logging.handlers.SysLogHandler`.

    :param address: The device file or network address of the system logging
                    daemon (a string or tuple, defaults to the result of
                    :func:`find_syslog_address()`).
    :param facility: Refer to :class:`~logging.handlers.SysLogHandler`.
                     Defaults to ``LOG_USER``.
    :param level: The logging level for the :class:`~logging.handlers.SysLogHandler`
                  (defaults to :data:`.DEFAULT_LOG_LEVEL`). This value is coerced
                  using :func:`~coloredlogs.level_to_number()`.
    :returns: A :class:`~logging.handlers.SysLogHandler` object or :data:`None` (if the
              system logging daemon is unavailable).

    The process of connecting to the system logging daemon goes as follows:

    - The following two socket types are tried (in decreasing preference):

       1. :data:`~socket.SOCK_RAW` avoids truncation of log messages but may
          not be supported.
       2. :data:`~socket.SOCK_STREAM` (TCP) supports longer messages than the
          default (which is UDP).
    N)facilityaddresssocktyper*   )find_syslog_addressr   handlersSysLogHandlerLOG_USERr   socketSOCK_RAWSOCK_STREAMdictsetLevelr
   IOError)r:   r9   r,   r;   r   r   s         r   r2   r2      s    0 %'##11::}!OOV%7%7=8W5%BzN	&&44:r:G _U34N >  	 	s   4B33	B?>B?c                     t         j                  dk(  r)t        j                  j	                  t
              rt
        S t        j                  j	                  t              rt        S dt        j                  j                  fS )a  
    Find the most suitable destination for system log messages.

    :returns: The pathname of a log device (a string) or an address/port tuple as
              supported by :class:`~logging.handlers.SysLogHandler`.

    On Mac OS X this prefers :data:`LOG_DEVICE_MACOSX`, after that :data:`LOG_DEVICE_UNIX`
    is checked for existence. If both of these device files don't exist the default used
    by :class:`~logging.handlers.SysLogHandler` is returned.
    darwin	localhost)
sysplatformospathexistsLOG_DEVICE_MACOSXLOG_DEVICE_UNIXr   r=   SYSLOG_UDP_PORTr*   r   r   r<   r<      sS     ||xBGGNN3D$E  		(G,,<<<<r   c                      t         j                  j                  d      } | t        |       S t	               xs
 t                S )aK  
    Determine whether system logging is supported.

    :returns:

        :data:`True` if system logging is supported and can be enabled,
        :data:`False` if system logging is not supported or there are good
        reasons for not enabling it.

    The decision making process here is as follows:

    Override
     If the environment variable ``$COLOREDLOGS_SYSLOG`` is set it is evaluated
     using :func:`~humanfriendly.coerce_boolean()` and the resulting value
     overrides the platform detection discussed below, this allows users to
     override the decision making process if they disagree / know better.

    Linux / UNIX
     On systems that are not Windows or MacOS (see below) we assume UNIX which
     means either syslog is available or sending a bunch of UDP packets to
     nowhere won't hurt anyone...

    Microsoft Windows
     Over the years I've had multiple reports of :pypi:`coloredlogs` spewing
     extremely verbose errno 10057 warning messages to the console (once for
     each log message I suppose) so I now assume it a default that
     "syslog-style system logging" is not generally available on Windows.

    Apple MacOS
     There's cPython issue `#38780`_ which seems to result in a fatal exception
     when the Python interpreter shuts down. This is (way) worse than not
     having system logging enabled. The error message mentioned in `#38780`_
     has actually been following me around for years now, see for example:

     - https://github.com/xolox/python-rotate-backups/issues/9 mentions Docker
       images implying Linux, so not strictly the same as `#38780`_.

     - https://github.com/xolox/python-npm-accel/issues/4 is definitely related
       to `#38780`_ and is what eventually prompted me to add the
       :func:`is_syslog_supported()` logic.

    .. _#38780: https://bugs.python.org/issue38780
    COLOREDLOGS_SYSLOG)rK   environr   r   r   r   )overrides    r   r/   r/      s;    X zz~~23Hh''L.HJ//r   c                 J    t        | t        j                  j                        S )aF  
    Identify system logging handlers.

    :param handler: The :class:`~logging.Handler` class to check.
    :returns: :data:`True` if the handler is a
              :class:`~logging.handlers.SysLogHandler`,
              :data:`False` otherwise.

    This function can be used as a callback for :func:`.find_handler()`.
    )
isinstancer   r=   r>   )r   s    r   r1   r1     s     gw//==>>r   )NNNTr%   )r)   r   logging.handlersrK   r@   rI   humanfriendlyr   humanfriendly.compatr   r   coloredlogsr   r   r   r	   r
   r   rN   rO   r0   r   r&   r   objectr   r   r2   r<   r/   r1   r*   r   r   <module>r\      s   ,   	  
 ) 5  &  < UN  
		8	$! F ! H5p*Z=&00f?r   