我使用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
答案 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_payload
是Any 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消息的使用。