Skip to content
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

Custom labels for caffeine cache #602

Closed

Conversation

aaabramov
Copy link

Adds an option to specify custom labels for metrics. This may be (and is!) useful in microservice environment where service caches are being used in different domains. Using custom labels, users will be able to distinguish different cache metrics without [pre/post]fixing cache (cacheName) parameter.

Also upgrades caffeine cache to v2.8.6

This feature keeps backwards binary & source compatibility.

List<String> labelNames = new ArrayList<String>(customLabels.size() + 1) {{
add("cache");
addAll(customLabels);
}};
Copy link
Author

@aaabramov aaabramov Nov 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we initialize this this List each time? Maybe simply initialize it once as instance field?

@aaabramov aaabramov marked this pull request as draft November 16, 2020 23:20
@aaabramov aaabramov marked this pull request as ready for review November 16, 2020 23:28
… is!) useful in microservice environment where service caches are being used in different domains. Using custom labels, users will be able to distinguish different cache metrics without [pre/post]fixing `cache` (`cacheName`) parameter.

Also upgrades caffeine cache to v2.8.6

This feature keeps backwards binary & source compatibility.

Signed-off-by: Andrii Abramov <[email protected]>
for (Map.Entry<String, String> entry : customLabels.entrySet()) {
add(entry.getValue());
}
}};
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be a good idea to store label inside children value. This would require adding custom class as a value but since it is internal we can implement this without breaking changes.

@brian-brazil
Copy link
Contributor

Can you expand on what you mean by different domains here?

@aaabramov
Copy link
Author

aaabramov commented Nov 16, 2020

Sure.
Let's say we are having k8s cluster with 10 different apps. Each of it uses caffeine as a cache. But single prometheus scrapper.

Currently, the only way to distinguish cache metrics provided by this library between apps is to modify somehow cacheName parameter (either we can prefix it with domain, e.g. users_the_cache_name, dashboards_the_cache_name, etc. or with postfix). This makes creating Grafana dashboards pretty difficult as we have to rely on regexes of cache label.

In order to create cache dashboard for users service we have to write something like

sum(rate(caffeine_cache_miss_total{cache~="users_.*"}[5m])) by (cache)

That's why I decided it would be easier for users to specify their own labels and create Grafana dashboard like this:

Map<String, String> labels = new HashMap<String, String>() {{
    put("app", "users-service");
}};

CacheMetricsCollector coll = new CacheMetricsCollector(labels);
sum(rate(caffeine_cache_miss_total{app="users-service"}[5m])) by (cache)

This PR is more like a proposal, I am totally open to discussion 👨‍💻

@brian-brazil
Copy link
Contributor

What happens if there's different libraries in the application that are using different label names with this? We can't make any assumptions in that regard.

@aaabramov
Copy link
Author

Is it an issue in this case? Wouldn't we expose different metrics in this case? I am not so strong enough in prometheus but I would expect to have different metric rows from prometheus, e.g.:

caffeine_cache_miss_total{app="app-1"} 1
caffeine_cache_miss_total{app="app-2"} 2
caffeine_cache_miss_total{app="app-3"} 3

Or am I missing something?

Anyway, we are simply allowing users to take control of what is exposed. We are not making any decisions for them.

@brian-brazil
Copy link
Contributor

Is it an issue in this case? Wouldn't we expose different metrics in this case?

Yes, you'd break downstream PromQL and depending on implementation could also produce invalid exposition (what happens if two libraries clash on labels?). If you're varying instrumentation labels, then the metric name must also change.

@aaabramov
Copy link
Author

Thanks, now I see.

But this could happen without this library? We are not introducing some sort of "failure injection".

It's user's responsibility to keep an eye on such things. We are just providing an instrument (facade, if you want) to make life easier.

@brian-brazil
Copy link
Contributor

It's user's responsibility to keep an eye on such things.

My point is that the user can't, as they don't have full control of all their libraries. If you have code like this, you have to presume that other unknown parts of your application are using it in arbitrary ways, and then considering if it's possible for you to write correct code given that. For this proposal as it stands it isn't.

@aaabramov
Copy link
Author

I see your point.

What is your proposal to solve the issue? Playing around with cacheName?

Well, it is still possible to inherit CacheMetricsCollector class and override collect method (that's what I'll probably do in case of rejecting this feature). But that will look like copy-pasting code because collect contains most of the logic of the class.

@brian-brazil
Copy link
Contributor

Given that there has only been one request for this thus far, I think it would be best to handle it on your side for now. Any form of wrapper that adjusts the metric name and labels should do the trick.

@aaabramov
Copy link
Author

Sadly, but decision is up to you.

I will create issue referencing this PR to get community feedback.

@aaabramov
Copy link
Author

@brian-brazil closing this for now, described proposal in #603

@aaabramov aaabramov closed this Nov 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants