Stop sending Spring boot metrics to Prometheus with Micrometer - spring-boot

I have a Spring boot application where I am sending custom metrics generated within the service to Prometheus via Pushgateway.
I am using Prometheus Pushgateway with Micrometer, mainly based on this tutorial: https://luramarchanjo.tech/2020/01/05/spring-boot-2.2-and-prometheus-pushgateway-with-micrometer.html
I have following dependencies in my pom.xml
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
<version>0.16.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
And sending custom metrics with:
Counter counter = Counter.builder("sb_console_test_counter").register(meterRegistry);
counter.increment();
It is working fine and I can view the custom metrics generated by the application however in addition to this I am seeing application specific metrics generated by Spring boot e.g.
tomcat_sessions_active_current_sessions
tomcat_sessions_active_max_sessions
etc.
I only want to capture the custom metrics generated by my code and not any other generic metrics, how can I stop sending this?

When you add the dependency spring-boot-starter-actuator you will get a lot of metrics out of the box from various configurations such as JvmMetricsAutoConfiguration and TomcatMetricsAutoConfiguration.
To filter those out, you could add a deny filter in your Micrometer config, and only allow your custom metric meters to be registered.
Example using a deny filter:
#Bean
public MeterRegistryCustomizer<MeterRegistry> metricsRegistryConfig() {
return registry -> registry.config()
.meterFilter(MeterFilter.deny(id -> !id.getName().startsWith("sb_console")));
}
The above will deny any metrics not starting with sb_console.
See this link for more info about the meter filters

I believe you can just add this:
management.metrics.export.defaults.enabled=false
to your application.properties. I see this in some of my code. I'm not set up to try it right now, but that's why we have it there.
If you want to add back some of the built in metrics, you can then add lines like this:
management.metrics.export.<groupname>.enabled=true

Related

How to configure Swagger with Openapi

I just started using springdoc-openapi. I want to be able to customize the Swagger for things like background color, logo, etc. Is there a way to do that? I see that springdoc-openapi-ui includes webjars/swagger-ui, but I'd hate to just run a customize version. Would prefer to do it as an update so it doesn't interfere with future upgrades
Just to experiment, I've tried copying the entire swagger-ui distribution to my resources directory: resources/swagger-ui. I've also tried resources/webjars/swagger-ui.
In my pom, I have
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.6</version>
<exclusions>
<exclusion>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
</exclusion>
</exclusions>
</dependency>
So it should only use my local version. But I get a 404
GET "/swagger-ui/index.html", parameters={}
Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/webjars/]]
Resource not found
Completed 404 NOT_FOUND
Not sure why it's not finding it at swagger-ui/index.html
It looks like you need to set some of the variables in the .properties file:
try
springdoc.swagger-ui.path=/swagger <- sets the url path so you can see localhost:8080/swagger/index.html
springdoc.swagger-ui.enabled=true <- sets the swagger-ui to enabled
springdoc.api-docs.enabled=true <- sets the springdoc openapi enpoint to enabled
I would look here for other property setting you might need - such as turning off swagger in production, etc...
https://springdoc.org/#properties
As for customization, you will have to create your own .html page and disable the use of the default one.
springdoc.swagger-ui.path=MyNewHtmlFile.html
I think is the property name for setting your own .html file.

Actuator metrics do not include http.server.requests

I am trying to expose timing metrics to prometheus from an api implemented with spring boot 2. I've included the following dependencies.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
I'm managing dependencies through spring-cloud-starter-parent Finchley.SR1, which gives me versions of 2.0.4.RELEASE on spring-boot-starter-actuator, and 1.0.6 on micrometer-registry-prometheus.
The /actuator/prometheus endpoint is working and reachable, but the metrics I need are not included. When I look at /acutator/metrics, the "http.server.requests" metric is not listed there:
{
"names": [
"jvm.memory.max",
"cache.eviction.weight",
"cache.gets",
"process.files.max",
"jvm.gc.memory.promoted",
"tomcat.cache.hit",
"system.load.average.1m",
"tomcat.cache.access",
"jvm.memory.used",
"jvm.gc.max.data.size",
"jvm.gc.pause",
"jvm.memory.committed",
"system.cpu.count",
"logback.events",
"tomcat.global.sent",
"jvm.buffer.memory.used",
"tomcat.sessions.created",
"jvm.threads.daemon",
"system.cpu.usage",
"jvm.gc.memory.allocated",
"tomcat.global.request.max",
"tomcat.global.request",
"tomcat.sessions.expired",
"jvm.threads.live",
"jvm.threads.peak",
"tomcat.global.received",
"process.uptime",
"cache.puts",
"cache.size",
"cache.evictions",
"tomcat.sessions.rejected",
"process.cpu.usage",
"tomcat.threads.config.max",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"tomcat.global.error",
"tomcat.sessions.active.current",
"tomcat.sessions.alive.max",
"jvm.gc.live.data.size",
"tomcat.servlet.request.max",
"tomcat.threads.current",
"tomcat.servlet.request",
"process.files.open",
"jvm.buffer.count",
"jvm.buffer.total.capacity",
"tomcat.sessions.active.max",
"tomcat.threads.busy",
"process.start.time",
"tomcat.servlet.error"
]
}
According to documentation, and everything I can find searching google, it should be one of the metrics that is autoconfigured out-of-the-box.
I have tried this with the spring.metrics.web.server.auto-time-requests property set to true, and with #Timed annotations on the endpoint I am testing with, and either way I get nothing.
I found this resolved issue in which someone had the same symptoms, but they were using spring boot 1.5 and their issue was an unneeded extra dependency that I do not have:
Actuator /metrics endpoint does not include http.server.requests
Any idea what would cause actuator to not expose the http.server.requests metric?
I should add that I have 6 other services like this one in which the metrics are working as expected, so it's just this one out of the 7 where it does not work. I can't figure out what is different about this one. I've even tried stripping it down to remove any dependencies that are not also present in the other six, but still this one won't report that metric.
Can you after accessing any one of your end-point? Just give it a try from postman or from your app and check the /metrics endpoint. I hope it should be there.

Expose metrics from spring application to prometheus without using spring-boot actuator

I have been trying to collect micrometer metrics in a non springboot application and expose them to prometheus.I have added the following dependency and the test method for the same.I would like to know how to proceed and expose the collected metrics to prometheus from my non spring boot application(traditional spring application).
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.2.0</version>
</dependency>
public string testmetrics(){
private PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
registry.counter("ws metric collection","tktdoc metrics");
String metricsInfo = registry.scrape();
return metricsInfo;
}
You practically have to expose an HTTP endpoint and configure Prometheus with it; the HTTP endpoint will supply the data for the scrapes.
An example showing how to add the HTTP endpoint by starting up an HTTP Server (your application may already be using one) is here.

Scheduling using Camel - Quartz2 and Spring boot

I am trying to setup a scheduler using Camel and Quartz2 and my goal is to read messages from queue only in a specific time period.I am getting the following error on start of the server.
org.apache.camel.spring.boot.CamelSpringBootInitializationException:
org.apache.camel.FailedToCreateRouteException: Failed to create route
route1:
Route(route1)[[From[quartz2://simpleTimer?cron=0/1+0+13-15+?...
because of Failed to resolve endpoint:
quartz2://simpleTimer?cron=0%2F1+0+13-15+%3F+*+MON-FRI due to: No
component found with scheme: quartz2
This is the pom entry
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz2</artifactId>
<version>2.19.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-dependencies</artifactId>
<version>2.19.2</version>
</dependency>
code snippet in routes
from("quartz2://simpleTimer?cron=0/1+0+13-14+?+*+MON-FRI")
.log("Reading msgs")
.from("some queue")
.bean("myBean")
Also tried with this
from("quartz2://testGroup/someName?cron=0/1+0+13-14+?+*+MON-FRI").
I made multiple attempts in fixing the issue but failed, can anyone help me in fixing this?
Can I use simpleTimer along with Cron settings or Is there any other approach?
any suggestions/help in this regards would be highly appreciated.
The error indicates you have not added the dependency in maven to camel-quartz2 component.
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz2</artifactId>
<version>x.x.x</version>
<!-- use the same version as your Camel core version -->
</dependency>
The problem is that you put 2 from in the same route. Each route has only one from.
When you read from a queue, for example with jms component, you get directly the messages as soon as they arrive. So quarz component is not needed.
Which component are you using for reading from a queue? Probably this component has more options that they can help you!
This got resolved when I created a Bean instance of QuartzComponent in routes file.Also, we can have multiple "from" in the routes definition.

How to block Cassandra from trying to connect automatically

I have this project where I'm trying to connect to different DB types based on configuration.
I have it working for Mongo and MySQL and switch by loading Beans by using #ConditionalOnProperty(name = "settings.data.source", havingValue = "mongodb")
Now I want to add Cassandra, but once I added the following dependency to my pom, it starts trying to connect to Cassandra nodes on localhost.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
I want to have more control over when the Cassandra resources are loaded.
It doesn't try to connect automatically when I added Mongo dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
Anyone familiar with this behavior? How can I control this? I don't always need a Cassandra connection...
You may disable Cassandra auto configuration,
#SpringBootApplication
#EnableAutoConfiguration(exclude={CassandraDataAutoConfiguration.class})
Yep, That's it, thanks!
#EnableAutoConfiguration(exclude={
CassandraDataAutoConfiguration.class,
MongoDataAutoConfiguration.class,
MongoRepositoriesAutoConfiguration.class,
MongoAutoConfiguration.class})
For both my #SpringBootApplication and #Configuration classes.

Resources