"logging" --- Instalación de logging para Python
************************************************

**Source code:** Lib/logging/__init__.py


Important
^^^^^^^^^

Esta página contiene la información de referencia de la API. Para
información sobre tutorial y discusión de temas más avanzados, ver

* Tutorial básico

* Tutorial avanzado

* Libro de recetas de Logging

======================================================================

Este módulo define funciones y clases que implementan un sistema
flexible de logging de eventos para aplicaciones y bibliotecas.

El beneficio clave de tener la API de logging proporcionada por un
módulo de la biblioteca estándar es que todos los módulos de Python
pueden participar en el logging, por lo que el registro de su
aplicación puede incluir sus propios mensajes integrados con mensajes
de módulos de terceros.

The simplest example:

   >>> import logging
   >>> logging.warning('Watch out!')
   WARNING:root:Watch out!

The module provides a lot of functionality and flexibility.  If you
are unfamiliar with logging, the best way to get to grips with it is
to view the tutorials (**see the links above and on the right**).

Las clases básicas definidas por el módulo, junto con sus funciones,
se enumeran a continuación.

* Los loggers exponen la interfaz que el código de la aplicación usa
  directamente.

* Los gestores envían los registros (creados por los loggers) al
  destino apropiado.

* Los filtros proporcionan una facilidad de ajuste preciso para
  determinar que registros generar.

* Los formateadores especifican el diseño de los registros en el
  resultado final.


Objetos Logger
==============

Los loggers tienen los siguientes atributos y métodos. Tenga en cuenta
que los loggers *NUNCA* deben ser instanciados directamente, siempre a
través de la función de nivel de módulo "logging.getLogger(name)".
Múltiples llamadas a "getLogger()" con el mismo nombre siempre
retornarán una referencia al mismo objeto Logger.

El "name" es potencialmente un valor jerárquico separado por puntos,
como "foo.bar.baz" (aunque también podría ser simplemente "`foo", por
ejemplo). Los loggers que están más abajo en la lista jerárquica son
hijos de los loggers que están más arriba en la lista. Por ejemplo,
dado un logger con el nombre de "foo", los logger con los nombres de
"foo.bar", "foo.bar.baz" y "foo.bam" son descendientes de "foo". La
jerarquía del nombre del logger es análoga a la jerarquía del paquete
Python e idéntica si organiza los logger por módulo utilizando la
construcción recomendada "logging.getLogger(__name__)". Debido que en
un módulo, "__name__" es el nombre del módulo en el espacio de nombres
del paquete Python.

