zalando-incubator / kopf

A Python framework to write Kubernetes operators in just few lines of code.
https://kopf.readthedocs.io
MIT License
970 stars 88 forks source link

Duplicate logs when using coloredlogs #310

Open mhamann opened 4 years ago

mhamann commented 4 years ago

Question

I'm using the coloredlogs library to format my log output. When it's enabled, I end up getting duplicate logs: one line from kopf's logging handler and one from the coloredlogs handler I configured.

Is there a way to get kopf to piggyback on my existing coloredlogs setup? (I imagine this would work for any existing Python logging setup, not just mine.)

Checklist

Keywords

nolar commented 4 years ago

Kopf injects its own logger in kopf.configure() based on --verbose, --debug, or --quiet CLI options. See the source code.

The easiest way would be to define your @kopf.on.startup() handler, and tweak the handlers of the root logger (logging.getLogger().handlers[:] = []). But few initial lines will be logged in the original setup anyway (before the startup handler is invoked).


Another way would be not to use kopf run CLI command, but define your own CLI entry point, and run the operator task yourselves. It should be as simple as this code, except that the options should be defined somehow by yourselves:

import kopf

@kopf.on.event(...)
def fn(...): ...

def main():
    # setup your logging here
    kopf.run(
        standalone=...,
        namespace=...,
        priority=...,
        peering_name=...,
        liveness_endpoint=...,
    )

Also see: embedding the operators if you want something even more advanced.


And yet another way would be adding a CLI option to Kopf itself, handled somewhere around these lines: https://github.com/zalando-incubator/kopf/blob/0.25/kopf/cli.py#L24-L34. And then, (re-)configuring your own logging on the module level statements or in @kopf.on.startup() handler.

E.g. --logging=none — which would also match with future --logging=json, --logging=plain, --logging=full (default), and other formats (see #44). With --logging=none, it can skip the configuration at all, and use the default Python logging, or whatever is configured otherwise.

See this diff for ideas (it was my experimentation branch — just ignore the part with JSON, look only at PLAIN/FULL formats).