您可以设置 Cloud Logging 日志条目的格式,以便 Error Reporting 自动捕获和分组应用错误,从而帮助您监控和诊断各项服务中的问题。
使用 Cloud Logging 写入日志条目时,LogEntry 对象必须包含堆栈轨迹或格式化的 ReportedErrorEvent 对象。请按照以下部分中的说明设置文本载荷和 JSON 字段(例如 message、stack_trace 和 @type)的格式,以便 Error Reporting (when used with Stackdriver) 功能正确解析和分组错误事件。
准备工作
按照适用于您所用语言和平台的设置说明执行操作。
如果您需要基于 API 密钥的身份验证,则必须使用 Error Reporting API。如需使用 Error Reporting API 报告错误事件,请执行
report方法,并将该方法的请求正文格式设置为ReportedErrorEvent对象。使用 Error Reporting API 时,系统会自动生成包含具有适当格式设置的错误消息的日志条目,并将其写入 Cloud Logging。这些日志条目会写入
logName格式如下的日志:projects/PROJECT_ID/clouderrorreporting.googleapis.com%2Freported_errors
由于日志条目是通过对
report的调用生成的,因此可能会产生 Cloud Logging 注入费用。如需控制注入哪些日志条目,请参阅排除项过滤条件。如果您使用 Error Reporting API 报告错误事件,则本文档的其余部分不适用。
LogEntry 格式要求
本部分介绍如何设置 LogEntry 的格式,以便 Error Reporting 捕获日志条目中包含的错误事件。
记录堆栈轨迹
如需记录作为堆栈轨迹的错误事件,请将该错误事件编写为以下类型之一:
- 多行
textPayload。 包含
message、stack_trace或exception字段的jsonPayload。您可以指定多个此类字段。如果指定了多个此类字段,则评估顺序依次为:
stack_trace、exception、message。如果系统评估了
message字段,并且该字段不为空,则仅当该字段包含支持的编程语言格式之一的堆栈轨迹时,系统才会捕获堆栈轨迹。如果使用不受支持的格式,Error Reporting 将不会捕获堆栈轨迹。如果您的错误事件格式为
ReportedErrorEvent对象,请将其字段复制到jsonPayload。如需了解详情和示例,请参阅以ReportedErrorEvent对象的形式记录错误。不包含
message、stack_trace或exception字段,但包含堆栈轨迹的jsonPayload。Error Reporting (when used with Stackdriver) 会在
jsonPayload中搜索所有字段以查找堆栈轨迹。如果找到多个堆栈轨迹,则选择其中一个堆栈轨迹。选择算法可确保选择的一致性。
记录短信
如需记录文本消息形式的错误事件,请使用以下格式的 jsonPayload:
"jsonPayload": {
"@type": "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent",
"message": "Text message"
},
当您将 @type 字段设置为指定值时,Error Reporting 始终会评估日志条目,就好像所有必需字段都存在一样。因此,Error Reporting 会捕获该错误事件。
如果您将 @type 字段设置为其他值或将其保持为未设置状态,则 Cloud Logging 会搜索标记为 serviceContext 的字段,以确定载荷是否为 ReportedErrorEvent 对象。
如果 jsonPayload 的 message、stack_trace 或 exception 字段包含堆栈轨迹,则无需设置 @type 字段。在这种情况下,Error Reporting 会自动捕获错误事件。
支持的受监控资源
将 LogEntry 对象的 resource 字段设置为支持的受监控的资源类型之一:
app_script_functionaws_ec2_instancecloud_functioncloud_run_jobscloud_run_revisionconsumed_apicontainerdataflow_stepgae_appgce_instancek8s_containerk8s_podml_job1workflows.googleapis.com/Workflowglobal1
1 不支持 textPayload
示例
本部分展示了如何确保当日志条目包含文本消息或堆栈轨迹时,Error Reporting (when used with Stackdriver) 会处理该日志条目。
记录文本消息形式的错误事件
如需记录文本消息形式的错误事件,请使用以下 JSON 结构设置 jsonPayload 字段的 LogEntry 对象格式:
{...
{
"jsonPayload": {
"@type": "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent",
"message": "A simple text message"
},
"logName": "projects/test-project/logs/reported-error",
"resource": {
"labels": {
"project_id": "test-project"
},
"type": "global"
},
"severity": "ERROR",
"timestamp": "2019-06-27T13:43:26.375834551Z"
}
}
如示例所示,您必须将 @type 字段设置为强制 Error Reporting 分组日志条目的值。如需了解详情,请参阅记录文本消息。
当 message 字段包含堆栈轨迹时,日志条目会自动分组,因此您无需指定 @type 字段。
记录格式为 ReportedErrorEvent 对象的错误
如果您的错误事件存储在 ReportedErrorEvent 对象中,请针对 LogEntry 的 jsonPayload 字段使用以下 JSON 结构:
{
"eventTime": string,
"serviceContext": {
"service": string, // Required.
"version": string
},
"message": string, // Required. This field contains the main error content to report.
"@type": string, // Optional. For information about this field, see Log a text message.
"context": {
"httpRequest": {
"method": string,
"url": string,
"userAgent": string,
"referrer": string,
"responseStatusCode": number,
"remoteIp": string
},
"user": string,
"reportLocation": { // Required if no stack trace is provided.
"filePath": string,
"lineNumber": number,
"functionName": string
}
}
}
确保您使用错误信息填充 message 字段。
如需了解如何在 ReportedErrorEvent 对象的 message 字段中存储堆栈轨迹,请参阅 report 方法的参考页面。
以下示例展示了如何将 LogEntry 的 jsonPayload 字段设置为格式化为 ReportedErrorEvent 对象。
由于 message 字段包含堆栈轨迹,因此 Error Reporting 会对错误事件进行分组:
{...
"jsonPayload": {
"serviceContext": {
"service": "frontend",
"version": "bf6b5b09b9d3da92c7bf964ab1664fe751104517"
},
"message": "com.example.shop.Template$CartDiv retrieveCart: Error\njava.lang.IndexOutOfBoundsException: Index: 4, Size: 4\n\tat java.util.ArrayList.rangeCheck(ArrayList.java:635)\n\tat java.util.ArrayList.get(ArrayList.java:411)\n\tat com.example.shop.Cart.retrieve(Cart.java:76)\n\tat com.example.shop.Cart.generate(Cart.java:55)\n\tat com.example.shop.Template$CartDiv.retrieveCart(Template.java:113)\n\tat com.example.shop.Template.generate(Template.java:22)\n\tat com.example.shop.CartServlet.doGet(CartServlet.java:115)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:717)\n",
"context": {
"httpRequest": {
"method": "GET",
"url": "http://example.com/shop/cart",
"responseStatusCode": 500
},
"user": "9f32f587135aa6774e78ed30fbaabcce3ec5528f"
}
},
"logName": "projects/test-project/logs/reported-error",
"resource": {
"labels": {
"project_id": "test-project"
},
"type": "global"
},
"severity": "ERROR",
"timestamp": "2019-06-27T13:43:26.375834551Z"
}
使用 textPayload 字段记录错误事件
您可以使用 LogEntry 的 textPayload 字段来存储错误消息(例如堆栈轨迹),从而记录错误事件。例如,以下 Google Cloud CLI 命令会生成一个严重程度为 ERROR 的日志条目,该条目的 textPayload 字段包含一个错误事件:
gcloud logging write test-log --severity=ERROR --payload-type=text 'RuntimeException: Oops! Something bad happened. at com.example.MyClass.method(MyClass.java:123) at com.example.OtherClass.doStuff(Unknown Source) at com.example.Sys.create(Native Method)'
上一个命令的结果是一条按 Error Reporting (when used with Stackdriver) 分组的日志条目:
{...
logName: "projects/PROJECT_ID/logs/test-log"
severity: "ERROR"
textPayload: "RuntimeException: Oops! Something bad happened.
at com.example.MyClass.method(MyClass.java:123)
at com.example.OtherClass.doStuff(Unknown Source)
at com.example.Sys.create(Native Method)"
...
}