I'm using google cloud HTTP functions and it seems like cloud functions automatically writes a single log line for each response. When an error occurs, I'd have expected perhaps a snippet of the body response to be logged, but there's nothing besides the status code and response size.
Here's some example code:
func init() {
functions.HTTP("Scrape", ScrapeHTTP)
}
func Scrape(w http.ResponseWriter, r *http.Request) {
err := validateRequestData(r)
if err != nil {
// Doesn't actually log "my error message" in `textPayload` on logs.
http.Error(w, "my error message", http.StatusBadRequest)
return
}
}
Here's an example of what gets logged:
{
"insertId": "65aea4130000c5a9b9b6bad2",
"httpRequest": {
"requestMethod": "GET",
"requestUrl": "<removed>",
"requestSize": "1355",
"status": 500,
"responseSize": "782",
"userAgent": "Google-Cloud-Tasks",
"latency": "0.143171908s",
"protocol": "HTTP/1.1"
},
"resource": {
"type": "cloud_run_revision",
"labels": {
"project_id": "<removed>",
"location": "<removed>",
"revision_name": "<removed>",
"service_name": "scrape",
"configuration_name": "scrape"
}
},
"timestamp": "2024-01-22T17:21:22.905611Z",
"severity": "ERROR",
"labels": {
"goog-managed-by": "cloudfunctions",
"instanceId": "<removed>"
},
"logName": "projects/<removed>/logs/run.googleapis.com%2Frequests",
"trace": "<removed>",
"receiveTimestamp": "2024-01-22T17:21:23.141132352Z",
"spanId": "1278497214486517307"
}
I would have expected "my error message" to appear somewhere in the logs but it doesn't. Is there a way to get that logged besides manually logging the error using the logging library?
When a function times out, the same automatic log response line has a textPayload with the message: "The request has been terminated because it has reached the maximum request timeout.", so perhaps there's a way of passing a textPayload to http.Error?
Here's what
http.Errordoes:There's actually no special magic logging from google cloud functions, the log line I'm seeing is actually coming from
fmt.Fprintln(w, error).The solution is to actually simply write your own error function that writes structured logs. It's unfortunate that this practice is never mentioned anywhere in the documentation, which uses
http.Erroreverywhere.Thanks a lot for the hint, @JohnHanley!