4
\$\begingroup\$

I have a custom logger which logs all messages at WARNING level and above to a Slack channel. Certain error messages occur so frequently that they make it hard to see actual errors in the channel, so I would like to be able to disable Slack logging for a specific message, using something like logger.error("This is a common error", slack=False).

The following approach works, but I was wondering if there is a nicer way to do it. One downside of this approach is that if any code that isn't using my custom logger uses the slack=False argument then it will cause an exception.

def get_slack_logger():
    logger = logging.getLogger("slack_logger")
    logger.setLevel(logging.DEBUG)

    # Add other handlers like stderr and log file.
    # ...

    # Add an error handler for Slack notifications.
    class SlackHandler(logging.Handler):
        def __init__(self):
            super().__init__(self)

        def emit(self, record):
            if not record.slack:
                return
            # Actually send the contents of `record.message` to a Slack channel.
            # ...

    slack_handler = SlackHandler()
    slack_handler.setLevel(logging.WARNING)
    logger.addHandler(slack_handler)

    # Wrap logger in an adapter that handles the `slack` argument.
    class SlackToggleableAdapter(logging.LoggerAdapter):
        def __init__(self, logger, extra={}):
            super().__init__(logger, extra)

        def process(self, msg, kwargs):
            extra = kwargs.get("extra", {})
            extra.update({"slack": kwargs.pop("slack", True)})
            kwargs["extra"] = extra
            return (msg, kwargs)

    logger = SlackToggleableAdapter(logger)
    return logger
\$\endgroup\$
  • 1
    \$\begingroup\$ Why not use a lower level for those messages? \$\endgroup\$ – Janne Karila Jan 12 '17 at 6:50
  • \$\begingroup\$ Because I want the other handlers to receive them at error level. \$\endgroup\$ – DanielGibbs Jan 12 '17 at 7:03
  • \$\begingroup\$ Did you consider using a filter instead? \$\endgroup\$ – Gareth Rees Jan 14 '17 at 19:17
  • \$\begingroup\$ I don't think I can achieve the same effect using a filter can I? The Logger will throw an exception on the slack argument. \$\endgroup\$ – DanielGibbs Jan 14 '17 at 19:19
  • \$\begingroup\$ @DanielGibbs: You wouldn't need the slack argument if you had a filter. \$\endgroup\$ – Gareth Rees Jan 14 '17 at 21:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.