Closed candlerb closed 4 years ago
Hmm, maybe this is a bad example. The fact that both exporter_exporter and snmp_exporter use a module
query-string argument is confusing.
EDIT: raised separately as #23
The point about error responses still stands. You can demonstrate it by missing a mandatory query string arg on snmp_exporter:
# curl -v localhost:9999/proxy?module=snmp
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9999 (#0)
> GET /proxy?module=snmp HTTP/1.1
> Host: localhost:9999
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Content-Type: text/plain; charset=utf-8
< X-Content-Type-Options: nosniff
< Date: Sat, 19 Oct 2019 09:41:44 GMT
< Content-Length: 103
<
An error has occurred while serving metrics:
text format parsing error in line 1: invalid metric name
* Connection #0 to host localhost left intact
In this case, tcpdump shows that the response from snmp_exporter was:
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Sat, 19 Oct 2019 09:43:05 GMT
Content-Length: 37
'target' parameter must be specified
Thanks for the report. We should be able to handle this better.
I've added support for reporting an error. Unfortunately, some of the internals mean that we cannot simply reforwarded all errors. As it stands, we should now at least report there is an error and not just report a parsing failure. Hopefully this helps a bit.
Great, thanks for that.
Aside: since at that point resp.Body has not been touched, presumably it would be possible to read (say) the first 1024 bytes and include it in the error message?
The problem is that it's promhttp.handler that calls the gatherer, so it's that that passes back the response. I could put a chunk of the Body in the error I give back to the promhttp handler, but that would be even uglier output than what we currently do.
When a backend gives an error status, it appears to confuse exporter_exporter.
Here is an example using snmp_exporter. If I talk to it directly with bad arguments, it returns a 400 status code and a useful message.
But using exporter_exporter:
Here is what I get:
I looks like exporter_exporter has attempted to parse the error message as a metric, and this in turn has caused a 500 internal server error.
I am not actually sure why exporter_exporter needs to parse metrics - why not pass the body through unchanged?
But in any case, when the backend returns a non-2xx code then I think that the backend response code and body should be passed through unchanged.