【问题标题】:Doing the equivalent of log_struct in python logger在 python 记录器中做相当于 log_struct
【发布时间】:2019-04-15 17:41:54
【问题描述】:

在谷歌示例中,它给出了以下内容:

logger.log_struct({
    'message': 'My second entry',
    'weather': 'partly cloudy',
})

我将如何在 python 的记录器中做同样的事情。例如:

import logging
log.info(
    msg='My second entry', 
    extra = {'weather': "partly cloudy"}
)

当我在 stackdriver 中查看时,额外的字段没有得到正确解析:

2018-11-12 15:41:12.366 PST
My second entry

Expand all | Collapse all 

{
 insertId:  "1de1tqqft3x3ri"  
 jsonPayload: {
  message:  "My second entry"   
  python_logger:  "Xhdoo8x"   
 }
 logName:  "projects/Xhdoo8x/logs/python"  
 receiveTimestamp:  "2018-11-12T23:41:12.366883466Z"  
 resource: {…}  
 severity:  "INFO"  
 timestamp:  "2018-11-12T23:41:12.366883466Z"  
}

我该怎么做?

我现在能做的最接近的是:

log.handlers[-1].client.logger('').log_struct("...")

但这仍然需要第二次调用...

【问题讨论】:

    标签: python python-3.x logging google-cloud-platform google-cloud-stackdriver


    【解决方案1】:

    目前无法做到这一点,see this open feature request on google-cloud-python 了解更多详情。

    【讨论】:

      【解决方案2】:

      目前的解决方案:

      更新 1 - 用户 Seth Nickell improved my proposed solution,所以我更新了这个答案,因为他的方法更好。以下是根据他在 GitHub 上的回复:

      https://github.com/snickell/google_structlog

      pip install google-structlog
      

      这样使用:

      import google_structlog
      
      google_structlog.setup(log_name="here-is-mylilapp")
      
      # Now you can use structlog to get searchable json details in stackdriver...
      import structlog
      logger = structlog.get_logger()
      logger.error("Uhoh, something bad did", moreinfo="it was bad", years_back_luck=5)
      
      # Of course, you can still use plain ol' logging stdlib to get { "message": ... } objects
      import logging
      logger = logging.getLogger("yoyo")
      logger.error("Regular logging calls will work happily too")
      
      # Now you can search stackdriver with the query:
      # logName: 'here-is-mylilapp'
      

      原答案:

      基于an answer from this GitHub thread,我使用以下bodge 将自定义对象记录为信息负载。它更多地来自原始_Worker.enqueue,并支持传递自定义字段。

      from google.cloud.logging import _helpers
      from google.cloud.logging.handlers.transports.background_thread import _Worker
      
      def my_enqueue(self, record, message, resource=None, labels=None, trace=None, span_id=None):
          queue_entry = {
              "info": {"message": message, "python_logger": record.name},
              "severity": _helpers._normalize_severity(record.levelno),
              "resource": resource,
              "labels": labels,
              "trace": trace,
              "span_id": span_id,
              "timestamp": datetime.datetime.utcfromtimestamp(record.created),
          }
      
          if 'custom_fields' in record:
              entry['info']['custom_fields'] = record.custom_fields
      
          self._queue.put_nowait(queue_entry)
      
      _Worker.enqueue = my_enqueue
      

      然后

      import logging
      from google.cloud import logging as google_logging
      
      logger = logging.getLogger('my_log_client')
      logger.addHandler(CloudLoggingHandler(google_logging.Client(), 'my_log_client'))
      
      logger.info('hello', extra={'custom_fields':{'foo': 1, 'bar':{'tzar':3}}})
      

      导致:

      这使得根据这些 custom_fields 进行过滤变得更加容易。

      让我们承认这不是好的编程,但在正式支持此功能之前,似乎没有什么可以做的。

      【讨论】:

      • bodge: '制作或修理(某事)糟糕或笨拙。'
      猜你喜欢
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 2013-08-06
      • 2013-01-10
      • 2019-05-17
      • 2011-01-09
      • 1970-01-01
      相关资源
      最近更新 更多