How to specify log levels using JSON format in Python


Hello, we would like to ask how to configure LOG_LEVEL of messages produced by python components?

We are using Nucleus(=2.5.3) with the following config:

    "logging": {
      "format": "JSON"

Please, consider the following Python script:

    print(f'This is an INFO message.', file=sys.stdout)
    print(f'This is an WARN message.', file=sys.stderr)

This produces the following two messages in the log file:

{"thread":"Copier","level":"INFO","eventType":"stdout","message":"This is an INFO message.","contexts":{"scriptName":"TEST.lifecycle.Run.Script","serviceName":"TEST","currentState":"RUNNING"},"loggerName":"TEST","timestamp":1646058300228,"cause":null}
{"thread":"Copier","level":"WARN","eventType":"stderr","message":"This is an WARN message.","contexts":{"scriptName":"TEST.lifecycle.Run.Script","serviceName":"TEST","currentState":"RUNNING"},"loggerName":"TEST","timestamp":1646058300228,"cause":null}

To our understanding, the field "level" in the JSON object is deduced from the file to which the log message is written:

  • stdout -> INFO

  • stderr -> WARN

We would like to be able to use all of the four different levels described in the GreenGrass Nucleus documentation (DEBUG, INFO, WARNING, ERROR).

What do we need to to to be able to log a message using level 'DEBUG' or 'ERROR' (i.e. the field "level" in the produced message has a value of "DEBUG" or "ERROR")?

Thank you kindly,

asked 2 years ago958 views
2 Answers

Hi Simon,

As you have determined, writing to stdout is logged at info and stderr is at warn. There is no way to use any different log levels in the Greengrass logger. You can certainly though using Python's builtin logging library to log to a file of your choosing which gives you full control over the log level and format.

answered 2 years ago

Hello, thank you for the quick reply.

Just to clarify - if we use the Python's logging module to log to the standard output, we can surely specify different logging levels:

    import logging

    logger = logging.getLogger()
    handler = logging.StreamHandler(sys.stdout)

    logger.debug('This is a debug')'This is an info')
    logger.warning('This is a warning')
    logger.error('This is an error')

The above code produces the following output. As we can notice, the field 'level' is set to 'INFO' in all of the entries (given that the stream handler is set to standard output). Is this indeed the expected behaviour?

{"thread":"Copier","level":"INFO","eventType":"stdout","message":"This is a debug","contexts":{"scriptName":"services.TEST.lifecycle.Run.Script","serviceName":"TEST","currentState":"RUNNING"},"loggerName":"TEST","timestamp":1646063970436,"cause":null}
{"thread":"Copier","level":"INFO","eventType":"stdout","message":"This is an info","contexts":{"scriptName":"services.TEST.lifecycle.Run.Script","serviceName":"TEST","currentState":"RUNNING"},"loggerName":"TEST","timestamp":1646063970436,"cause":null}
{"thread":"Copier","level":"INFO","eventType":"stdout","message":"This is a warning","contexts":{"scriptName":"services.TEST.lifecycle.Run.Script","serviceName":"TEST","currentState":"RUNNING"},"loggerName":"TEST","timestamp":1646063970436,"cause":null}
{"thread":"Copier","level":"INFO","eventType":"stdout","message":"This is an error","contexts":{"scriptName":"services.TEST.lifecycle.Run.Script","serviceName":"TEST","currentState":"RUNNING"},"loggerName":"TEST","timestamp":1646063970436,"cause":null}
answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions