-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add header to ease tracking HTTP requests #624
Conversation
Re: the header we're adding to HTTP request, do we think there might be a risk that some users are monitoring endpoints with strict header policies (e.g. reject requests with unexpected headers) and we could bust their SM check with this change? Might be a contrived corner case for most SM cases but just wondering if this wants a config to disable it? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this @The-9880 !
Overall it looks good. I made a couple of comments on whether it makes sense to move the header definition "one level up" and accept a more generic argument in the HTTP probe implementation. Let me know what do you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good, thanks.
I think there's some minor reorg to be made, but otherwise it's nice!
internal/prober/http/http.go
Outdated
for _, header := range check.Settings.Http.Headers { | ||
name, _ := strToHeaderNameValue(header) | ||
|
||
_, present := reservedHeaders[strings.ToLower(name)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of strings.ToLower
(which is fine in this context), you can use http.CanonicalHeaderKey
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this also means that the keys in reservedHeaders should be in canonical form, too.
internal/scraper/scraper.go
Outdated
@@ -114,13 +114,14 @@ func (d *probeData) Tenant() model.GlobalID { | |||
func New(ctx context.Context, check model.Check, publisher pusher.Publisher, probe sm.Probe, logger zerolog.Logger, | |||
scrapeCounter Incrementer, errorCounter IncrementerVec, k6runner k6runner.Runner, labelsLimiter LabelsLimiter, | |||
) (*Scraper, error) { | |||
checkProbeIdentifier := fmt.Sprintf("%d-%d", check.Id, probe.Id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be check.GlobalID()
(so that we can identify the region that the check belongs to)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See below, I think this logic should be part of prober.proberFactory.New
internal/scraper/scraper.go
Outdated
return NewWithOpts(ctx, check, ScraperOpts{ | ||
Probe: probe, | ||
Publisher: publisher, | ||
Logger: logger, | ||
ScrapeCounter: scrapeCounter, | ||
ErrorCounter: errorCounter, | ||
ProbeFactory: prober.NewProberFactory(k6runner), | ||
ProbeFactory: prober.NewProberFactory(k6runner, checkProbeIdentifier), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to remember hard why we had to add the runner here...
... and for that matter why a new factory needs to be created for each scraper, because the factory should be the same one for all scrapers, as it's stateless.
My gut feeling is that there's an existing mistake here and we shouldn't be compounding it. It's possibly true that scraper.New
should take a factory as an argument, and that factory should be initialized with the runner and the probe's ID and other global information. (but that's a change for a different issue)
I think the factory constructor (prober.NewProberFactory
) might take the probe ID as an argument, because that's independent of the check, and then the created factory should be able to take the check as an argument (as it does) and build the identifier for the check based on the probe ID and the check ID. The prober.proberFactory.New
basically takes the check that is passed as an argument, and it can build an identifier with the information it has for the checks that support it (Http and MultiHttp right now, but scripted checks in the future, too -- we will need to inject headers there so that HTTP connections use them).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense! Thanks for read here, I'd be happy to take a look into that issue later
internal/prober/http/http.go
Outdated
} | ||
|
||
for header, values := range reservedHeaders { | ||
headers = append(headers, fmt.Sprintf("%s:%s", header, strings.Join(values, ","))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that it's OK to have the same header present multiple times
If reservedHeaders has multiple values for a single key, what should be done is add the header multiple times, e.g.
for key, values := range reservedHeaders {
var b strings.Builder
for _, value := range values {
b.Reset()
b.WriteString(key)
b.WriteRune(':')
b.WriteString(value)
headers = append(headers, b.String())
}
}
for key, values := range reservedHeaders { | ||
updatedHeaders = append(updatedHeaders, &sm.HttpHeader{Name: key, Value: strings.Join(values, ",")}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the same comment about multiple values for the headers applies here
43b336b
to
cc22a6f
Compare
* Add an option to log multihttp responses (#550) * Update to grafana-build-tools v0.6.0 * Chore(deps): Bump golang.org/x/net from 0.20.0 to 0.21.0 * Chore(deps): Bump github.com/rs/zerolog from 1.31.0 to 1.32.0 * Chore(deps): Bump github.com/miekg/dns from 1.1.57 to 1.1.58 * Fix: add test for HTTP check with a long URL * Add tenant label limits (#581) * Release v0.20.0 (#613) * Fix global tenant id usage for label limits query * Release v0.20.1 * Feature: promote adhoc to permanent feature (#615) * Update release script (#617) * Chore(deps): Bump github.com/mccutchen/go-httpbin/v2 (#618) * Fix: missing http check regex validations (#612) * Release v0.20.2 (#620) * Chore(deps): Bump github.com/mccutchen/go-httpbin/v2 (#626) * change the name of the k6 check type to scripted (#622) * Chore(deps): Bump github.com/prometheus/client_model from 0.5.0 to 0.6.0 * Chore(deps): Bump google.golang.org/grpc from 1.61.0 to 1.61.1 * Chore(deps): Bump github.com/prometheus/common from 0.46.0 to 0.47.0 * Chore(deps): Bump github.com/prometheus/prometheus from 0.49.1 to 0.50.0 * Add header to ease tracking HTTP requests (#624) * Add telemetry protobuf definitions (#627) Signed-off-by: ka3de <[email protected]>
* Add an option to log multihttp responses (#550) * Update to grafana-build-tools v0.6.0 * Chore(deps): Bump golang.org/x/net from 0.20.0 to 0.21.0 * Chore(deps): Bump github.com/rs/zerolog from 1.31.0 to 1.32.0 * Chore(deps): Bump github.com/miekg/dns from 1.1.57 to 1.1.58 * Fix: add test for HTTP check with a long URL * Add tenant label limits (#581) * Release v0.20.0 (#613) * Fix global tenant id usage for label limits query * Release v0.20.1 * Feature: promote adhoc to permanent feature (#615) * Update release script (#617) * Chore(deps): Bump github.com/mccutchen/go-httpbin/v2 (#618) * Fix: missing http check regex validations (#612) * Release v0.20.2 (#620) * Chore(deps): Bump github.com/mccutchen/go-httpbin/v2 (#626) * change the name of the k6 check type to scripted (#622) * Chore(deps): Bump github.com/prometheus/client_model from 0.5.0 to 0.6.0 * Chore(deps): Bump google.golang.org/grpc from 1.61.0 to 1.61.1 * Chore(deps): Bump github.com/prometheus/common from 0.46.0 to 0.47.0 * Chore(deps): Bump github.com/prometheus/prometheus from 0.49.1 to 0.50.0 * Add header to ease tracking HTTP requests (#624) * Add telemetry protobuf definitions (#627) Signed-off-by: ka3de <[email protected]>
Addressing #325.
The goal is to add a header
x-sm-id
with a valuecheckId-probeId
so we can identify the owner of a check for anti-abuse purposes. This header gets added tohttp.Prober.config
.Happy to hear any suggestions on how to test this Go code better - testing
NewProber()
fromhttp_test.go
works to assert the resulting http config directly. but it'd be nicer to have a test server or something so I can add an HTTP check to a testUpdater
and validate the request headers sent.