class logging.Logger

   propagate

      Si este atributo se evalúa como verdadero, los eventos
      registrados en este logger se pasarán a los gestores de los
      loggers de nivel superior (ancestro), además de los gestores
      asociados a este logger. Los mensajes se pasan directamente a
      los gestores de los loggers ancestrales; no se consideran ni el
      nivel ni los filtros de los loggers ancestrales en cuestión.

      Si esto se evalúa como falso, los mensajes de registro no se
      pasan a los gestores de los logger ancestrales.

      Spelling it out with an example: If the propagate attribute of
      the logger named "A.B.C" evaluates to true, any event logged to
      "A.B.C" via a method call such as
      "logging.getLogger('A.B.C').error(...)" will [subject to passing
      that logger's level and filter settings] be passed in turn to
      any handlers attached to loggers named "A.B", "A" and the root
      logger, after first being passed to any handlers attached to
      "A.B.C". If any logger in the chain "A.B.C", "A.B", "A" has its
      "propagate" attribute set to false, then that is the last logger
      whose handlers are offered the event to handle, and propagation
      stops at that point.

      El constructor establece este atributo en "True".

      Nota:

        Si adjunta un controlador a un logger *y* uno o más de sus
        ancestros, puede emitir el mismo registro varias veces. En
        general, no debería necesitar adjuntar un gestor a más de un
        logger; si solo lo adjunta al logger apropiado que está más
        arriba en la jerarquía del logger, verá todos los eventos
        registrados por todos los logger descendientes, siempre que la
        configuración de propagación sea "True". Un escenario común es
        adjuntar gestores solo al logger raíz y dejar que la
        propagación se encargue del resto.

   setLevel(level)

      Establece el umbral para este logger en *level*. Los mensajes de
      logging que son menos severos que *level* serán ignorados; los
      mensajes de logging que tengan un nivel de severidad *level* o
      superior serán emitidos por cualquier gestor o gestores que
      atiendan este logger, a menos que el nivel de un gestor haya
      sido configurado en un nivel de severidad más alto que *level*.

      Cuando se crea un logger, el nivel se establece en "NOTSET" (que
      hace que todos los mensajes se procesen cuando el logger es el
      logger raíz, o la delegación al padre cuando el logger no es un
      logger raíz). Tenga en cuenta que el logger raíz se crea con el
      nivel "WARNING".

      El término 'delegación al padre' significa que si un logger
      tiene un nivel de NOTSET, su cadena de logger ancestrales se
      atraviesa hasta que se encuentra un ancestro con un nivel
      diferente a NOTSET o se alcanza la raíz.

      Si se encuentra un antepasado con un nivel distinto de NOTSET,
      entonces el nivel de ese antepasado se trata como el nivel
      efectivo del logger donde comenzó la búsqueda de antepasados, y
      se utiliza para determinar cómo se maneja un evento de registro.

      Si se alcanza la raíz y tiene un nivel de NOTSET, se procesarán
      todos los mensajes. De lo contrario, el nivel de la raíz se
      utilizará como el nivel efectivo.

      Ver Niveles de logging para obtener una lista de niveles.

      Distinto en la versión 3.2: El parámetro *level* ahora acepta
      una representación de cadena del nivel como 'INFO' como
      alternativa a las constantes de enteros como "INFO". Sin
      embargo, tenga en cuenta que los niveles se almacenan
      internamente como e.j. "getEffectiveLevel()" y "isEnabledFor()"
      retornará/esperará que se pasen enteros.

   isEnabledFor(level)

      Indica si este logger procesará un mensaje de gravedad *level*.
      Este método verifica primero el nivel de nivel de módulo
      establecido por "logging.disable(level)" y luego el nivel
      efectivo del logger según lo determinado por
      "getEffectiveLevel()".

   getEffectiveLevel()

      Indica el nivel efectivo para este logger. Si se ha establecido
      un valor distinto de "NOTSET" utilizando "setLevel()", se
      retorna. De lo contrario, la jerarquía se atraviesa hacia la
      raíz hasta que se encuentre un valor que no sea "NOTSET" y se
      retorna ese valor. El valor retornado es un entero, típicamente
      uno de "logging.DEBUG", "logging.INFO" etc.

   getChild(suffix)

      Retorna un logger que es descendiente de este logger, según lo
      determinado por el sufijo. Por lo tanto,
      "logging.getLogger('abc').getChild('def.ghi')" retornaría el
      mismo logger que retornaría "logging.getLogger('abc.def.ghi')".
      Este es un método convenientemente útil cuando el logger
      principal se nombra usando e.j. "__name__" en lugar de una
      cadena literal.

      Nuevo en la versión 3.2.

   debug(msg, *args, **kwargs)

      Registra un mensaje con el nivel "DEBUG" en este logger. El
      *msg* es la cadena de formato del mensaje, y los *args* son los
      argumentos que se fusionan en *msg* utilizando el operador de
      formato de cadena. (Tenga en cuenta que esto significa que puede
      usar palabras clave en la cadena de formato, junto con un solo
      argumento de diccionario). No se realiza ninguna operación de
      formateo % en *msg* cuando no se suministran *args*.

      Hay cuatro argumentos de palabras clave *kwargs* que se
      inspeccionan: *exc_info*, *stack_info*, *stacklevel* y *extra*.

      Si *exc_info* no se evalúa como falso, hace que se agregue
      información de excepción al mensaje de registro. Si se
      proporciona una tupla de excepción (en el formato retornado por
      "sys.exc_info()") o se proporciona una instancia de excepción,
      se utiliza; de lo contrario, se llama a "sys.exc_info()" para
      obtener la información de excepción.

      El segundo argumento opcional con la palabra clave *stack_info*,
      que por defecto es "False". Si es verdadero, la información de
      la pila agregara el mensaje de registro, incluida la actual
      llamada del registro. Tenga en cuenta que esta no es la misma
      información de la pila que se muestra al especificar *exc_info*:
      la primera son los cuadros de la pila desde la parte inferior de
      la pila hasta la llamada de registro en el hilo actual, mientras
      que la segunda es la información sobre los cuadros de la pila
      que se han desenrollado, siguiendo una excepción, mientras busca
      gestores de excepción.

      Puede especificar *stack_info* independientemente de *exc_info*,
      por ejemplo solo para mostrar cómo llegaste a cierto punto en tu
      código, incluso cuando no se lanzaron excepciones. Los marcos de
      la pila se imprimen siguiendo una línea de encabezado que dice:

         Stack (most recent call last):

      Esto imita el "Traceback (most recent call last):" que se usa
      cuando se muestran marcos de excepción.

      El tercer argumento opcional con la palabra clave *stacklevel*,
      que por defecto es "1". Si es mayor que 1, se omite el número
      correspondiente de cuadros de pila al calcular el número de
      línea y el nombre de la función establecidos en "LogRecord"
      creado para el evento de registro. Esto se puede utilizar en el
      registro de ayudantes para que el nombre de la función, el
      nombre de archivo y el número de línea registrados no sean la
      información para la función/método auxiliar, sino más bien su
      llamador. El nombre de este parámetro refleja el equivalente en
      el modulo "warnings".

      El cuarto argumento de palabra clave es *extra*, que se puede
      usar para pasar un diccionario que se usa para completar el
      __dict__ de "LogRecord" creado para el evento de registro con
      atributos definidos por el usuario. Estos atributos
      personalizados se pueden usar a su gusto. Podrían incorporarse
      en mensajes registrados. Por ejemplo:

         FORMAT = '%(asctime)s %(clientip)-15s %(user)-8s %(message)s'
         logging.basicConfig(format=FORMAT)
         d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
         logger = logging.getLogger('tcpserver')
         logger.warning('Protocol problem: %s', 'connection reset', extra=d)

      imprimiría algo como

         2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset

      The keys in the dictionary passed in *extra* should not clash
      with the keys used by the logging system. (See the section on
      Atributos LogRecord for more information on which keys are used
      by the logging system.)

      Si elige usar estos atributos en los mensajes registrados, debe
      tener cuidado. En el ejemplo anterior, se ha configurado
      "Formatter" con una cadena de formato que espera *clientip* y
      'usuario' en el diccionario de atributos de "LogRecord". Si
      faltan, el mensaje no se registrará porque se producirá una
      excepción de formato de cadena. En este caso, siempre debe pasar
      el diccionario *extra* con estas teclas.

      Si bien esto puede ser molesto, esta función está diseñada para
      su uso en circunstancias especializadas, como servidores de
      subprocesos múltiples donde el mismo código se ejecuta en muchos
      contextos, y las condiciones interesantes que surgen dependen de
      este contexto (como la dirección IP del cliente remoto y
      autenticado nombre de usuario, en el ejemplo anterior). En tales
      circunstancias, es probable que se especialice "Formatter"s con
      particular "Handler"s.

      If no handler is attached to this logger (or any of its
      ancestors, taking into account the relevant "Logger.propagate"
      attributes), the message will be sent to the handler set on
      "lastResort".

      Distinto en la versión 3.2: Se agregó el parámetro *stack_info*.

      Distinto en la versión 3.5: El parámetro *exc_info* ahora puede
      aceptar instancias de excepción.

      Distinto en la versión 3.8: Se agregó el parámetro *stacklevel*.

   info(msg, *args, **kwargs)

      Registra un mensaje con el nivel "INFO" en este logger. Los
      argumentos se interpretan como "debug()".

   warning(msg, *args, **kwargs)

      Registra un mensaje con el nivel "WARNING" en este logger. Los
      argumentos se interpretan como "debug()".

      Nota:

        Hay un método obsoleto "warn" que es funcionalmente idéntico a
        "warning". Como "warn" está en desuso, no lo use, use
        "warning" en su lugar.

   error(msg, *args, **kwargs)

      Registra un mensaje con nivel "ERROR" en este logger. Los
      argumentos se interpretan como "debug()".

   critical(msg, *args, **kwargs)

      Registra un mensaje con el nivel "CRITICAL" en este logger. Los
      argumentos se interpretan como "debug()".

   log(level, msg, *args, **kwargs)

      Registra un mensaje con nivel entero *level* en este logger. Los
      otros argumentos se interpretan como "debug()".

   exception(msg, *args, **kwargs)

      Registra un mensaje con nivel "ERROR" en este logger. Los
      argumentos se interpretan como "debug()". La información de
      excepción se agrega al mensaje de registro. Este método solo
      debe llamarse desde un gestor de excepciones.

   addFilter(filter)

      Agrega el filtro *filter* especificado a este logger.

   removeFilter(filter)

      Elimina el filtro *filter* especificado de este logger.

   filter(record)

      Aplique los filtros de este logger al registro y retorna "True"
      si se va a procesar el registro. Los filtros se consultan a su
      vez, hasta que uno de ellos retorna un valor falso. Si ninguno
      de ellos retorna un valor falso, el registro será procesado
      (pasado a los gestores). Si se retorna un valor falso, no se
      produce más procesamiento del registro.

   addHandler(hdlr)

      Agrega el gestor especificado *hdlr* a este logger.

   removeHandler(hdlr)

      Elimina el gestor especificado *hdlr* de este logger.

   findCaller(stack_info=False, stacklevel=1)

      Encuentra el nombre de archivo de origen de la invoca y el
      número de línea. Retorna el nombre del archivo, el número de
      línea, el nombre de la función y la información de la pila como
      una tupla de 4 elementos. La información de la pila se retorna
      como "None" a menos que *stack_info* sea "True".

      El parámetro *stacklevel* se pasa del código que llama a
      "debug()" y otras API. Si es mayor que 1, el exceso se utiliza
      para omitir los cuadros de la pila antes de determinar los
      valores que se retornarán. Esto generalmente será útil al llamar
      a las API de registro desde un *helper/wrapper*, de modo que la
      información en el registro de eventos no se refiera al
      *helper/wrapper*, sino al código que lo llama.

   handle(record)

      Gestiona un registro pasándolo a todos los gestores asociados
      con este logger y sus antepasados (hasta que se encuentre un
      valor falso de *propagar*). Este método se utiliza para
      registros no empaquetados recibidos de un socket, así como para
      aquellos creados localmente. El filtrado a nivel de logger se
      aplica usando "filter()".

   makeRecord(name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)

      Este es un método *factory* que se puede sobreescribir en
      subclases para crear instancias especializadas "LogRecord".

   hasHandlers()

      Comprueba si este logger tiene algún controlador configurado.
      Esto se hace buscando gestores en este logger y sus padres en la
      jerarquía del logger. Retorna "True" si se encontró un gestor,
      de lo contrario, "False" . El método deja de buscar en la
      jerarquía cada vez que se encuentra un logger con el atributo
      *propagate* establecido en falso: ese será el último logger que
      verificará la existencia de gestores.

      Nuevo en la versión 3.2.

   Distinto en la versión 3.7: Los logger ahora se pueden serializar y
   deserializar (*pickled and unpickled*).


Niveles de logging
==================

Los valores numéricos de los niveles de logging se dan en la siguiente
tabla. Estos son principalmente de interés si desea definir sus
propios niveles y necesita que tengan valores específicos en relación
con los niveles predefinidos. Si define un nivel con el mismo valor
numérico, sobrescribe el valor predefinido; se pierde el nombre
predefinido.

+----------------+-----------------+
| Nivel          | Valor numérico  |
|================|=================|
| "CRITICAL"     | 50              |
+----------------+-----------------+
| "ERROR"        | 40              |
+----------------+-----------------+
| "WARNING"      | 30              |
+----------------+-----------------+
| "INFO"         | 20              |
+----------------+-----------------+
| "DEBUG"        | 10              |
+----------------+-----------------+
| "NOTSET"       | 0               |
+----------------+-----------------+


Gestor de objetos
=================

Los gestores tienen los siguientes atributos y métodos. Tenga en
cuenta que "Handler" nunca se instancia directamente; Esta clase actúa
como base para subclases más útiles. Sin embargo, el método
"__init__()" en las subclases debe llamar a "Handler.__init__()".

class logging.Handler

   __init__(level=NOTSET)

      Inicializa la instancia "Handler" estableciendo su nivel,
      configurando la lista de filtros en la lista vacía y creando un
      bloqueo (usando "createLock()") para serializar el acceso a un
      mecanismo de E/S.

   createLock()

      Inicializa un bloqueo de subprocesos que se puede utilizar para
      serializar el acceso a la funcionalidad de E/S subyacente que
      puede no ser segura para subprocesos.

   acquire()

      Adquiere el bloqueo de hilo creado con "createLock()".

   release()

      Libera el bloqueo de hilo adquirido con "acquire()".

   setLevel(level)

      Establece el umbral para este gestor en *level*. Los mensajes de
      registro que son menos severos que *level* serán ignorados.
      Cuando se crea un controlador, el nivel se establece en "NOTSET"
      (lo que hace que se procesen todos los mensajes).

      Ver Niveles de logging para obtener una lista de niveles.

      Distinto en la versión 3.2: El parámetro *level* ahora acepta
      una representación de cadena del nivel como 'INFO' como
      alternativa a las constantes de enteros como "INFO".

   setFormatter(fmt)

      Establece "Formatter" para este controlador en *fmt*.

   addFilter(filter)

      Agrega el filtro *filter* especificado a este gestor.

   removeFilter(filter)

      Elimina el filtro especificado *filter* de este gestor.

   filter(record)

      Aplique los filtros de este gestor al registro y retorna "True"
      si se va a procesar el registro. Los filtros se consultan a su
      vez, hasta que uno de ellos retorna un valor falso. Si ninguno
      de ellos retorna un valor falso, se emitirá el registro. Si uno
      retorna un valor falso, el controlador no emitirá el registro.

   flush()

      Asegúrese de que toda la salida de logging se haya vaciado. Esta
      versión no hace nada y está destinada a ser implementada por
      subclases.

   close()

      Poner en orden los recursos utilizados por el gestor. Esta
      versión no genera salida, pero elimina el controlador de una
      lista interna de gestores que se cierra cuando se llama a
      "shutdown()". Las subclases deben garantizar que esto se llame
      desde métodos "close()" sobreescritos.

   handle(record)

      Emite condicionalmente el registro especifico, según los filtros
      que se hayan agregado al controlador. Envuelve la actual emisión
      del registro con *acquisition/release* del hilo de bloqueo E/S.

   handleError(record)

      Este método debe llamarse desde los gestores cuando se encuentra
      una excepción durante una llamada a "emit()". Si el atributo de
      nivel de módulo "raiseExceptions" es `` False``, las excepciones
      se ignoran silenciosamente. Esto es lo que más se necesita para
      un sistema de registro: a la mayoría de los usuarios no les
      importan los errores en el sistema de registro, están más
      interesados en los errores de la aplicación. Sin embargo, puede
      reemplazar esto con un gestor personalizado si lo desea. El
      registro especificado es el que se estaba procesando cuando se
      produjo la excepción. (El valor predeterminado de
      "raiseExceptions" es `` True``, ya que es más útil durante el
      desarrollo).

   format(record)

      Formato para un registro - si se configura un formateador,
      úselo. De lo contrario, use el formateador predeterminado para
      el módulo.

   emit(record)

      Haga lo que sea necesario para registrar de forma especifica el
      registro. Esta versión está destinada a ser implementada por
      subclases y, por lo tanto, lanza un "NotImplementedError".

      Advertencia:

        This method is called after a handler-level lock is acquired,
        which is released after this method returns. When you override
        this method, note that you should be careful when calling
        anything that invokes other parts of the logging API which
        might do locking, because that might result in a deadlock.
        Specifically:

        * Logging configuration APIs acquire the module-level lock,
          and then individual handler-level locks as those handlers
          are configured.

        * Many logging APIs lock the module-level lock. If such an API
          is called from this method, it could cause a deadlock if a
          configuration call is made on another thread, because that
          thread will try to acquire the module-level lock *before*
          the handler-level lock, whereas this thread tries to acquire
          the module-level lock *after* the handler-level lock
          (because in this method, the handler-level lock has already
          been acquired).

Para obtener una lista de gestores incluidos como estándar, consulte
"logging.handlers".


Objetos formateadores
=====================

"Formatter" tiene los siguientes atributos y métodos. Son responsables
de convertir una "LogRecord" a (generalmente) una cadena que puede ser
interpretada por un sistema humano o externo. La base "Formatter"
permite especificar una cadena de formato. Si no se proporciona
ninguno, se utiliza el valor predeterminado de "'%(message)s'", que
solo incluye el mensaje en la llamada de registro. Para tener
elementos de información adicionales en la salida formateada (como una
marca de tiempo), siga leyendo.

Un formateador se puede inicializar con una cadena de formato que
utiliza el conocimiento de los atributos "LogRecord", como el valor
predeterminado mencionado anteriormente, haciendo uso del hecho de que
el mensaje y los argumentos del usuario están formateados previamente
en "LogRecord"'s con *message* como atributo. Esta cadena de formato
contiene claves de mapeo de Python %-style estándar. Ver la sección
Formateo de cadenas al estilo *printf* para obtener más información
sobre el formato de cadenas.

Las claves de mapeo útiles en a "LogRecord" se dan en la sección sobre
Atributos LogRecord.

class logging.Formatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)

   Retorna una nueva instancia de "Formatter". La instancia se
   inicializa con una cadena de formato para el mensaje en su
   conjunto, así como una cadena de formato para la porción fecha/hora
   de un mensaje. Si no se especifica *fmt*, se utiliza
   "'%(message)s'". Si no se especifica *datefmt*, se utiliza un
   formato que se describe en la documentación "formatTime()".

   El parámetro *style* puede ser uno de '%', '{'' o '$' y determina
   cómo se fusionará la cadena de formato con sus datos: usando uno de
   %-formatting, "str.format()" o "string.Template". Esto solo aplica
   al formato de cadenas de caracteres *fmt* (e.j. "'%(message)s'" o
   "{message}"), no al mensaje pasado actualmente al "Logger.debug"
   etc; ver Usar estilos de formato particulares en toda su aplicación
   para más información sobre usar {- y formateado-$ para mensajes de
   log.

   El parámetro *defaults* puede ser un diccionario con valores por
   defecto para usar en campos personalizados. Por ejemplo:
   "logging.Formatter('%(ip)s %(message)s', defaults={"ip": None})"

   Distinto en la versión 3.2: Se agregó el parámetro *style*.

   Distinto en la versión 3.8: Se agregó el parámetro *validate*. Si
   el estilo es incorrecto o no coincidente, *fmt* lanzará un
   "ValueError". Por ejemplo: "logging.Formatter('%(asctime)s -
   %(message)s', style='{')".

   Distinto en la versión 3.10: Se agregó el parámetro *defaults*.

   format(record)

      The record's attribute dictionary is used as the operand to a
      string formatting operation. Returns the resulting string.
      Before formatting the dictionary, a couple of preparatory steps
      are carried out. The *message* attribute of the record is
      computed using *msg* % *args*. If the formatting string contains
      "'(asctime)'", "formatTime()" is called to format the event
      time. If there is exception information, it is formatted using
      "formatException()" and appended to the message. Note that the
      formatted exception information is cached in attribute
      *exc_text*. This is useful because the exception information can
      be pickled and sent across the wire, but you should be careful
      if you have more than one "Formatter" subclass which customizes
      the formatting of exception information. In this case, you will
      have to clear the cached value (by setting the *exc_text*
      attribute to "None") after a formatter has done its formatting,
      so that the next formatter to handle the event doesn't use the
      cached value, but recalculates it afresh.

      Si la información de la pila está disponible, se agrega después
      de la información de la excepción, usando "formatStack()" para
      transformarla si es necesario.

   formatTime(record, datefmt=None)

      Este método debe ser llamado desde "format()" por un formateador
      que espera un tiempo formateado . Este método se puede
      reemplazar en formateadores para proporcionar cualquier
      requisito específico, pero el comportamiento básico es el
      siguiente: if *datefmt* (una cadena), se usa con
      "time.strftime()" para formatear el tiempo de creación del
      registro De lo contrario, se utiliza el formato '%Y-%m-%d
      %H:%M:%S,uuu', donde la parte *uuu* es un valor de milisegundos
      y las otras letras son "time.strftime()" . Un ejemplo de tiempo
      en este formato es "2003-01-23 00:29:50,411". Se retorna la
      cadena resultante.

      Esta función utiliza una función configurable por el usuario
      para convertir el tiempo de creación en una tupla. Por defecto,
      se utiliza "time.localtime()"; Para cambiar esto para una
      instancia de formateador particular, se agrega el atributo
      "converter" en una función con igual firma como
      "time.localtime()" o "time.gmtime()". Para cambiarlo en todos
      los formateadores, por ejemplo, si desea que todos los tiempos
      de registro se muestren en GMT, agregue el atributo "converter"
      en la clase "Formatter".

      Distinto en la versión 3.3: Anteriormente, el formato
      predeterminado estaba codificado como en este ejemplo:
      "2010-09-06 22:38:15,292" donde la parte anterior a la coma es
      manejada por una cadena de formato strptime ("'%Y-%m-%d
      %H:%M:%S'"), y la parte después de la coma es un valor de
      milisegundos. Debido a que strptime no tiene una posición de
      formato para milisegundos, el valor de milisegundos se agrega
      usando otra cadena de formato, "'%s,%03d'"--- ambas cadenas de
      formato se han codificado en este método. Con el cambio, estas
      cadenas se definen como atributos de nivel de clase que pueden
      *overridden* a nivel de instancia cuando se desee. Los nombres
      de los atributos son "default_time_format" (para una cadena de
      formato strptime) y "default_msec_format" (para agregar el valor
      de milisegundos).

      Distinto en la versión 3.9: El formato "default_msec_format"
      puede ser "None".

   formatException(exc_info)

      Formatea la información de una excepción especificada (una
      excepción como una tupla estándar es retornada por
      "sys.exc_info()") como una cadena. Esta implementación
      predeterminada solo usa "traceback.print_exception()". La cadena
      resultantes retornada.

   formatStack(stack_info)

      Formatea la información de una pila especificada (una cadena es
      retornada por "traceback.print_stack()", pero con la ultima
      línea removida) como una cadena. Esta implementación
      predeterminada solo retorna el valor de entrada.

class logging.BufferingFormatter(linefmt=None)

   A base formatter class suitable for subclassing when you want to
   format a number of records. You can pass a "Formatter" instance
   which you want to use to format each line (that corresponds to a
   single record). If not specified, the default formatter (which just
   outputs the event message) is used as the line formatter.

   formatHeader(records)

      Return a header for a list of *records*. The base implementation
      just returns the empty string. You will need to override this
      method if you want specific behaviour, e.g. to show the count of
      records, a title or a separator line.

   formatFooter(records)

      Return a footer for a list of *records*. The base implementation
      just returns the empty string. You will need to override this
      method if you want specific behaviour, e.g. to show the count of
      records or a separator line.

   format(records)

      Return formatted text for a list of *records*. The base
      implementation just returns the empty string if there are no
      records; otherwise, it returns the concatenation of the header,
      each record formatted with the line formatter, and the footer.


Filtro de Objetos
=================

Los "Manejadores" y los "Registradores" pueden usar los "Filtros" para
un filtrado más sofisticado que el proporcionado por los niveles. La
clase de filtro base solo permite eventos que están por debajo de
cierto punto en la jerarquía del logger. Por ejemplo, un filtro
inicializado con 'A.B' permitirá los eventos registrados por los
logger 'A.B', 'A.B.C', 'A.B.C.D', 'A.B.D' etc., pero no 'A.BB',
'B.A.B', etc. Si se inicializa con una cadena vacía, se pasan todos
los eventos.

class logging.Filter(name='')

   Retorna una instancia de la clase "Filter". Si se especifica
   *name*, nombra un logger que, junto con sus hijos, tendrá sus
   eventos permitidos a través del filtro. Si *name* es una cadena
   vacía, permite todos los eventos.

   filter(record)

      ¿Se apuntará el registro especificado? Retorna cero para no,
      distinto de cero para sí. Si se considera apropiado, el registro
      puede modificarse in situ mediante este método.

Tenga en cuenta que los filtros adjuntos a los gestores se consultan
antes de que el gestor emita un evento, mientras que los filtros
adjuntos a los loggers se consultan cada vez que se registra un evento
(usando "debug()", "info()", etc.), antes de enviar un evento a los
gestores. Esto significa que los eventos que han sido generados por
loggers descendientes no serán filtrados por la configuración del
filtro del logger, a menos que el filtro también se haya aplicado a
esos loggers descendientes.

En realidad, no se necesita la subclase "Filtro": se puede pasar
cualquier instancia que tenga un método de "filter" con la misma
semántica.

Distinto en la versión 3.2: No es necesario crear clases
especializadas de "Filter" ni usar otras clases con un método
"filter": puede usar una función (u otra invocable) como filtro. La
lógica de filtrado verificará si el objeto de filtro tiene un atributo
"filter": si lo tiene, se asume que es un "Filter" y se llama a su
método "filter()". De lo contrario, se supone que es invocable y se
llama con el registro como único parámetro. El valor retornado debe
ajustarse al retornado por "filter()".

Aunque los filtros se utilizan principalmente para filtrar registros
basados en criterios más sofisticados que los niveles, son capaces de
ver cada registro que es procesado por el gestor o logger al que están
adjuntos: esto puede ser útil si desea hacer cosas como contar cuántos
registros fueron procesados por un logger o gestor en particular, o
agregando, cambiando o quitando atributos en "LogRecord" que se está
procesando. Obviamente, el cambio de LogRecord debe hacerse con cierto
cuidado, pero permite la inyección de información contextual en los
registros (ver Usar filtros para impartir información contextual).


Objetos LogRecord
=================

Las instancias "LogRecord" son creadas automáticamente por "Logger"
cada vez que se registra algo, y se pueden crear manualmente a través
de "makeLogRecord()" (por ejemplo, a partir de un evento serializado
(*pickled*) recibido en la transmisión).

class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)

   Contiene toda la información pertinente al evento que se registra.

   The primary information is passed in *msg* and *args*, which are
   combined using "msg % args" to create the "message" attribute of
   the record.

   Parámetros:
      * **name** (*str*) -- The name of the logger used to log the
        event represented by this "LogRecord". Note that the logger
        name in the "LogRecord" will always have this value, even
        though it may be emitted by a handler attached to a different
        (ancestor) logger.

      * **level** (*int*) -- The numeric level of the logging event
        (such as "10" for "DEBUG", "20" for "INFO", etc). Note that
        this is converted to *two* attributes of the LogRecord:
        "levelno" for the numeric value and "levelname" for the
        corresponding level name.

      * **pathname** (*str*) -- The full string path of the source
        file where the logging call was made.

      * **lineno** (*int*) -- El número de línea en el archivo de
        origen donde se realizó la llamada logging.

      * **msg** (*typing.Any*) -- The event description message, which
        can be a %-format string with placeholders for variable data,
        or an arbitrary object (see Usando objetos arbitrarios como
        mensajes).

      * **args** (*tuple | dict**[**str**, **typing.Any**]*) -- Datos
        variables para fusionar en el argumento *msg* para obtener la
        descripción del evento.

      * **exc_info** (*tuple**[**type**[**BaseException**]**,
        **BaseException**, **types.TracebackType**] **| None*) -- An
        exception tuple with the current exception information, as
        returned by "sys.exc_info()", or "None" if no exception
        information is available.

      * **func** (*str | None*) -- El nombre de la función o método
        desde el que se invocó la llamada de logging.

      * **sinfo** (*str | None*) -- Una cadena de texto que representa
        la información de la pila desde la base de la pila en el hilo
        actual, hasta la llamada de logging.

   getMessage()

      Retorna el mensaje para la instancia "LogRecord" después de
      fusionar cualquier argumento proporcionado por el usuario con el
      mensaje. Si el argumento del mensaje proporcionado por el
      usuario para la llamada de logging no es una cadena de
      caracteres, se invoca "str()" para convertirlo en una cadena.
      Esto permite el uso de clases definidas por el usuario como
      mensajes, cuyo método "__str__" puede retornar la cadena de
      formato real que se utilizará.

   Distinto en la versión 3.2: La creación de "LogRecord" se ha hecho
   más configurable al proporcionar una fábrica que se utiliza para
   crear el registro. La fábrica se puede configurar usando
   "getLogRecordFactory()" y "setLogRecordFactory()" (ver esto para la
   firma de la fábrica).

   Esta funcionalidad se puede utilizar para inyectar sus propios
   valores en "LogRecord" en el momento de la creación. Puede utilizar
   el siguiente patrón:

      old_factory = logging.getLogRecordFactory()

      def record_factory(*args, **kwargs):
          record = old_factory(*args, **kwargs)
          record.custom_attribute = 0xdecafbad
          return record

      logging.setLogRecordFactory(record_factory)

   Con este patrón, se podrían encadenar varias fábricas y, siempre
   que no sobrescriban los atributos de las demás o se sobrescriban
   involuntariamente los atributos estándar enumerados anteriormente,
   no debería haber sorpresas.


Atributos LogRecord
===================

El LogRecord tiene una serie de atributos, la mayoría de los cuales se
derivan de los parámetros del constructor. (Tenga en cuenta que los
nombres no siempre se corresponden exactamente entre los parámetros
del constructor de LogRecord y los atributos de LogRecord). Estos
atributos pueden utilizarse para combinar los datos del registro en la
cadena de formato. La siguiente tabla enumera (en orden alfabético)
los nombres de los atributos, sus significados y el correspondiente
marcador de posición en una cadena de formato de estilo con %.

Si utilizas formato-{} ("str.format()"), puedes usar "{attrname}" como
marcador de posición en la cadena de caracteres de formato. Si está
utilizando formato-$ ("string.Template"), use la forma "${attrname}".
En ambos casos, por supuesto, reemplace` *attrname`* con el nombre de
atributo real que desea utilizar.

En el caso del formato-{}, puede especificar *flags* de formato
colocándolos después del nombre del atributo, separados con dos
puntos. Por ejemplo: un marcador de posición de "{msecs:03d}"
formateará un valor de milisegundos de "4" como "004". Consulte la
documentación "str.format()" para obtener detalles completos sobre las
opciones disponibles.

+------------------+---------------------------+-------------------------------------------------+
| Nombre del       | Formato                   | Descripción                                     |
| atributo         |                           |                                                 |
|==================|===========================|=================================================|
| args             | No debería necesitar      | La tupla de argumentos se fusionó en "msg" para |
|                  | formatear esto usted      | producir un "messsage", o un dict cuyos valores |
|                  | mismo.                    | se utilizan para la fusión (cuando solo hay un  |
|                  |                           | argumento y es un diccionario).                 |
+------------------+---------------------------+-------------------------------------------------+
| asctime          | "%(asctime)s"             | Fecha y Hora en formato legible por humanos     |
|                  |                           | cuando se creó "LogRecord". De forma            |
|                  |                           | predeterminada, tiene el formato '2003-07-08    |
|                  |                           | 16: 49: 45,896' (los números después de la coma |
|                  |                           | son milisegundos).                              |
+------------------+---------------------------+-------------------------------------------------+
| created          | "%(created)f"             | Tiempo en que se creó "LogRecord" (según lo     |
|                  |                           | retornado por "time.time()").                   |
+------------------+---------------------------+-------------------------------------------------+
| exc_info         | No debería necesitar      | Tupla de excepción (al modo "sys.exc_info") o,  |
|                  | formatear esto usted      | si no se ha producido ninguna excepción,        |
|                  | mismo.                    | "None".                                         |
+------------------+---------------------------+-------------------------------------------------+
| filename         | "%(filename)s"            | Parte del nombre de archivo de "pathname".      |
+------------------+---------------------------+-------------------------------------------------+
| funcName         | "%(funcName)s"            | Nombre de la función que contiene la llamada de |
|                  |                           | logging.                                        |
+------------------+---------------------------+-------------------------------------------------+
| levelname        | "%(levelname)s"           | Texto de nivel de logging para el mensaje       |
|                  |                           | ("'DEBUG'", "'INFO'", "'WARNING'", "'ERROR'",   |
|                  |                           | "'CRITICAL'").                                  |
+------------------+---------------------------+-------------------------------------------------+
| levelno          | "%(levelno)s"             | Número de nivel de logging para el mensaje      |
|                  |                           | ("DEBUG", "INFO", "WARNING", "ERROR",           |
|                  |                           | "CRITICAL").                                    |
+------------------+---------------------------+-------------------------------------------------+
| lineno           | "%(lineno)d"              | Número de línea original donde se emitió la     |
|                  |                           | llamada de logging (si está disponible).        |
+------------------+---------------------------+-------------------------------------------------+
| message          | "%(message)s"             | El mensaje registrado, computado como "msg %    |
|                  |                           | args". Esto se establece cuando se invoca       |
|                  |                           | "Formatter.format()".                           |
+------------------+---------------------------+-------------------------------------------------+
| module           | "%(module)s"              | Módulo (parte del nombre de "filename").        |
+------------------+---------------------------+-------------------------------------------------+
| msecs            | "%(msecs)d"               | Porción de milisegundos del tiempo en que se    |
|                  |                           | creó "LogRecord".                               |
+------------------+---------------------------+-------------------------------------------------+
| msg              | No debería necesitar      | La cadena de caracteres de formato pasada en la |
|                  | formatear esto usted      | llamada logging original. Se fusionó con "args" |
|                  | mismo.                    | para producir un "message", o un objeto         |
|                  |                           | arbitrario (ver Usando objetos arbitrarios como |
|                  |                           | mensajes).                                      |
+------------------+---------------------------+-------------------------------------------------+
| name             | "%(name)s"                | Nombre del logger usado para registrar la       |
|                  |                           | llamada.                                        |
+------------------+---------------------------+-------------------------------------------------+
| pathname         | "%(pathname)s"            | Nombre de ruta completo del archivo de origen   |
|                  |                           | donde se emitió la llamada de logging (si está  |
|                  |                           | disponible).                                    |
+------------------+---------------------------+-------------------------------------------------+
| process          | "%(process)d"             | ID de proceso (si está disponible).             |
+------------------+---------------------------+-------------------------------------------------+
| processName      | "%(processName)s"         | Nombre del proceso (si está disponible).        |
+------------------+---------------------------+-------------------------------------------------+
| relativeCreated  | "%(relativeCreated)d"     | Tiempo en milisegundos cuando se creó el        |
|                  |                           | LogRecord, en relación con el tiempo en que se  |
|                  |                           | cargó el módulo logging.                        |
+------------------+---------------------------+-------------------------------------------------+
| stack_info       | No debería necesitar      | Apila la información del marco (si está         |
|                  | formatear esto usted      | disponible) desde la parte inferior de la pila  |
|                  | mismo.                    | en el hilo actual hasta la llamada de registro  |
|                  |                           | que dio como resultado la generación de este    |
|                  |                           | registro.                                       |
+------------------+---------------------------+-------------------------------------------------+
| thread           | "%(thread)d"              | ID de hilo (si está disponible).                |
+------------------+---------------------------+-------------------------------------------------+
| threadName       | "%(threadName)s"          | Nombre del hilo (si está disponible).           |
+------------------+---------------------------+-------------------------------------------------+

Distinto en la versión 3.1: *processName* fue agregado.


Objetos LoggerAdapter
=====================

Las instancias "LoggerAdapter" se utilizan para pasar convenientemente
información contextual en las llamadas de logging. Para ver un ejemplo
de uso, consulte la sección sobre agregar información contextual a su
salida de logging.

class logging.LoggerAdapter(logger, extra)

   Retorna una instancia de "LoggerAdapter" inicializada con una
   instancia subyacente "Logger" y un objeto del tipo *dict*.

   process(msg, kwargs)

      Modifica el mensaje y/o los argumentos de palabra clave pasados
      a una llamada de logging para insertar información contextual.
      Esta implementación toma el objeto pasado como *extra* al
      constructor y lo agrega a *kwargs* usando la clave 'extra'. El
      valor de retorno es una tupla (*msg*, *kwargs*) que tiene las
      versiones (posiblemente modificadas) de los argumentos pasados.

Además de lo anterior, "LoggerAdapter" admite los siguientes métodos
de "Logger": "debug()", "info()", "warning()", "error()",
"exception()", "critical()", "log()", "isEnabledFor()",
"getEffectiveLevel()", "setLevel()" y "hasHandlers()". Estos métodos
tienen las mismas firmas que sus contrapartes en "Logger", por lo que
puede usar los dos tipos de instancias indistintamente.

Distinto en la versión 3.2: Los métodos "isEnabledFor()",
"getEffectiveLevel()", "setLevel()" y "hasHandlers()" se agregaron a
"LoggerAdapter" . Estos métodos se delegan al logger subyacente.

Distinto en la versión 3.6: Se añadieron el atributo Attribute
"manager" y el método "_log()", que delegan al logger subyacente y
permiten que los adaptadores se aniden.


Seguridad del hilo
==================

El módulo logging está diseñado para ser seguro para subprocesos sin
que sus clientes tengan que realizar ningún trabajo especial. Lo logra
mediante el uso de bloqueos de hilos; hay un bloqueo para serializar
el acceso a los datos compartidos del módulo, y cada gestor también
crea un bloqueo para serializar el acceso a su E/S subyacente.

Si está implementando gestores de señales asíncronos usando el módulo
"signal", es posible que no pueda usar logging desde dichos gestores.
Esto se debe a que las implementaciones de bloqueo en el módulo
"threading" no siempre son reentrantes y, por lo tanto, no se pueden
invocar desde dichos gestores de señales.


Funciones a nivel de módulo
===========================

Además de las clases descritas anteriormente, hay una serie de
funciones a nivel de módulo.

logging.getLogger(name=None)

   Retorna un logger con el nombre especificado o, si el nombre es
   "None", retorna un logger que es el logger principal de la
   jerarquía. Si se especifica, el nombre suele ser un nombre
   jerárquico separado por puntos como *'a'*, *'a.b'* or *'a.b.c.d'*.
   La elección de estos nombres depende totalmente del desarrollador
   que utiliza logging.

   Todas las llamadas a esta función con un nombre dado retornan la
   misma instancia de logger. Esto significa que las instancias del
   logger nunca necesitan pasar entre diferentes partes de una
   aplicación.

logging.getLoggerClass()

   Retorna ya sea la clase estándar "Logger", o la última clase pasada
   a "setLoggerClass()". Esta función se puede llamar desde una nueva
   definición de clase, para garantizar que la instalación de una
   clase personalizada "Logger" no deshaga las *customizaciones* ya
   aplicadas por otro código. Por ejemplo:

      class MyLogger(logging.getLoggerClass()):
          # ... override behaviour here

logging.getLogRecordFactory()

   Retorna un invocable que se usa para crear una "LogRecord".

   Nuevo en la versión 3.2: Esta función se ha proporcionado, junto
   con "setLogRecordFactory()", para permitir a los desarrolladores un
   mayor control sobre cómo "LogRecord" representa un evento logging
   construido.

   Consulte "setLogRecordFactory()" para obtener más información sobre
   cómo se llama a la fábrica.

logging.debug(msg, *args, **kwargs)

   Registra un mensaje con el nivel "DEBUG" en el logger raíz. *msg *
   es la cadena de carácteres de formato del mensaje y *args* son los
   argumentos que se fusionan en *msg* usando el operador de formato
   de cadena. (Tenga en cuenta que esto significa que puede utilizar
   palabras clave en la cadena de formato, junto con un único
   argumento de diccionario).

   Hay tres argumentos de palabras clave en *kwargs* que se
   inspeccionan: *exc_info* que, si no se evalúa como falso, hace que
   se agregue información de excepción al mensaje de registro. Si se
   proporciona una tupla de excepción (en el formato retornado por
   "sys.exc_info()") o una instancia de excepción, se utiliza; de lo
   contrario, se llama a "sys.exc_info()" para obtener la información
   de la excepción.

   El segundo argumento opcional con la palabra clave *stack_info*,
   que por defecto es "False". Si es verdadero, la información de la
   pila agregara el mensaje de registro, incluida la actual llamada
   del registro. Tenga en cuenta que esta no es la misma información
   de la pila que se muestra al especificar *exc_info*: la primera son
   los cuadros de la pila desde la parte inferior de la pila hasta la
   llamada de registro en el hilo actual, mientras que la segunda es
   la información sobre los cuadros de la pila que se han
   desenrollado, siguiendo una excepción, mientras busca gestores de
   excepción.

   Puede especificar *stack_info* independientemente de *exc_info*,
   por ejemplo solo para mostrar cómo llegaste a cierto punto en tu
   código, incluso cuando no se lanzaron excepciones. Los marcos de la
   pila se imprimen siguiendo una línea de encabezado que dice:

      Stack (most recent call last):

   Esto imita el "Traceback (most recent call last):" que se usa
   cuando se muestran marcos de excepción.

   El tercer argumento de palabra clave opcional es *extra* que se
   puede usar para pasar un diccionario que se usa para completar el
   __dict__ de LogRecord creado para el evento de registro con
   atributos definidos por el usuario. Estos atributos personalizados
   se pueden utilizar como desee. Por ejemplo, podrían incorporarse a
   mensajes registrados. Por ejemplo:

      FORMAT = '%(asctime)s %(clientip)-15s %(user)-8s %(message)s'
      logging.basicConfig(format=FORMAT)
      d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
      logging.warning('Protocol problem: %s', 'connection reset', extra=d)

   imprimiría algo como:

      2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset

   Las claves en el diccionario pasado *extra* no deben entrar en
   conflicto con las claves utilizadas por el sistema de registro.
   (Ver la documentación de "Formatter" para obtener más información
   sobre qué claves utiliza el sistema de registro).

   Si opta por utilizar estos atributos en los mensajes registrados,
   debemos tener cuidado. En el caso anterior, por ejemplo,
   "Formatter" se ha configurado con una cadena de caracteres de
   formato que espera 'clientip' y 'user' en el diccionario de
   atributos de LogRecord. Si faltan, el mensaje no se registrará
   porque se producirá una excepción de formato de cadena. Entonces,
   en este caso, siempre debe pasar el diccionario *extra* con estas
   claves.

   Si bien esto puede ser molesto, esta función está diseñada para su
   uso en circunstancias especializadas, como servidores de
   subprocesos múltiples donde el mismo código se ejecuta en muchos
   contextos, y las condiciones interesantes que surgen dependen de
   este contexto (como la dirección IP del cliente remoto y
   autenticado nombre de usuario, en el ejemplo anterior). En tales
   circunstancias, es probable que se especialice "Formatter"s con
   particular "Handler"s.

   This function (as well as "info()", "warning()", "error()" and
   "critical()") will call "basicConfig()" if the root logger doesn't
   have any handler attached.

   Distinto en la versión 3.2: Se agregó el parámetro *stack_info*.

logging.info(msg, *args, **kwargs)

   Registra un mensaje con nivel "INFO" en el logger raíz. Los
   argumentos se interpretan como "debug()".

logging.warning(msg, *args, **kwargs)

   Registra un mensaje con nivel "WARNING" en el logger raíz. Los
   argumentos se interpretan como "debug()".

   Nota:

     Hay una función obsoleta *warn`* que es funcionalmente idéntica a
     "warning". Como "warn" está deprecado, por favor no lo use, use
     "warning" en su lugar.

logging.error(msg, *args, **kwargs)

   Registra un mensaje con nivel "ERROR" en el logger raíz. Los
   argumentos se interpretan como "debug()".

logging.critical(msg, *args, **kwargs)

   Registra un mensaje con nivel "CRITICAL" en el logger raíz. Los
   argumentos se interpretan como "debug()".

logging.exception(msg, *args, **kwargs)

   Registra un mensaje con nivel "ERROR" en el logger raíz. Los
   argumentos se interpretan como "debug()". Se agrega información de
   excepción al mensaje de logging. Esta función solo se debe llamar
   desde un gestor de excepciones.

logging.log(level, msg, *args, **kwargs)

   Registra un mensaje con nivel *level* en el logger raíz. Los
   argumentos restantes se interpretan como "debug()".

logging.disable(level=CRITICAL)

   Proporciona un nivel superior de *level* para todos los loggers que
   tienen prioridad sobre el propio nivel del logger. Cuando surge la
   necesidad de reducir temporalmente la salida de logging en toda la
   aplicación, esta función puede resultar útil. Su efecto es
   deshabilitar todas las llamadas de gravedad *level* e inferior, de
   modo que si lo llaman con un valor de INFO, todos los eventos INFO
   y DEBUG se descartarán, mientras que los de gravedad WARNING y
   superiores se procesarán de acuerdo con el nivel efectivo del
   logger. Si se llama a "logging.disable(logging.NOTSET)" , elimina
   efectivamente este nivel primordial, de modo que la salida del
   registro depende nuevamente de los niveles efectivos de los loggers
   individuales.

   Tenga en cuenta que si ha definido un nivel de logging
   personalizado superior a "CRITICAL" (esto no es recomendado), no
   podrá confiar en el valor predeterminado para el parámetro *level*,
   pero tendrá que proporcionar explícitamente un valor adecuado.

   Distinto en la versión 3.7: El parámetro *level* se estableció por
   defecto en el nivel "CRITICAL". Consulte el Issue #28524 para
   obtener más información sobre este cambio.

logging.addLevelName(level, levelName)

   Asocia nivel *level* con el texto *levelName* en un diccionario
   interno, que se utiliza para asignar niveles numéricos a una
   representación textual, por ejemplo, cuando "Formatter" formatea un
   mensaje. Esta función también se puede utilizar para definir sus
   propios niveles. Las únicas restricciones son que todos los niveles
   utilizados deben registrarse utilizando esta función, los niveles
   deben ser números enteros positivos y deben aumentar en orden
   creciente de severidad.

   Nota:

     Si está pensando en definir sus propios niveles, consulte la
     sección sobre Niveles personalizados.

logging.getLevelName(level)

   Retorna la representación textual o numérica del nivel de registro
   *level*.

   Si *level* es uno de los niveles predefinidos "CRITICAL", "ERROR",
   "WARNING", "INFO" o "DEBUG" entonces se obtiene la cadena
   correspondiente. Si has asociado niveles con nombres usando
   "addLevelName()" entonces se retorna el nombre que has asociado con
   *level*. Si se pasa un valor numérico correspondiente a uno de los
   niveles definidos, se retorna la representación de cadena
   correspondiente.

   El parámetro *level* también acepta una representación de cadena
   del nivel como, por ejemplo, "INFO". En estos casos, esta función
   retorna el correspondiente valor numérico del nivel.

   Si no se pasa un valor numérico o de cadena que coincida, se
   retorna la cadena de caracteres 'Level %s' % nivel.

   Nota:

     Los niveles internamente son números enteros (ya que deben
     compararse en la lógica de logging). Esta función se utiliza para
     convertir entre un nivel entero y el nombre del nivel que se
     muestra en la salida de logging formateado mediante el
     especificador de formato "%(levelname)s" (ver Atributos
     LogRecord).

   Distinto en la versión 3.4: En las versiones de Python anteriores a
   la 3.4, esta función también podría pasar un nivel de texto y
   retornaría el valor numérico correspondiente del nivel. Este
   comportamiento indocumentado se consideró un error y se eliminó en
   Python 3.4, pero se restableció en 3.4.2 debido a que conserva la
   compatibilidad con versiones anteriores.

logging.makeLogRecord(attrdict)

   Crea y retorna una nueva instancia "LogRecord" cuyos atributos
   están definidos por *attrdict*. Esta función es útil para tomar un
   diccionario de atributos serializado (*pickled*) "LogRecord",
   enviado a través de un socket, y reconstituido como una instancia
   "LogRecord" en el extremo receptor.

logging.basicConfig(**kwargs)

   Realiza una configuración básica para el sistema de logging creando
   una "StreamHandler" con un "Formatter" predeterminado y agregándolo
   al logger raíz. Las funciones "debug()", "info()", "warning()",
   "error()" y "critical()" llamarán "basicConfig()" automáticamente
   si no se definen gestores para el logger raíz.

   Esta función no hace nada si el logger raíz ya tiene gestores
   configurados, a menos que el argumento de palabra clave *force*
   esté establecido como "True".

   Nota:

     Esta función debe llamarse desde el hilo principal antes de que
     se inicien otros hilos. En las versiones de Python anteriores a
     2.7.1 y 3.2, si se llama a esta función desde varios subprocesos,
     es posible (en raras circunstancias) que se agregue un gestor al
     logger raíz más de una vez, lo que genera resultados inesperados
     como mensajes duplicados en el registro.

   Se admiten los siguientes argumentos de palabras clave.

   +----------------+-----------------------------------------------+
   | Formato        | Descripción                                   |
   |================|===============================================|
   | *filename*     | Specifies that a "FileHandler" be created,    |
   |                | using the specified filename, rather than a   |
   |                | "StreamHandler".                              |
   +----------------+-----------------------------------------------+
   | *filemode*     | Si se especifica *filename*, abre el archivo  |
   |                | en mode. Por defecto es "'a'".                |
   +----------------+-----------------------------------------------+
   | *format*       | Utiliza la cadena de caracteres de formato    |
   |                | especificada para el gestor.Los atributos por |
   |                | defecto son "levelname", "name" y "message"   |
   |                | separado por dos puntos.                      |
   +----------------+-----------------------------------------------+
   | *datefmt*      | Utiliza el formato de fecha/hora              |
   |                | especificado, aceptado por "time.strftime()". |
   +----------------+-----------------------------------------------+
   | *style*        | Si *format* es especificado, utilice este     |
   |                | estilo para la cadena de caracteres de        |
   |                | formato. Uno de "'%'", "'{'" o "'$'" para     |
   |                | printf- style, "str.format()" o               |
   |                | "string.Template" respectivamente. El valor   |
   |                | predeterminado es "'%'".                      |
   +----------------+-----------------------------------------------+
   | *level*        | Establece el nivel del logger raíz en el      |
   |                | level especificado.                           |
   +----------------+-----------------------------------------------+
   | *stream*       | Utiliza la secuencia especificada para        |
   |                | inicializar "StreamHandler". Tenga en cuenta  |
   |                | que este argumento es incompatible con        |
   |                | *filename* - si ambos están presentes, se     |
   |                | lanza un "ValueError".                        |
   +----------------+-----------------------------------------------+
   | *handlers*     | Si se especifica, debe ser una iteración de   |
   |                | los gestores ya creados para agregar al       |
   |                | logger raíz. A cualquier gestor que aún no    |
   |                | tenga un formateador configurado se le        |
   |                | asignará el formateador predeterminado creado |
   |                | en esta función. Tenga en cuenta que este     |
   |                | argumento es incompatible con *filename* o    |
   |                | *stream*; si ambos están presentes, se lanza  |
   |                | un "ValueError".                              |
   +----------------+-----------------------------------------------+
   | *force*        | Si este argumento de palabra clave se         |
   |                | especifica como verdadero, los gestores       |
   |                | existentes adjuntos al logger raíz se         |
   |                | eliminan y cierran antes de llevar a cabo la  |
   |                | configuración tal como se especifica en los   |
   |                | otros argumentos.                             |
   +----------------+-----------------------------------------------+
   | *encoding*     | If this keyword argument is specified along   |
   |                | with *filename*, its value is used when the   |
   |                | "FileHandler" is created, and thus used when  |
   |                | opening the output file.                      |
   +----------------+-----------------------------------------------+
   | *errors*       | If this keyword argument is specified along   |
   |                | with *filename*, its value is used when the   |
   |                | "FileHandler" is created, and thus used when  |
   |                | opening the output file. If not specified,    |
   |                | the value 'backslashreplace' is used. Note    |
   |                | that if "None" is specified, it will be       |
   |                | passed as such to "open()", which means that  |
   |                | it will be treated the same as passing        |
   |                | 'errors'.                                     |
   +----------------+-----------------------------------------------+

   Distinto en la versión 3.2: Se agregó el argumento *style*.

   Distinto en la versión 3.3: Se agregó el argumento *handlers*. Se
   agregaron verificaciones adicionales para detectar situaciones en
   las que se especifican argumentos incompatibles (por ejemplo,
   *handlers* junto con *stream* o *filename*, o *stream* junto con
   *filename*).

   Distinto en la versión 3.8: Se agregó el argumento *force*.

   Distinto en la versión 3.9: Se han añadido los argumentos
   *encoding* y *errors*.

logging.shutdown()

   Informa al sistema de logging para realizar un apagado ordenado
   descargando y cerrando todos los gestores. Esto se debe llamar al
   salir de la aplicación y no se debe hacer ningún uso posterior del
   sistema de logging después de esta llamada.

   Cuando se importa el módulo de logging, registra esta función como
   un gestor de salida (ver "atexit"), por lo que normalmente no es
   necesario hacerlo manualmente.

logging.setLoggerClass(klass)

   Le dice al sistema de logging que use la clase *klass* al crear una
   instancia de un logger. La clase debe definir "__init__()" tal que
   solo se requiera un argumento de nombre, y "__init__()" debe llamar
   "Logger.__init__()". Por lo general, esta función se llama antes de
   cualquier loggers sea instanciado por las aplicaciones que
   necesitan utilizar un comportamiento de logger personalizado.
   Después de esta llamada, como en cualquier otro momento, no cree
   instancias de loggers directamente usando la subclase: continúe
   usando la API "logging.getLogger()" para obtener sus loggers.

logging.setLogRecordFactory(factory)

   Establece un invocable que se utiliza para crear "LogRecord".

   Parámetros:
      **factory** -- La fábrica invocable que se utilizará para crear
      una instancia de un registro.

   Nuevo en la versión 3.2: Esta función se ha proporcionado, junto
   con "getLogRecordFactory()", para permitir a los desarrolladores un
   mayor control sobre cómo se construye "LogRecord" que representa un
   evento de logging.

   La fábrica tiene la siguiente firma:

   "factory(name, level, fn, lno, msg, args, exc_info, func=None,
   sinfo=None, **kwargs)"

      name:
         El nombre del logger.

      level:
         El nivel de logging (numérico).

      fn:
         El nombre de ruta completo del archivo donde se realizó la
         llamada de logging.

      lno:
         El número de línea en el archivo donde se realizó la llamada
         de logging.

      msg:
         El mensaje de logging.

      args:
         Los argumentos para el mensaje de logging.

      exc_info:
         Una tupla de excepción o "None".

      func:
         El nombre de la función o método que invocó la llamada de
         logging.

      sinfo:
         Un seguimiento de pila como el que proporciona
         "traceback.print_stack()", que muestra la jerarquía de
         llamadas.

      kwargs:
         Argumentos de palabras clave adicionales.


Atributos a nivel de módulo
===========================

logging.lastResort

   Un "gestor de último recurso" está disponible a través de este
   atributo. Esta es una "StreamHandler" que escribe en``sys.stderr``
   con un nivel "WARNING", y se usa para gestionar eventos de logging
   en ausencia de cualquier configuración de logging. El resultado
   final es simplemente imprimir el mensaje en "sys.stderr". Esto
   reemplaza el mensaje de error anterior que decía que "no se
   pudieron encontrar gestores para el logger XYZ". Si necesita el
   comportamiento anterior por alguna razón, "lastResort" se puede
   configurar en "None".

   Nuevo en la versión 3.2.


Integración con el módulo de advertencias
=========================================

La función "captureWarnings()" se puede utilizar para integrar
"logging" con el módulo "warnings".

logging.captureWarnings(capture)

   Esta función se utiliza para activar y desactivar la captura de
   advertencias (*warnings*).

   Si *capture* es "True", las advertencias emitidas por el módulo
   "warnings" serán redirigidas al sistema de logging.
   Específicamente, una advertencia se formateará usando
   "warnings.formatwarning()" y la cadena de caracteres resultante se
   registrará en un logger  llamado "'py.warnings'" con severidad
   "WARNING".

   Si *capture* es "False", la redirección de advertencias al sistema
   de logging se detendrá y las advertencias serán redirigidas a sus
   destinos originales (es decir, aquellos en vigor antes de que se
   llamara a "captureWarnings(True)").

Ver también:

  Módulo "logging.config"
     API de configuración para el módulo logging.

  Módulo "logging.handlers"
     Gestores útiles incluidos con el módulo logging.

  **PEP 282** - A Logging System
     La propuesta que describió esta característica para su inclusión
     en la biblioteca estándar de Python.

  Paquete logging original de Python
     Esta es la fuente original del paquete "logging". La versión del
     paquete disponible en este sitio es adecuada para usar con Python
     1.5.2, 2.1.xy 2.2.x, que no incluyen el paquete "logging" en la
     biblioteca estándar.
