How to expose Prometheus metrics with RedisCacheManager? - spring-boot

I have a Spring Boot 2 application that has caching with Caffeine cache manager already implemented. Caching is implemented in a standard way with #Cacheable, #CacheEvict, #CachePut annotations.
I migrated the app for using Redis to have caching distributed between pods.
The problem now is with metrics. Before migration Caffeine exposed cache metrics like cache_puts_total, cache_gets_total, etc. and now there is nothing. Is there something implemented for metrics in RedisCacheManager? I can not find anything.

Unfortunately as you can see in the Spring Boot documentation: 52. Metrics, Spring Boot does not provide cache statistics for Redis by default:
By default, Spring Boot provides cache statistics for EhCache, Hazelcast, Infinispan, JCache and Guava. You can add additional CacheStatisticsProvider beans if your favourite caching library isn’t supported out of the box.
As another alternative to implementing this yourself, you can use Redisson. This Redis client comes with an integration with Spring that exposes Prometheus metrics. Your metrics will look just like you hint:
# HELP cache_gets_total the number of times cache lookup methods have returned an uncached (newly loaded) value, or null
# TYPE cache_gets_total counter
cache_gets_total{cache="...",cacheManager="...",name="...",result="miss",} 0.0
cache_gets_total{cache="...",cacheManager="...",name="...",result="hit",} 0.0
# HELP cache_puts_total The number of entries added to the cache
# TYPE cache_puts_total counter
cache_puts_total{cache="...",cacheManager="...",name="...",} 0.0

Related

Spring Cache Persistence in Kubernetes Deployment

Have seen a super weird issue in our aws kubernetes cluster deployment where the in-memory spring cache appeared to be persistent even after a rollout restart and pod deletion. Is that even possible for an argument sake? Deletion of a pod should have deleted the container which should thereby the underlying memory.
Please share your thoughts, as there is no logs associated to share except the observed behavior.
Environment Details:
Spring Boot 2.7.x
AWS EKS 1.21
Java 17
Spring Cache is an abstraction that provides automatic integration with various persistence technologies besides a simple in-memory cache.
If you have redis configured, for example, and are using spring boot, a default redis caching will take place.

How can I achieve local caching using Spring boot?

I am trying to setup a spring boot application and looking for options to store the small data in the local cache and then this local cache interacts with Redis server which will be on google cloud platform. This local cache can be shared across multiple nodes. I see Redis pro can help to achieve this but that is not free. Is there any open source option I can use? Or any other way I can set this up in Spring boot? How can I set this local cache which syncs up with the central cache? Any suggestions please?
You can use Redisson https://github.com/redisson/redisson/wiki/14.-Integration-with-frameworks/#1421-spring-cache-local-cache-and-data-partitioning. It's available in the Pro version.
If you would like to implement it by yourself, you would need to implement custom CacheManager that first looks up entries in local cache (implemented likely with something smarter than a HashMap, like Caffeine, if entry not found goes to Redis based CacheManager and then depending on the result puts the data to Caffeine cache.
For storing data in Redis and making sure all nodes are in sync, you can use Redis Pub/Sub mechanism to notify each connected node to update local cache.
Spring Boot for Apache Geode (SBDG) offers client-side caching, or what is commonly referred to as "Near Caching". See here.
HISTORY
Apache Geode is an open source software (OSS), In-Memory Data Grid (IMDG) technology, having an Apache 2 License. Indeed, it can be much more than a cache if need be, but fits perfectly well in the caching use case, at any layer in the application architecture (Web, Service, Data).
The commercial version of Apache Geode is VMware Tanzu GemFire, built on Apache Geode source with support from VMware, if needed. But, to use Apache Geode, is completely free.
In fact, the original Spring Cache Abstraction was inspired by Costin Leau's development (original lead & creator) of Spring Data GemFire, which has been replaced by Spring Data for Apache Geode (SDG), to focus on the OSS offering. (See here/alt-here, then here, as well as from Boot).
SBDG is an extension of SDG to give users of Apache Geode (or alternatively, VMware Tanzu GemFire) a proper and first-class experience using Apache Geode in a Spring context, and specifically with Spring Boot features (e.g. auto-configuration). That is, SBDG is a special extension of Spring Boot catered specifically to Apache Geode to handle a variety of application concerns (like caching) that is owned and maintained by the Spring Team, itself.
SBDG is even capable of handling several caching patterns in addition to "Near Caching". See the topic of caching in general.
Finally, SBDG also includes Spring Session for Apache Geode (SSDG) to handle your Web, HTTP Session state caching concerns independent of you Web container (e.g. Tomcat) using Apache Geode as the caching provider for the HTTP Session state. It is, of course, built on Spring Session core (see here).

Checkpointing with Spring AWS Integration

According to Spring release notes, spring-integration-aws.1.1.0.M1 does not include DynamoDB MetaDataStore implementation. There is still ConcurrentMetadataStore class which is a key-value based store and based on implementation I suppose it maps streams with latest sequence number read. But it does not use any data store as to retrieve checkpoints.
I am using spring integration for kinesis consuming and need to implement checkpointing. I am wondering if I need to do it manually by connecting to DynamoDB and always update checkpoints or there is another way of doing it using spring framework?
P.S: I can't use Spring Cloud KinesisBinderConfiguration as I dynamically consume events from a list of configurable streams.
Thank you
If you are not talking about Spring Cloud Stream and the AWS Kinesis Binder implementation, then I don't see any blockers for you to upgrade your solution to the Spring Integration AWS 2.0 and go ahead with already provided DynamoDbMetaDataStore.
Or if that is so hard for you to move to the Spring Integration 5.0, then you simply can consider to copy/paste an implementation to your own class and inject it into the KinesisMessageDrivenChannelAdapter: https://github.com/spring-projects/spring-integration-aws/blob/master/src/main/java/org/springframework/integration/aws/metadata/DynamoDbMetaDataStore.java
Although it is really available in the 1.1.0.RELEASE - I don't see reason for your to stick with the 1.1.0.M1: https://spring.io/blog/2017/11/27/spring-integration-for-aws-1-1-ga-available

Metrics for CPU usage and Utilization using Spring Boot Dropwizard

Is there a way to measure CPU usage and Utilization of different aspects (CPU, Thread, Memory etc) using dropwizard in spring-boot?
Use spring-boot-actuator for that. There is already a /metrics endpoint for the data you are asking for.
Check systemload.average, mem, mem.free, threads etc for the exact information.
For more information check:
https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-metrics.html
https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-metrics.html#production-ready-dropwizard-metrics
A default MetricRegistry Spring bean will be created when you declare
a dependency to the io.dropwizard.metrics:metrics-core library; you
can also register you own #Bean instance if you need customizations.
Users of the Dropwizard ‘Metrics’ library will find that Spring Boot
metrics are automatically published to
com.codahale.metrics.MetricRegistry. Metrics from the MetricRegistry
are also automatically exposed via the /metrics endpoint
When Dropwizard metrics are in use, the default CounterService and
GaugeService are replaced with a DropwizardMetricServices, which is a
wrapper around the MetricRegistry (so you can #Autowired one of those
services and use it as normal). You can also create “special”
Dropwizard metrics by prefixing your metric names with the appropriate
type (i.e. timer., histogram. for gauges, and meter.* for counters).

how to use redismetricrepository in spring boot

I am working on spring boot actuator and able to see the metrics of my application. But I want to store these metrics to some db. In Spring doc it has been mentioned that RedisMetricRepository provides option for storing metrics to redis db. But I dont how to make use of this RedisMetricRepository to store metrics to redis db.Kindly help me out how to use RedisMetricRepository for storing metrics to redis db.
You can just create a #Bean of type RedisMetricRepository. I suspect that will just store the metrics in Redis immediately. I prefer to buffer in memory and export to Redis periodically. Here's a sample using #Scheduled to export to Redis every 5s): https://github.com/scratches/aggregator/blob/master/generator/src/main/java/demo/GeneratorApplication.java#L61.

Resources