0

我将从我的数据管道生成的日志发送到 GCP 上的 Stackdriver。但由于某种原因,它发送了相同事件日志的多个副本。在我的ensure_stackdriver_logging函数中,我检查处理程序是否已经存在,以防止如果task重新运行处理程序将不会被多次添加的情况。有谁知道问题是什么?

def ensure_stackdriver_logging():
    logger = get_logger()
    lg_client = google.cloud.logging.Client()
    lg_handler = CloudLoggingHandler(lg_client, 'thinknum_etl_logging')
    if lg_handler not in logger.handlers:
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        lg_handler.setFormatter(formatter)
        logger.setLevel(logging.INFO)
        logger.addHandler(lg_handler)


def task():
    ensure_stackdriver_logging()
    ...

更新:

我也试过这个——

def ensure_stackdriver_logging():
    logger = get_logger()

    if hasattr(logger, 'initialized'):
        return logger
    else:
        setattr(logger, 'initialized', True)

    lg_client = google.cloud.logging.Client()
    lg_handler = CloudLoggingHandler(lg_client, 'thinknum_etl_logging')
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    lg_handler.setFormatter(formatter)
    logger.setLevel(logging.INFO)
    logger.addHandler(lg_handler)

但它没有用。

4

1 回答 1

0

如果您ensure_stackdriver_logging()在另一个地方调用该方法,甚至之前添加了一个记录器处理程序,它会发生两次(或更多),因为您的 if 检查没有按预期工作。

当您进行if lg_handler not in logger.handlers:检查时,会在对象 ID 和列表中的其他对象之间进行比较lg_handler,但是因为您刚刚lg_handler在列表之前的行中创建了它,所以它不会在列表中。

以此为例:

class Foo():
    pass

l = [Foo()]
b = Foo()
print(b in l)
>>> False

b不在列表中,因为b指向的对象不在列表中,而是Foo具有相同值的对象。

于 2020-08-05T16:49:39.267 回答