Micrometer: LoggerContext changes when using Spring Cloud

Created on 18 Apr 2018  路  12Comments  路  Source: micrometer-metrics/micrometer

Hi,

I am using the Spring Boot 1.5 micrometer code and have found that the LoggerContext changes shortly after application startup (which I believe is related to our use of Spring Cloud). When the application starts io.micrometer.core.instrument.binder.logging.LogbackMetrics registers io.micrometer.core.instrument.binder.logging.MetricsTurboFilter, but when the application context is reloaded, LogbackMetrics is now pointing to the old LoggerContext. To get round this I created the following class:

@Component
public class FlexLogbackMetricsListener implements ApplicationListener<ContextRefreshedEvent> {

    private final LogbackMetrics logbackMetrics;
    private final MeterRegistry meterRegistry;

    public FlexLogbackMetricsListener(final LogbackMetrics logbackMetrics, final MeterRegistry meterRegistry) {
        this.logbackMetrics = logbackMetrics;
        this.meterRegistry = meterRegistry;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
       logbackMetrics.bindTo(meterRegistry);
    }

}

Is there a better way to do this? It works a treat, but does seem a little hacky.

Thanks

Nick

external-project

Most helpful comment

In the end this is what I managed to get working:

LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
boolean exists = loggerContext.getTurboFilterList().stream()
    .anyMatch(i -> i.getClass().getName().equals("io.micrometer.core.instrument.binder.logging.MetricsTurboFilter"));
if (!exists) {
    logbackMetrics.bindTo(meterRegistry);
}

All 12 comments

cc / @spencergibb.

In the end this is what I managed to get working:

LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
boolean exists = loggerContext.getTurboFilterList().stream()
    .anyMatch(i -> i.getClass().getName().equals("io.micrometer.core.instrument.binder.logging.MetricsTurboFilter"));
if (!exists) {
    logbackMetrics.bindTo(meterRegistry);
}

Would a listener like posted above work in general. Any case where a library calls SpringApplication.run() such as spring cloud commons or spring cloud stream will reset this.

The solution seems reasonable to me. But I'm curious to hear the Spring Boot team's opinion. We'll just follow their lead.

We're going to postpone this to Micrometer 1.0.5/Spring Boot 2.0.3 because it's a little more difficult to reproduce reliably than expected.

Any update now 1.0.5 and spring boot 2.0.3 have been released?

After a context refresh event (RefreshScopeRefreshedEvent) the LogbackMetrics' TurboFilter is removed from the LoggerContext. I use a workaround now to rebind the metrics:

@Bean
MetricsRefreshEventListener metricsEventListener(final LogbackMetrics logbackMetrics, final MeterRegistry meterRegistry) {
    return new MetricsRefreshEventListener(logbackMetrics, meterRegistry);
}

@RequiredArgsConstructor
class MetricsRefreshEventListener implements ApplicationListener<RefreshScopeRefreshedEvent> {
    private final LogbackMetrics logbackMetrics;
    private final MeterRegistry meterRegistry;

    @Override
    public void onApplicationEvent(final RefreshScopeRefreshedEvent event) {
        logbackMetrics.bindTo(meterRegistry);
    }
}

Based on spring-projects/spring-boot#13077 (comment), it seems that this can be closed as well in favor of spring-cloud/spring-cloud-commons#608.

I agree. Let's close this, waiting for the resolution of the spring-cloud-commons issue. We can reopen later if need be.

Hi. Unfortunately spring-cloud/spring-cloud-commons#608 didn't fix this. The original workaround still works.
@shakuzen will you reopen this?

Hi. Unfortunately spring-cloud/spring-cloud-commons#608 didn't fix this. The original workaround still works.
@shakuzen will you reopen this?

This issue would be reopened if there were some change to make in Micrometer itself. So far all the discussed solutions have been changes in other projects. The resolution of the linked spring-cloud-commons issue indicates to me that it should not be a problem since the 2020.0.0-M4 release of Spring Cloud.

Hi. Unfortunately spring-cloud/spring-cloud-commons#608 didn't fix this. The original workaround still works.
@shakuzen will you reopen this?

This issue would be reopened if there were some change to make in Micrometer itself. So far all the discussed solutions have been changes in other projects. The resolution of the linked spring-cloud-commons issue indicates to me that it should not be a problem since the 2020.0.0-M4 release of Spring Cloud.

You are completely right. I will head over to the spring-cloud-commons project and refer to this bug. Maybe they can help out some more. Thanks for the quick reply!

Was this page helpful?
0 / 5 - 0 ratings