Starting and stopping Spring Boot metrics on demand - java

Spring Boot 2.x here. Reading through metrics/micrometer docs and trying to figure out how I could stop/restart all metrics collections on the fly at runtime.
It looks like the typical way metrics registries are created are:
SimpleMeterRegistry registry = new SimpleMeterRegistry();
And I would expect this to happen in a #Bean-annotated method from inside a #Configuration-annotated class. So to me, this indicates that the registry is started automatically as part of some background process. However, for my application, I want to be able to explicitly start/stop/restart metrics collection on demand.
Any ideas as to how to accomplish this? Thanks in advance.

Related

Get all Spring integration channel names at startup - Initializing Spring Integration Metrics at startup

Unfortunately Spring Integration metrics are registered when they are first used.
https://stackoverflow.com/a/63619360/13657000
this means that prometheus query functions like increase give incorrect calculations.
Is there a way to get all channel names in Spring integration so that I can initialize metrics for each channel?
I'm using dsl.
I looked at this https://gist.github.com/flopezluis/2964429 but they find their channel names using XML.
Any help is appreciated, thanks.
I'm not sure why you need names of channels since the story is really about calling a MessageChannel.send(), so you perhaps just need an ApplicationContext.getBeansOfType(MessageChannel.class). Pay attention though, that sending a message to the channel will trigger not only metrics registration but also their consumption on the other side. Therefore you might need to think about filtering these "initial" messages somehow before they reach your real consumer.
On the other hand I wonder if there is some Micrometer option to make those timer metrics to be registered eagerly even if we don't produce messages yet. Just call registry.timer() as early as possible?

Opentelemetry: How to add logs to a span

I am using OpenTelemetry java auto instrumentation in my spring boot app. Is there a way to make the application logs part of the spans that are created?
My autoconfig settings are as below:
-Dotel.traces.exporter=jaeger
-Dotel.metrics.exporter=none
-Dotel.exporter.jaeger.endpoint=http://localhost:14250
-Dotel.resource.attributes=service.name=myService
-javaagent:C:/path/to/opentelemetry-javaagent-1.0.1-all.jar
OpenTelemetry ships logs separately to the telemetry data obtained from auto instrumentation, and does not interleave log data I'm afraid. We ship our logs via the use of FluentBit (https://medium.com/opentelemetry/introducing-the-fluentbit-exporter-for-opentelemetry-574ec133b4b4).
You may wish to use manual instrumentation and add spans, span attributes and/or events to pertinent code blocks, to add log like context to the metadata utilised downstream.
As you are using Spring Boot, it would be advisable to use one of the starter dependencies, such as opentelemetry-otlp-exporter-starter (https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/spring/starters/otlp-exporter-starter), which should get you most of the way there. You want to use the #WithSpan annotation to decorate your methods, which will enable you to obtain the current span easily. See https://opentelemetry.lightstep.com/java/.
The official docs have a few examples, that may help, but be aware that the API and SDK are changing rapidly, so examples don't always work - https://opentelemetry.io/docs/java/manual_instrumentation/.
Detailed information regarding OpenTelemetry and logging: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/overview.md
Adding logs to spans depends a bit on the backend you are using for collecting the traces/spans and visualizing them.
I used Jaegar, which interprets OTEL events as logs in the UI, and so I wrote a custom log appender which put app logs into an event, which was picked up subsequently in the UI.
More details here:
https://stackoverflow.com/a/68739794/2715083

Is there a way to make Spring reload bootstrap properties dynamically?

I have a spring-boot app that autoconfigures an instance of Netflix's DynamicPropertyFactory. This enables us to read any properties spring is aware of plus any additional sources we specify.
The issue arises when we change a spring property that is used in core spring classes. For example logging.level.org.springframework.web=INFO is used on core classes or spring before, during, and after applicationContext setup. If we change this property while the application is running to say logging.level.org.springframework.web=TRACE...
dynamicPropertyFactory.getInstance().getStringProperty() eventually realizes the change. However, the spring core classes continue to log at INFO rather than change to TRACE as expected.

Hystrix metrics via JMX: how to get values before any command invocations?

I'm using Hystrix 1.5.3 in Spring Boot application, and the metrics are published to JMX via hystrix-codahale-metrics-publisher. I also tried using hystrix-servo-metrics-publisher with the same exact result, so I'm not sure if the publisher implementation matters.
The problem is that there are no JMX MBeans/attributes visible until the corresponding HystrixCommand executes.
For example, if I have two HystrixCommands - Foo & Bar and just started the app, the MBean with metrics won't appear at all. If the command Foo is executed, the MBeans and attributes appear, but only for Foo. What I want to achieve is having visible MBeans and attributes for both Foo and Bar immediately after application startup.
According to Hystrix metrics wiki, looks like the storage is really initialized with the command execution. I've also gone through Hystrix issue tracker and didn't find anyone who had problems with such behavior.
Is there a way to force exposing metrics for all existing HystrixCommands? I don't have a lot of commands, so manually adding them to some registry and initializing with default values will probably be OK.

hazelcast : changing configuration programatically doesnt work

I am unable to configure/change the Map(declared as part of hazelcast config in spring) properties after hazelcast instance start up. I am using hazelcast integrated with spring as hibernate second level cache. I am trying to configure the properties of map (like TTL) in an init method (PostConstruct annotated) which is called during spring bean initialization.
There is not enough Documentation , if there is please guide me to it.
Mean while i went through this post and found this Hazelcast MapStoreConfig ignored
But how does the management center changes the config, will it recreate a new instance again ?
Is hazelcast Instance light weight unlike session factory ? i assume not,
please share your thoughts
This is not yet supported. JCache is the only on-the-fly configuration data structure at the moment.
However you'll most probably be able to destroy a proxy (DistributedObject like IMap, IQueue, ...), reconfigure it and recreate it. Anyhow at the time of recreation you must make sure that every node sees the same configuration, for example by storing the configuration itself inside an IMap or something like that. You'll have to do some wrapping on your own.
PS: This is not officially supported and an implementation detail that might change at later versions!
PPS: This feature is on the roadmap for quite some time but didn't made it into a release version yet, it however is still expected to have full support at some time in the future.

Categories