Skip to content

Commit

Permalink
Allow Metrics to be disabled if not needed
Browse files Browse the repository at this point in the history
  • Loading branch information
raynigon committed Nov 8, 2022
1 parent 432706d commit 78d08ae
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.raynigon.ecs.logging.async.service;

import com.raynigon.ecs.logging.async.service.helper.TimerWrapper;

public interface AsyncMetricsService {

TimerWrapper createQueueTimer(Class<?> source);

TimerWrapper createExecutionTimer(Class<?> source);
}

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.raynigon.ecs.logging.async.service;

import com.raynigon.ecs.logging.async.executor.MdcForkJoinPool;
import com.raynigon.ecs.logging.async.service.helper.SampleWrapper;
import com.raynigon.ecs.logging.async.service.helper.TimerWrapper;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.RequiredArgsConstructor;
Expand All @@ -17,24 +19,22 @@
@RequiredArgsConstructor
public class DefaultAsyncService implements AsyncService {

private static final String QUEUE_TIMER_NAME = "raynigon.async.service.queue.duration";
private static final String EXECUTION_TIMER_NAME = "raynigon.async.service.execution.duration";


private final MdcForkJoinPool forkJoinPool;

private final MeterRegistry meterRegistry;
private final AsyncMetricsService metrics;

private static final Logger log = LoggerFactory.getLogger(DefaultAsyncService.class);

@Override
public <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
String sourceName = formatSource(supplier.getClass());
Timer queueTimer = meterRegistry.timer(QUEUE_TIMER_NAME, "source", sourceName);
Timer execTimer = meterRegistry.timer(EXECUTION_TIMER_NAME, "source", sourceName);
Timer.Sample sample = Timer.start();
TimerWrapper queueTimer = metrics.createQueueTimer(supplier.getClass());
TimerWrapper execTimer = metrics.createExecutionTimer(supplier.getClass());
SampleWrapper sample = queueTimer.start();
Supplier<U> wrapped = () -> {
long nanoseconds = sample.stop(queueTimer);
log.trace("The supplier {} took {} ms in Queue", sourceName, nanoseconds / 1000000.0);
long nanoseconds = queueTimer.stop(sample);
log.trace("The supplier {} took {} ms in Queue", supplier.getClass(), nanoseconds / 1000000.0);
return execTimer.record(supplier);
};
log.trace("Add supplier {} to ForkJoinPool", supplier);
Expand All @@ -43,19 +43,15 @@ public <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {

@Override
public <V> ForkJoinTask<V> submit(Callable<V> callable) {
String sourceName = formatSource(callable.getClass());
Timer queueTimer = meterRegistry.timer(QUEUE_TIMER_NAME, "source", sourceName);
Timer execTimer = meterRegistry.timer(EXECUTION_TIMER_NAME, "source", sourceName);
Timer.Sample sample = Timer.start();
TimerWrapper queueTimer = metrics.createQueueTimer(callable.getClass());
TimerWrapper execTimer = metrics.createExecutionTimer(callable.getClass());
SampleWrapper sample = queueTimer.start();
Callable<V> wrapped = () -> {
long nanoseconds = sample.stop(queueTimer);
log.trace("The callable {} took {} ms in Queue", sourceName, nanoseconds / 1000000.0);
long nanoseconds = queueTimer.stop(sample);
log.trace("The callable {} took {} ms in Queue", callable.getClass(), nanoseconds / 1000000.0);
return execTimer.recordCallable(callable);
};
return forkJoinPool.submit(wrapped);
}

private String formatSource(Class<?> source){
return source.getName().split("/")[0];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.raynigon.ecs.logging.async.service;

import com.raynigon.ecs.logging.async.service.helper.MicrometerTimer;
import com.raynigon.ecs.logging.async.service.helper.TimerWrapper;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@ConditionalOnClass(MeterRegistry.class)
@ConditionalOnProperty(name = "raynigon.logging.async.metrics.enabled", havingValue = "true")
public class MicrometerMetricsService implements AsyncMetricsService {


private static final String QUEUE_TIMER_NAME = "raynigon.async.service.queue.duration";
private static final String EXECUTION_TIMER_NAME = "raynigon.async.service.execution.duration";

private final MeterRegistry meterRegistry;

@Override
public TimerWrapper createQueueTimer(Class<?> source) {
Timer timer = meterRegistry.timer(QUEUE_TIMER_NAME, "source", formatSource(source));
return wrap(timer);
}

@Override
public TimerWrapper createExecutionTimer(Class<?> source) {
Timer timer = meterRegistry.timer(EXECUTION_TIMER_NAME, "source", formatSource(source));
return wrap(timer);
}

private TimerWrapper wrap(Timer timer) {
return new MicrometerTimer(timer);
}

private String formatSource(Class<?> source) {
return source.getName().split("/")[0];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.raynigon.ecs.logging.async.service;

import com.raynigon.ecs.logging.async.service.helper.NoOpTimer;
import com.raynigon.ecs.logging.async.service.helper.TimerWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;

@Service
@ConditionalOnMissingBean(AsyncMetricsService.class)
public class NoOpMetricsService implements AsyncMetricsService {
@Override
public TimerWrapper createQueueTimer(Class<?> source) {
return new NoOpTimer();
}

@Override
public TimerWrapper createExecutionTimer(Class<?> source) {
return new NoOpTimer();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.raynigon.ecs.logging.async.service.helper;

import io.micrometer.core.instrument.Timer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class MicrometerSample implements SampleWrapper {

private final Timer timer;
private final Timer.Sample sample;

public long stop() {
return sample.stop(timer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.raynigon.ecs.logging.async.service.helper;

import io.micrometer.core.instrument.Timer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

import java.util.concurrent.Callable;
import java.util.function.Supplier;

@RequiredArgsConstructor
public class MicrometerTimer implements TimerWrapper{

private final Timer timer;

@Override
@SneakyThrows
public <V> V recordCallable(Callable<V> callable) {
return timer.recordCallable(callable);
}

@Override
public <U> U record(Supplier<U> supplier) {
return timer.record(supplier);
}

@Override
public SampleWrapper start() {
return wrap(timer, Timer.start());
}

@Override
public long stop(SampleWrapper wrapper) {
MicrometerSample sample = (MicrometerSample) wrapper;
return sample.stop();
}

private SampleWrapper wrap(Timer timer, Timer.Sample sample) {
return new MicrometerSample(timer, sample);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.raynigon.ecs.logging.async.service.helper;

public class NoOpSample implements SampleWrapper {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.raynigon.ecs.logging.async.service.helper;

import lombok.SneakyThrows;

import java.util.concurrent.Callable;
import java.util.function.Supplier;

public class NoOpTimer implements TimerWrapper {
@Override
@SneakyThrows
public <V> V recordCallable(Callable<V> callable) {
return callable.call();
}

@Override
public <U> U record(Supplier<U> supplier) {
return supplier.get();
}

@Override
public SampleWrapper start() {
return new NoOpSample();
}

@Override
public long stop(SampleWrapper wrapper) {
return -1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.raynigon.ecs.logging.async.service.helper;

public interface SampleWrapper {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.raynigon.ecs.logging.async.service.helper;

import java.util.concurrent.Callable;
import java.util.function.Supplier;

public interface TimerWrapper {
<V> V recordCallable(Callable<V> callable);

<U> U record(Supplier<U> supplier);

SampleWrapper start();

long stop(SampleWrapper wrapper);
}

0 comments on commit 78d08ae

Please sign in to comment.