Code Monkey home page Code Monkey logo

micrometer-counter-exporter-example's Introduction

micrometer-counter-exporter-example

After using Micrometer for a while, a little quirk surfaced. This example is to reproduce the problem, and is intended to serve as a base for troubleshooting it.

The problem

When running Micrometer (independently of whether it is running with Spring Boot or in standalone mode), Counters incremented for the first time shortly before application exit are exported with an unexpected value. Let's assume Micrometer is running in an AWS Lambda function, which are naturally short-lived environments. Let's also assume that you want to count the number of successful runs of your function by incrementing a counter every time your app reaches the end of its life. Shortly after the counter is incremented, the function exits.

The sample

The sample contains a custom StepMeterRegistry, which, instead of actually exporting, simply logs whenever a counter would be exported. The MyLogCounterRegistry also contains a MyLogCounter which does exactly what the StepCounter does, but also logs when its created or incremented.

There are four Counters in the sample, created and incremented at different times in the application lifecycle. Depending on when they are created and incremented, they are exported at different times.

The output

When running the MicrometerStandalone sample, this output is generated (annotations added manually):

[main] INFO io.micrometer.core.instrument.push.PushMeterRegistry - publishing metrics for MyLogCounterRegistry every 5s
# Count 1, 3, and 3 are created at the beginning of the app, and count 1 is incremented immediately
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count1 created
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count1 incremented by 1.0
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count2 created
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count3 created

# The main thread sleeps for the duration of the export interval, thus the first export cycle will have rolled around
[main] INFO org.pirgeo.example.MicrometerStandalone - sleeping for 5 seconds
[my-counter-logs-publisher] INFO org.pirgeo.example.MyLogCounterRegistry - Export #0

# Note that count 1 is immediately exported after being incremented in the first export cycle
[my-counter-logs-publisher] INFO org.pirgeo.example.MyLogCounterRegistry - count1 | created_at=0,incremented_at=0 | 1.00
[my-counter-logs-publisher] INFO org.pirgeo.example.MyLogCounterRegistry - count2 | created_at=0,incremented_at=1 | 0.00
[my-counter-logs-publisher] INFO org.pirgeo.example.MyLogCounterRegistry - count3 | created_at=0,incremented_at=2 | 0.00
[main] INFO org.pirgeo.example.MicrometerStandalone - sleep over, continuing main thread
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count1 incremented by 1.0
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count2 incremented by 1.0
[main] INFO org.pirgeo.example.MicrometerStandalone - sleeping for 5 seconds
[my-counter-logs-publisher] INFO org.pirgeo.example.MyLogCounterRegistry - Export #1

# Again, the two counters that have been incremented in the last interval are exported immediately
[my-counter-logs-publisher] INFO org.pirgeo.example.MyLogCounterRegistry - count1 | created_at=0,incremented_at=0 | 1.00
[my-counter-logs-publisher] INFO org.pirgeo.example.MyLogCounterRegistry - count2 | created_at=0,incremented_at=1 | 1.00
[my-counter-logs-publisher] INFO org.pirgeo.example.MyLogCounterRegistry - count3 | created_at=0,incremented_at=2 | 0.00
[main] INFO org.pirgeo.example.MicrometerStandalone - sleep over, continuing main thread

# This is the last export interval, it will *not* run until the export interval rolls around (there is no sleep here)
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count4 created
# Increment by 2 here, to distinguish in the export
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count0 incremented by 2.0
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count1 incremented by 2.0
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count2 incremented by 2.0
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count3 incremented by 2.0

# On shutdown, all counters are exported once more
[main] INFO org.pirgeo.example.MyLogCounterRegistry - Shutdown request received, exporting once more, then shutting down...
[main] INFO org.pirgeo.example.MyLogCounterRegistry - Export #2

# In the last export interval, the results from the previous interval are exported, which is unexpected.
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count1 | created_at=0,incremented_at=0 | 1.00
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count2 | created_at=0,incremented_at=1 | 1.00
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count3 | created_at=0,incremented_at=2 | 0.00
[main] INFO org.pirgeo.example.MyLogCounterRegistry - count4 | created_at=2,incremented_at=2 | 0.00

Expectations

The expectation is that on shutdown, the change since the last export would be exported.

micrometer-counter-exporter-example's People

Contributors

pirgeo avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.