2

I'm writing an application with Spring boot 2. My method try to generate value until the value will be unique. Each unique generated value is added to the cache. Generally, it should generate value with the first try, but the more application run - more chance that generated value will have duplicates, and it will be required to generate it again.

I want to have the metric, shows the percentile of tryToGenerate values.

Let's say my code looks the following:

public void generateUniqueValue() {

  String value;
  int tryToGenerate = 0;
  do {
     tryToGenerate ++
     value = generateRandom();
     boolean unique = isUniqueValue(value);

  } while (!unique);

  addGeneratedValueToCache(value);   
}

I'm using micrometer, but have no idea what should I start with. Becase in order to calculate percentile I need to store not the single value, but the array of the values

a3dsfcv
  • 1,146
  • 2
  • 20
  • 35

1 Answers1

2

To determine the result of isUniqueValue(..), you're already storing the used values already. You can use that storage to create a proper metric.

Let's assume that you're storing each used value within a list called usedIds. Additionally, let's say you're generating a unique number between 0 and 1000.

In that case, you could write a method like this:

public float getPercentageUsed() {
    return (float) usedIds.size() / 1000;
}

Now you can create a Gauge to add this value to the metrics. Let's say that the class that's used to generate unique values is called UniqueValueService, and it's a proper Spring bean. In that case, you could create a Gauge bean like this:

@Bean
public Gauge uniqueValueUsedGauge(MeterRegistry registry, UniqueIdService service) {
    return Gauge
        .builder("unique-values-used", service::getPercentageUsed)
        .baseUnit("%")
        .description("Percentage of possible unique values that have been used")
        .register(registry);
    }

Edit: It seems I've misunderstood your question. If you want to get a histogram of tryToGenerate, to see how many attempts succeed within the first, second or nth attempt, you can use a DistributionSummary. For example:

@Bean
public DistributionSummary summary(MeterRegistry registry) {
    return DistributionSummary
        .builder("unique-value-attempts")
        .sla(1, 5, 10)
        .publishPercentileHistogram()
        .register(registry);
}

In this example, it will count how many calls succeeded within the 1st, 5th or 10th attempt.

In your service, you can now autowire the DistributionSummary and at the end of the loop, you can use it like this:

do {
    tryToGenerate++
    value = generateRandom();
    boolean unique = isUniqueValue(value);
  } while (!unique);
distributionSummary.record(tryToGenerate); // Add this

Now you can use /actuator/metrics/unique-value-attempts.histogram?tag=le:1 to see how many calls succeeded within the first try. The same can be done with the 5th and 10th try.

g00glen00b
  • 41,995
  • 13
  • 95
  • 133
  • that's not the exact thing that I was looking for, because I wanted to know the real numbers, how often generated value is not unique. Let's say, due to bad generator implementation, it always gives the same sequence of pseudo-random numbers. – a3dsfcv Dec 08 '19 at 12:14
  • But let me add, that this metric is better than nothing, so guess I will use it – a3dsfcv Dec 08 '19 at 12:15
  • @a3dsfcv I misunderstood your question. I think `DistributionSummary` might be more useful in that case. I've edited my answer with an example. – g00glen00b Dec 08 '19 at 15:26