m1well
m1well

Reputation: 884

Why is my micrometer gauge only be executed once after application startup?

i want to implement a micrometer gauge, to monitor the amount of records in my database. so I created an aspect with spring-boot-starter-aop which is executed after my service methods are getting called.

Aspect:

@Slf4j
@Aspect
@Configuration
public class ContactAmountAspect {

  @Autowired
  ContactRepository contactRepository;

  @Autowired
  MeterRegistry registry;

  @AfterReturning(value = "execution(* mypackage.ContactService.*(..))")
  public void monitorContactAmount() {
    Gauge
        .builder("contacts.amount", contactRepository.findAll(), List::size)
        .register(registry);
    log.info("Amount of contacts in database: {}", contactRepository.findAll().size());
  }
}

On the /prometheus endpoint I only see the amount of contacts on the first call after the application startup. If I now call my POST rest endpoint and add a contact to my database, only my log.info prints out the new amount of contacts, but my gauge does nothing.
Order:

1. App Startup (let's say with 1 contact in DB)
2. Call Rest Endpoint "getAllContacts"
3. My AOP method starts
4. The gauge monitors contact amount of 1
5. the logger logs contact amount of 1
6. Call Rest Endpoint "postOneContact"
7. My AOP method starts
8. The gauge does nothing or monitors still the amount of 1
9. the logger logs contact amount of 2


What am I doing wrong?

Or is there another way to monitor the amount of records in a database table???

Upvotes: 5

Views: 4475

Answers (2)

vitr
vitr

Reputation: 51

Actually, the problem is incorrect initialization of Gauge metric. You should declare this metric like that:

    Gauge
        .builder("contacts.amount", contactRepository, ContactRepository::count)
        .register(registry);

This code work for me!

Upvotes: 4

m1well
m1well

Reputation: 884

I found out that the gauge builder doesn't work.
instead I have to use this:

@Slf4j
@Aspect
@Configuration
public class AspectConfig {

  @Autowired
  ContactRepository contactRepository;

  AtomicInteger amount = new AtomicInteger(0);

  @AfterReturning("execution(* mypackage.ContactService.*(..))")
  public void monitorContactAmount() {
    Metrics.gauge("database.contacts.amount", amount);
    amount.set(contactRepository.findAll().size());
    log.info("Monitoring amount of contacts in database: {}", contactRepository.findAll().size());
  }
}

Upvotes: 1

Related Questions