-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Prometheus remote write endpoint #16609
Conversation
Signed-off-by: chrismark <[email protected]>
Signed-off-by: chrismark <[email protected]>
Signed-off-by: chrismark <[email protected]>
Signed-off-by: chrismark <[email protected]>
If it is not urgent, please wait until go modules is merged. It is a huge effort to keep |
Cool! No problem on waiting! |
Signed-off-by: chrismark <[email protected]>
Signed-off-by: chrismark <[email protected]>
fb85033
to
0adda8c
Compare
Signed-off-by: chrismark <[email protected]>
Signed-off-by: chrismark <[email protected]>
@exekias any feedback at this point would be more than welcome. It is becoming quite big but we can split it in smaller PRs like so:
|
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.
Left a few comments, I like where things are going!
@@ -0,0 +1,577 @@ | |||
# -*- coding: utf-8 -*- |
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.
is this file needed?
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 is required by the python tests: https://github.com/elastic/beats/pull/16609/files#diff-f0fbea18a4681afd920cb91b903d03d2R6
return p.labels.String() | ||
} | ||
|
||
func samplesToEvents(metrics model.Samples) map[string]mb.Event { |
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 understand Samples will always be untyped right? For example, we won't be able to differenciate a histogram metric from a gauge
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.
Prometheus sends data with writerequest using this proto. Not sure if we can retrieve the type of the metric in an easy way 🤔
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 guess this is going to be an issue with histograms? Should we do a best-effort guess if it includes metrics with some special labels and/or suffixes?
if !math.IsNaN(val) && !math.IsInf(val, 0) { | ||
events = append(events, PromEvent{ | ||
data: common.MapStr{ | ||
name: val, | ||
}, | ||
labels: labels, | ||
timestamp: metric.Timestamp.Time(), | ||
}) | ||
} | ||
} | ||
|
||
// join metrics with same labels in a single event | ||
eventList := map[string]mb.Event{} | ||
|
||
for _, promEvent := range events { | ||
labelsHash := promEvent.LabelsHash() | ||
if _, ok := eventList[labelsHash]; !ok { | ||
eventList[labelsHash] = mb.Event{ | ||
ModuleFields: common.MapStr{ | ||
"metrics": common.MapStr{}, | ||
}, | ||
} | ||
|
||
// Add labels | ||
if len(promEvent.labels) > 0 { | ||
eventList[labelsHash].ModuleFields["labels"] = promEvent.labels | ||
} | ||
} | ||
|
||
// Not checking anything here because we create these maps some lines before | ||
e := eventList[labelsHash] | ||
e.Timestamp = promEvent.timestamp | ||
e.ModuleFields["metrics"].(common.MapStr).Update(promEvent.data) | ||
} |
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 can probably be optimized, by storing events already indexed by label hash, so only an insert is needed
// was an error creating the MetricSet then an error will be returned. The | ||
// returned MetricSet must also implement either EventFetcher or EventsFetcher | ||
// (but not both). | ||
type HandlerFactory func(h *HttpServer) func(writer http.ResponseWriter, req *http.Request) |
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.
Do you really need a factory? The metricset is already initializing the server, so you could pass a private metricset.handleFunc
which implements func(writer http.ResponseWriter, req *http.Request)
func (h *HttpEvent) SetEvent(event common.MapStr) { | ||
h.event = event | ||
} |
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.
Having that you are now passing a custom handler when initializing (which I think is a good idea), do you need an HttpEvent construct anymore? This was used to pass data between a generic HTTP server and the metricset. But now the metricset is in control of the requests, and can directly build and send events to the output. That should make things simpler, WDYT?
Signed-off-by: chrismark <[email protected]>
0cfcdbc
to
d052651
Compare
Signed-off-by: chrismark <[email protected]>
Note: In order to confirm that |
Signed-off-by: chrismark <[email protected]>
Signed-off-by: chrismark <[email protected]>
return p.labels.String() | ||
} | ||
|
||
func samplesToEvents(metrics model.Samples) map[string]mb.Event { |
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 guess this is going to be an issue with histograms? Should we do a best-effort guess if it includes metrics with some special labels and/or suffixes?
Comments addressed. Let's see if CI is happy. |
Signed-off-by: chrismark <[email protected]>
Signed-off-by: chrismark <[email protected]>
Signed-off-by: chrismark <[email protected]>
@jsoriano regarding #16609 (comment), this is something we discussed with @exekias already and guessing would be the way to go when we will decide to adopt histograms for this metricset. I think that comments have been addressed 🙂 . |
else | ||
# this works only on Mac envs | ||
HOST_DOMAIN="host.docker.internal" | ||
break |
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.
Why only breaking in this case?
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.
We want to keep trying to reach host.docker.internal
otherwise to fallback to 0.0.0.0
.
(cherry picked from commit a6f406b)
What does this PR do?
This PR implements Prometheus remote write as a new metricset.
Why is it important?
How to test this PR locally
Start metricbeat
Sending metrics from Prometheus
Use this forked project: https://github.com/ChrsMark/dockprom.
docker-compose up
With that metrics should be collected by metricbeat and reported.
Extra: Test with https
/prometheus/prometheus.yml
of the above docker-compose project)my_key.key
andmy_key.pem
under/prometheus
folder in the docker-compose project.my_key.key
andmy_key.pem
.Related issues
Notes about changes
This PR changes
HttpServer
so as to accepthandlerFunc
from metricset on server initialisation. This makes it reusable from different metricsets and not onlyserver
metricset ofhttp
module. In order to confirm thatserver
metricset ofhttp
module is not broken I runINTEGRATION_TESTS=1 BEAT_STRICT_PERMS=false nosetests ./module/http/test_http.py
successfully which shows that functionality is preserved.