使用Python查询GCP Stackdriver日志

时间:2018-05-11 23:54:42

标签: google-bigquery stackdriver google-cloud-stackdriver google-cloud-python google-cloud-logging

我使用Python3查询Stackdriver的GCP日志。不幸的是,具有重要数据的日志条目将作为" NoneType"返回给我。而不是作为" dict"或者" str"。由此产生的" entry.payload"是类型"无"和" entry.payload_pb"有我想要的数据,但它是乱码。

有没有办法让Stackdriver以干净的格式返回这些数据,还是有办法解析它? 如果没有,有没有办法我应该查询这个数据比我正在做的更好并产生干净的数据?

我的代码看起来像这样:

#!/usr/bin/python3

from google.cloud.logging import Client, ASCENDING, DESCENDING
from google.oauth2.service_account import Credentials

projectName = 'my_project'
myFilter = 'logName="projects/' + projectName + '/logs/compute.googleapis.com%2Factivity_log"'

client = Client(project = projectName)
entries = client.list_entries(order_by=DESCENDING, page_size = 500, filter_ = myFilter)
for entry in entries:
    if isinstance(entry.payload, dict):
        print(entry.payload)
    if isinstance(entry.payload, str):
        print(entry.payload)
    if isinstance(entry.payload, None):
        print(entry.payload_pb)

" entry.payload_pb"数据总是这样开始:

type_url: "type.googleapis.com/google.cloud.audit.AuditLog"
 value: "\032;\n9gcp-user@my-project.iam.gserviceaccount.com"I\n\r129.105.16.28\0228

4 个答案:

答案 0 :(得分:1)

如果有人遇到同样的问题,我的解决方法如下:

1)下载并安装protobuf。我在使用brew(brew install protobuf)的mac上做了这个 2)下载并安装grpcio。我使用了pip install grpcio
3)将“Google API”下载到已知目录。我用/ tmp和这个命令git clone https://github.com/googleapis/googleapis
4)将目录更改为您刚刚在步骤3中下载的存储库的根目录 5)使用protoc构建python存储库。这个命令对我有用protoc -I=/tmp/googleapis/ --python_out=/tmp/ /tmp/googleapis/google/cloud/audit/audit_log.proto
6)您的audit_log_pb2.py文件存在于/tmp/audit_log_pb2.py中 7)将此文件放在正确的路径中或与脚本位于同一目录中 8)将此行添加到脚本中的导入中:
import audit_log_pb2
9)在我这样做之后,Protobuf条目的entry.payload部分始终填充了dicts。

请注意:您应该使用以下命令protoc验证您正在使用的protoc --version版本。你真的想使用protoc 3.x,因为我们构建的文件来自规范的第3版。我在Linux机器上安装的Ubuntu软件包是版本2,这有点令人沮丧。此外,尽管此文件是为Python 2.x构建的,但它似乎可以与Python 3.x一起使用。

答案 1 :(得分:1)

实际上我错过了,但是您可以通过将环境变量gRPC设置为非空字符串(例如,将dict禁用,并使API返回GOOGLE_CLOUD_DISABLE_GRPC(JSON)负载)。 GOOGLE_CLOUD_DISABLE_GRPC=true

这将填充payload而不是payload_pb-比编译可能过期的原型缓冲区更容易!

答案 2 :(得分:0)

LogEntry.proto_payloadAny message,它编码其他一些原型缓冲区消息。 proto消息的类型由type_url表示,消息正文序列化为value字段。识别出类型后,您可以使用类似

的类型对其进行反序列化
from google.cloud.audit import AuditLog
...

audit_log = AuditLog()
audit_log.ParseFromString(entry.payload_pb.value)

https://github.com/googleapis/googleapis/blob/master/google/cloud/audit/audit_log.proto上的AuditLog消息和相应的Python definitions can be built using the protoc compiler

请注意,AuditLog邮件的某些字段也可以包含其他Any邮件。 https://cloud.google.com/logging/docs/audit/api/

有更多详情

答案 3 :(得分:0)

我遵循@ rhinestone-cowguy的答案,但认为示例用法将帮助找到此答案的人们。要使用编译后的(原始)代码:

from google.cloud import logging
import audit_log_pb2

client = logging.Client()
PROJECT_IDS = ["one-project", "another-project"]

for entry in client.list_entries(projects=PROJECT_IDS):  # API call(s)

    # The proto payload is an Any message.
    audit_log = audit_log_pb2.AuditLog()
    entry.payload.Unpack(audit_log)
    print(audit_log)

Python Generated Code中记录了对Any消息的使用。