1

I am using structlog - http://www.structlog.org/en/stable/ in my Python Project. I have one if the processors in the configuration to be

stdlib.add_logger_name

This adds the key in the event_dict to be logger. But, I want to change the key string to something else like namespace rather than logger. How can I do that?

I have checked the function for

stdlib.add_logger_name(logger, method_name, event_dict)

but that function uses hardcoded string logger as

event_dict["logger"] = logger.name
RSY
  • 51
  • 5
  • Why do you care which string it uses as key? Sounds like an XY problem - what are you actually trying to achieve? – mkrieger1 Aug 08 '19 at 19:54
  • All the logs will be added to Splunk in JSON format and I want to follow the convention used for namespace in other repos. In Python it is labelled as `logger` and I want it to be `namespace`. – RSY Aug 09 '19 at 03:41

2 Answers2

1

Currently, structlog.stdlib.add_logger_name() is 6 LoC, of which you most likely only need two:

def add_logger_name(logger, method_name, event_dict):
    """
    Add the logger name to the event dict.
    """
    record = event_dict.get("_record")
    if record is None:
        event_dict["logger"] = logger.name
    else:
        event_dict["logger"] = record.name
    return event_dict

Just copy and paste it and adapt it to your needs.

It wouldn't be worth it to add options to the processor and slow it down for everybody since it didn't come up until today, but structlog has been engineered purposefully to make such customizations easy.

hynek
  • 3,647
  • 1
  • 18
  • 26
  • Sorry, but I am totally new to this. Can I try adding a function in `structlog.configure_once(processors=[add_logger_name(logger, event_dict)])` This 'add_logger_name()' will be my function with these arguments to be passed, but I am not understanding how would I get the event_dict? I thought logger would be the logger created by structlog.get_logger(__name__). But, the object that get passed to the stdlib function is different. Can you please help me in this? My `wrapper_class=stdlib.BoundLogger` – RSY Aug 12 '19 at 14:53
  • No, you would add `add_loger_name`, the _function object_ to the processors list. Every callable in that list gets called with the three arguments you see there: `logger`, `method_name` and `even_dict`. – hynek Aug 12 '19 at 15:40
  • I tried this `stdlib.add_logger_name(logger, add_logger_name(logger, logger._initial_values), logger._initial_values),` where add_logger_name is a method defined in my file with same code and just added this `event_dict["namespace"]` in the function. I am not sure if the logger and event_dict that I am passing are the correct ones. I am getting an error - `event_dict = proc(self._logger, method_name, event_dict) TypeError: 'dict' object is not callable` – RSY Aug 12 '19 at 16:44
  • You _must not_ call whatever you're passing into `processors` if it's lower-case because that means that it's a function. You seem to still call it which makes the return value of the function the processor, which is in your case a dict which is not callable and gives you the error you've quoted. A processor is just a callable. If it's a function, just pass the function object. like `structlog.configure_once(processors=[add_logger_name])` – hynek Aug 13 '19 at 14:43
1

Thanks to hynek's answer. I solved this by adding a local function:

def add_logger_name(logger, method_name, event_dict):
    """
    Add the logger name to the event dict with namespace as the key as per logging convention
    """
    record = event_dict.get("_record")
    if record is None:
        event_dict["namespace"] = logger.name
    else:
        event_dict["namespace"] = record.name
    return event_dict

Setting this in the

processors=[add_logger_name,...]
RSY
  • 51
  • 5