Duplicate log entries with Google Cloud Stackdriver logging of Python code on Kubernetes Engine

前端 未结 2 1072
一生所求
一生所求 2020-12-31 07:42

I have a simple Python app running in a container on Google Kubernetes Engine. I am trying to connect the standard Python logging to Google Stackdriver logging using this gu

相关标签:
2条回答
  • 2020-12-31 08:17

    Problem is in the way how logging client initializes root logger

        logger = logging.getLogger()
        logger.setLevel(log_level)
        logger.addHandler(handler)
        logger.addHandler(logging.StreamHandler())
    

    it adds default stream handler in addition to Stackdriver handler. My workaround for now is to initialize appropriate Stackdriver handler manually:

                # this basically manually sets logger compatible with GKE/fluentd
                # as LoggingClient automatically add another StreamHandler - so 
                # log records are duplicated
                from google.cloud.logging.handlers import ContainerEngineHandler
                formatter = logging.Formatter("%(message)s")
                handler = ContainerEngineHandler(stream=sys.stderr)
                handler.setFormatter(formatter)
                handler.setLevel(level)
                root = logging.getLogger()
                root.addHandler(handler)
                root.setLevel(level)
    
    
    0 讨论(0)
  • 2020-12-31 08:37

    I solved this problem by overwriting the handlers property on my root logger immediately after calling the setup_logging method

    import logging
    from google.cloud import logging as gcp_logging
    from google.cloud.logging.handlers import CloudLoggingHandler, ContainerEngineHandler, AppEngineHandler
    
    logging_client = gcp_logging.Client()
    logging_client.setup_logging(log_level=logging.INFO)
    root_logger = logging.getLogger()
    # use the GCP handler ONLY in order to prevent logs from getting written to STDERR
    root_logger.handlers = [handler
                            for handler in root_logger.handlers
                            if isinstance(handler, (CloudLoggingHandler, ContainerEngineHandler, AppEngineHandler))]
    

    To elaborate on this a bit, the client.setup_logging method sets up 2 handlers, a normal logging.StreamHandler and also a GCP-specific handler. So, logs will go to both stderr and Cloud Logging. You need to remove the stream handler from the handlers list to prevent the duplication.

    EDIT: I have filed an issue with Google to add an argument to to make this less hacky.

    0 讨论(0)
提交回复
热议问题