-
Notifications
You must be signed in to change notification settings - Fork 903
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
Clarify sdk prometheus exporter resource attributes #2640
Comments
I think the fundamental issue here is that we've been "Loose" with resource attributes, and it causes problems for Metrics (vs. traces). Effectively, Metrics have WAY MORE concern on cardinality of all atributes used to identify a timeseries. We have a few open bugs/issues previously about knowing which rsource attributes are important or avoiding adding resource attributes that have high cardinality (like the ones you list). e.g. #1782 was a very lengthy discussion on this. Fundmanetally I think we need to "fix" a few design considerations that we've talked about:
|
It has been my long-held view that a definition of a Resource as just a bag of key-value attributes is not sufficient. We need to be able to distinguish between identifying and non-identifying attributes. I see 3 possible ways to improve the situation:
|
I like the direction of (3), particularly in the light that I've been viewing resources lately: Specifically - for OTEL resource to work (as designed) we almost REQUIRE an external metadata / service-discovery mechanism A few points:
This leads me to believe that, in practice, we need a few key features around
TL;Dr; regarding @tigrannajaryan's three options, I don't think option 1 or 2 make enough room for service discovery within our notion of resource. |
Let me post this old proposal to model entities in the Collector (precisely for discovery purposes): https://docs.google.com/document/d/1Tg18sIck3Nakxtd3TFFcIjrmRO_0GLMdHXylVqBQmJA/edit# There are a couple diagrams in the doc that show examples of "entities". In my mind there are different kinds of entities, some are defined at build time (such as the Service or Container Image), some are defined at run time (such as K8s Pod, K8s Node, Host, Service Instance, etc). Here is a bit more comprehensive case (boxes are entities, arrows are relationships): Today we lump all information about these entities into a single bag of attributes and call it a Resource. By doing so we loose important information. The irony is that our resource detectors often detect entities separately, so our implementations in the Collector for example could create distinct entities and even link them by the correct relationships. Instead we flatten this information into a single bag of attributes and call it a Resource. |
@tigrannajaryan This is inline with my thinking as well. I think maybe we should open a (non prometheus SDK focused) feature-request / proposal around resources that can help resolve the specific issues called out in this bug. Is it worth discussing in a SPec SiG before working on an entity proposal, or should we flesh out this idea more (I'm happy to outline the requirements section)? |
I think it is worth discussing first. It is a relatively big commitment IMO. I personally would love to work on it, but have a few other things in progress right now, so would prefer to finish those first. |
@jsuereth maybe i'm misreading, but this seems contradictory. If a set of attributes is uniquely identifying, it has maximum cardinality. Put another way, adding non-identifying attributes does not increase cardinality. The concern here seems to be that prometheus keeps the same resource (i.e. job + instance) across restarts, but OTel does not, which results in higher cardinality. The benefit of OTel's model is that we can tell when something restarted, but it comes at the cost of an extra metric stream.
A single metric stream per-restart of an application doesn't really seem like a cardinality issue, as a single prometheus histogram often has hundreds, or even thousands of streams. Are you concerned about specific scenarios (e.g. crashlooping)? I'm definitely on-board with it being configurable, and like the idea of a filter for the resource attributes added, but it does seem nice to preserve resource information by default. |
@dashpole initially I thought so too, but I don't think this is always true. For example imagine we are reporting host metrics. The host is uniquely identified by SMBIOS hardware machine ID which is the only and sufficient identifying attribute that we add to the Resource as a let's say "host.id" attribute. However, we also decide to add the IP address as a Resource attribute "host.ip" (sounds like a reasonable idea for a Host, right?). The host also happens to be using DHCP, so its IP address changes over time (can happen on restarts or even periodically). So, the combination of the machine ID and IP address is higher cardinality than machine ID alone. Arguably, it not only is higher cardinality, it results in discontinuities in the metrics reported by the same host, so it is also logically undesirable even if higher cardinality itself is not a problem. So, to make it clear: non-identifying attribute does not mean "a derived" attribute that can be inferred from identifying attributes. Non-identifying really means any value that should not be used for identification purposes because it is superfluous and results in incorrect identity of timeseries. |
I'm wondering how much of a problem this actually is. Even if some attributes change occasionally, |
It will depend on the frequency of the restarts and how resource constrained the prometheus instances are, but in general I think I agree that it shouldn't be a big problem most of the time. One solution would be to have the prometheus exporter have a configurable disallow list, where target_info includes all resource attributes except those on the disallowed list. The other question implied in this issue but not explicitly stated is what is the use case that including target_info solves? Reiterating that in pull based metric systems ingestors are expected know the target metadata a-priori, I can't think of a sensible setup where a user would be able to take advantage of this information. |
Yes, it is likely not a problem most of the time from performance perspective. However, to emphasize what I wrote above: I think it is still a problem from timeseries continuity perspective. If I am looking at the CPU usage timeseries for a particular host I don't expect the timeseries to terminate and a new timeseries to be created when the IP address of the machine changes (well, assuming that I believe the host is identified solely by its machine ID and not by its IP address). It is important that the timerseries is identified by dimensions that the user expects to be the identity of the entity that is being observed (sorry, that was mouthful). When irrelevant dimensions are added on top of the correct ones it can result in a surprising behavior. |
I agree in general that we need to find some mechanism to indicate which resource attributes are identifying vs descriptive. However the prometheus SDK exporter doesn't necessarily have to address this question since in pull based exporters scrapers have the responsibility of identifying entities. Including resource attributes in target_info conflates responsibilities, and it's not clear which use case(s) stand to benefit. To put it another way, if we were to remove the language around sdks exposing resource attributes in the prometheus exporter via target_info, what would we loose? The target info is aimed at push based approaches, and for pull based approaches that expose several targets (i.e. a collector exposing the metrics for several individual SDKs). The SDK prometheus exporter doesn't fall under either of those use cases, so why include target info at all? |
I understand the desire to limit the scope but I think the solution may need to be broader than what is necessary just for Prometheus SDK exporter. Exporting into other non-OTLP formats will likely face similar challenges. |
The SDK prometheus exporter "MUST NOT support Push mode". |
👍 this sounds good: If
There different ways how to set up an OTel metrics pipeline with Prometheus. You could scrape metrics directly from the applications. Or you could have the applications push metrics to the collector via OTLP, and the collector forward these metrics to the Prometheus server via remote write. It would be good if users could see the same metrics in Prometheus independent of the pipeline. It would be weird if the |
There are a few motivations behind
For the OpenMetrics specification: It is true that pull-based systems are expected to have have some resource information, but metadata the exposer is aware of is still expected to be useful when using pull-based systems: |
On this note the round trip behavior of
A question I keep asking is how users are actually expected to use these. To my knowledge, you can't join in prometheus so the data isn't accessible at query time. And I also couldn't find any way to configure a prometheus scrape job to extract target_info attributes and add them to the scraped series. Overall though, I'm happy enough if the sdk prometheus exporter has a optional configurable disallow list. Or perhaps an even simpler option of having an option to toggle target_info off all together. |
This is not true tbh, and The Prometheus community has also been talking about a simpler syntax for joins: prometheus/prometheus#3094 And on top, metric discontinuity is not that much of an issue in Prometheus because you never select on labels that are going to be different across restarts, change frequently. If you don't select on them, the queries should all work the same with and without the metric discontinuities. Further, @fstab mentioned in todays Prometheus WG call that we can always use |
Good to know!
Another great point. So with joins available to access target_info attributes I'm convinced of the usefulness of making the resource attributes available via target_info. And with metric_relabel_rules available to perform the same functionality as a disallow list would provide, I'm in favor of encouraging users to use that existing functionality rather than adding something new. I still think the round tripping is weird, and that we generally need some way to indicate resource attributes as identifying or descriptive, but I'm happy enough to close this specific issue. |
To plot exactly 1 metric in Prometheus all the labels of that metric are needed, which to me sounds as all label key-value pairs are needed to identify a metric. Does that mean those labels should be in the "resource" field of OT then instead of "datapoint attributes"? |
The spec says the following about the SDK prometheus exporter and resource attribute:
This initially seems like a good idea, but after implementing in java and talking it over with other java maintainers, I'm not so sure.
The primary concern of including resource attributes is increasing cardinality. Resource attributes will tend to be unique for each restart of the app due to
service.instance.id
. Prometheus automatically appends ajob
andinstance
label to scraped time series, which are likely to stay constant across restarts of an app. This means a casual user ingesting the target info metric would be exposed to higher cardinality than they would otherwise expect.Given that in pull based metric systems ingestors are expected know the target metadata a-priori, it seems odd that the SDK prometheus exporters should include target info by default.
Instead, target info could be opt in with a configuration option. We also might consider making the set of resource attributes exposed through target info configurable.
The text was updated successfully, but these errors were encountered: