logdna / python

A python package for sending logs to LogDNA
MIT License
48 stars 35 forks source link

"ValueError: incomplete format" when using %-symbol in the message #85

Closed dbartenstein closed 2 years ago

dbartenstein commented 2 years ago

From what I see in the docs, the meta parameter is passed to the log method using *args: log.warning("Warning message", {'app': 'bloop'}) https://docs.python.org/3/library/logging.html#logging.debug

With the following code fragment we run into a nasty error as it tries to do a substitution of the message:

>>> logging.warning('7.7%', {'meta': {'user': 5698}})
--- Logging error ---
Traceback (most recent call last):
  File "/usr/lib/python3.9/logging/__init__.py", line 1079, in emit
    msg = self.format(record)
  File "/usr/lib/python3.9/logging/__init__.py", line 923, in format
    return fmt.format(record)
  File "/usr/lib/python3.9/logging/__init__.py", line 659, in format
    record.message = record.getMessage()
  File "/usr/lib/python3.9/logging/__init__.py", line 363, in getMessage
    msg = msg % self.args
ValueError: incomplete format
Call stack:
  File "<stdin>", line 1, in <module>
Message: '7.7%'
Arguments: {'meta': {'user': 5698}}

Looking at the Python logging documentation, the extra parameter seems to be the proper way of doing it: https://docs.python.org/3/library/logging.html#logging.Logger.debug image

The way forward

logging.warning('7.7%', extra={'meta': {'user': 5698}}) currently does not send the meta data to LogDNA. image

That should be changed of course. Python libraries for other logging services do it exactly like that: https://docs.logtail.com/integrations/python

dkhokhlov commented 2 years ago

@dbartenstein here is working example:

        import logging
        import os
        from logdna import LogDNAHandler
        log = logging.getLogger('logdna')
        key = os.environ['LOGDNA_INGESTION_KEY']
        options = { 'custom_fields': 'meta' }
        custom = LogDNAHandler(key, options)
        log.addHandler(custom)
        log.setLevel(logging.INFO)
        log.warning('7.7%', extra={'meta': {'user': 5698}})

This line is critical in your case: options = { 'custom_fields': 'meta' }

You are right - the initial error was caused by missing 'extra='. We will fix the doc. Thanks.

dbartenstein commented 2 years ago

@dbartenstein here is working example:

        import logging
        import os
        from logdna import LogDNAHandler
        log = logging.getLogger('logdna')
        key = os.environ['LOGDNA_INGESTION_KEY']
        options = { 'custom_fields': 'meta' }
        custom = LogDNAHandler(key, options)
        log.addHandler(custom)
        log.setLevel(logging.INFO)
        log.warning('7.7%', extra={'meta': {'user': 5698}})

This line is critical in your case: options = { 'custom_fields': 'meta' }

You are right - the initial error was caused by missing 'extra='. We will fix the doc. Thanks.

@dkhokhlov thanks Dmitri! That works! Please update the doc accordingly and close this alleged issue.