使用Cloud Functions将AlertPolicy列表写入Cloud Storage报错处理问询
问题核心原因
你遇到的TypeError: Object of type AlertPolicy is not JSON serializable报错,是因为Google Cloud官方Python客户端返回的API响应是ProtoBuf生成的类实例,而非原生Python字典,无法直接被json.dumps序列化。
疑问解答
- 为什么API Explorer返回的是易处理的JSON,但客户端拿到的是AlertPolicy对象?
API底层接口确实返回JSON格式数据,但官方Python客户端为了提升开发体验,默认会将JSON响应反序列化为对应服务的Proto Message类实例,你可以直接通过点号访问属性(比如policy.name),不需要手动解析JSON,所以和API Explorer看到的纯JSON结构表现不同。 - 分页逻辑应该如何实现?
list_alert_policies返回的是Pager迭代器对象,默认已经封装了分页逻辑,你直接用for policy in policies迭代时,迭代器会自动检测是否有下一页、自动携带page_token拉取后续数据,绝大多数场景不需要手动处理分页。如果你需要控制每页拉取数量,可以在调用list_alert_policies时传入page_size参数即可。 - 为什么
print(policies)输出是每行一个元素的特殊格式?
Proto Message类默认实现了__str__方法,会将自身格式化为可读性高的多行类JSON字符串输出,方便开发调试,但这只是字符串表示,本质上变量还是Proto对象,不是JSON字符串也不是字典。 - 有没有通用的处理方案,还是需要单独适配该API?
有通用处理方案,所有Google Cloud Python客户端的Proto响应对象都自带to_dict()和to_json()两个方法,可以直接将对象转为原生Python字典或者JSON字符串,不需要针对每个API做特殊适配。 - 是否需要手动拼接JSON对象?
完全不需要手动拼接,使用自带的to_dict()或者to_json()方法即可,所有字段会和官方API定义完全对齐,不会出现字段遗漏、命名错误的问题。
修正后的可运行代码
from google.cloud import monitoring_v3 from google.cloud import storage import json def my_function(request): alert_client = monitoring_v3.AlertPolicyServiceClient() storage_client = storage.Client() project_name = 'projects/my_project' bucket_name = 'test' # 建议按业务规则命名文件,避免覆盖已有数据 destination_blob_name = 'alert_policies.json' # 迭代自动处理分页,拉取所有告警策略 policies = alert_client.list_alert_policies(name=project_name) # 转为原生字典列表,可直接序列化 policy_list = [policy.to_dict() for policy in policies] bucket = storage_client.bucket(bucket_name) blob = bucket.blob(destination_blob_name) # indent=2 生成格式化的JSON,方便后续查看 blob.upload_from_string( json.dumps(policy_list, indent=2), content_type='application/json' ) return '告警策略已同步至GCS', 200
补充注意事项
- 确保Cloud Functions的服务账号拥有Monitoring的
monitoring.alertPolicies.list权限,以及GCS存储桶的storage.objects.create权限 - 如果你需要每个告警策略单独存为一个文件,可以在循环内调用
policy.to_json()直接上传字符串,不需要再调用json.dumps
内容的提问来源于stack exchange,提问作者Simon Breton
相关产品推荐
相关产品推荐

