/** * Creates a new timer function using the given template. This method initializes the default timers. * * @param timerTemplate The template to create the instances from. * @return The newly created function that returns a timer for a given code. */ protected Function<Code, Timer> asTimerFunction(final Supplier<Timer.Builder> timerTemplate) { final Map<Code, Timer> cache = new EnumMap<>(Code.class); final Function<Code, Timer> creator = code -> timerTemplate.get() .tag(TAG_STATUS_CODE, code.name()) .register(this.registry); final Function<Code, Timer> cacheResolver = code -> cache.computeIfAbsent(code, creator); // Eager initialize for (final Code code : this.eagerInitializedCodes) { cacheResolver.apply(code); } return cacheResolver; }
.tags(commonTags) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .tag(TAG_EXCEPTION, "") .description("Times the duration elapsed between a subscription and the onComplete termination of the sequence") .register(registry); this.subscribeToCancelTimer = Timer .builder(METER_FLOW_DURATION) .tags(commonTags) .tag(TAG_STATUS, TAGVALUE_CANCEL) .tag(TAG_EXCEPTION, "") .description("Times the duration elapsed between a subscription and the cancellation of the sequence") .register(registry); .tags(commonTags) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .description("Times the duration elapsed between a subscription and the onError termination of the sequence, with the exception name as a tag"); this.subscribeToErrorTimerFactory = e -> { return subscribeToErrorTimerBuilder .tag(TAG_EXCEPTION, e.getClass().getName()) .register(registry); }; .tags(commonTags) .description("Measures delays between onNext signals (or between onSubscribe and first onNext)") .register(registry);
/** * Returns a newly-registered {@link Timer} configured by {@link #distributionStatisticConfig()}. */ public static Timer newTimer(MeterRegistry registry, String name, Iterable<Tag> tags) { requireNonNull(registry, "registry"); requireNonNull(name, "name"); requireNonNull(tags, "tags"); final Duration maxExpectedValue = Optional.ofNullable(distStatCfg.getMaximumExpectedValue()) .map(Duration::ofNanos).orElse(null); final Duration minExpectedValue = Optional.ofNullable(distStatCfg.getMinimumExpectedValue()) .map(Duration::ofNanos).orElse(null); return Timer.builder(name) .tags(tags) .maximumExpectedValue(maxExpectedValue) .minimumExpectedValue(minExpectedValue) .publishPercentiles(distStatCfg.getPercentiles()) .publishPercentileHistogram(distStatCfg.isPercentileHistogram()) .distributionStatisticBufferLength(distStatCfg.getBufferLength()) .distributionStatisticExpiry(distStatCfg.getExpiry()) .register(registry); }
.tags(commonTags) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .tag(TAG_EXCEPTION, "") .description("Times the duration elapsed between a subscription and the onComplete termination of the sequence") .register(registry); this.subscribeToCancelTimer = Timer .builder(METER_FLOW_DURATION) .tags(commonTags) .tag(TAG_STATUS, TAGVALUE_CANCEL) .tag(TAG_EXCEPTION, "") .description("Times the duration elapsed between a subscription and the cancellation of the sequence") .register(registry); .tags(commonTags) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .description("Times the duration elapsed between a subscription and the onError termination of the sequence, with the exception name as a tag"); this.subscribeToErrorTimerFactory = e -> { return subscribeToErrorTimerBuilder .tag(TAG_EXCEPTION, e.getClass().getName()) .register(registry); }; .tags(commonTags) .description("Measures delays between onNext signals (or between onSubscribe and first onNext)") .register(registry);
Timer timer = Timer.builder(name + ".latency") .publishPercentiles(0.5, 0.9, 0.95, 0.99) .tags(tags) .register(registry); return Operators.lift( (scannable, subscriber) -> {
else { Timer.Builder timerBuilder = Timer.builder(timed.value()) .tags(timed.extraTags()) .description("Timer of @Scheduled task"); timerBuilder = timerBuilder.publishPercentiles(timed.percentiles()); shortTaskTimer = timerBuilder.register(registry);
.tag(tagKey, tagValue); timerBuilder = timerBuilder.publishPercentiles(0.5, 0.95) .publishPercentileHistogram(); .register(meterRegistry);
.tags(commonTags) .tag(FluxMetrics.TAG_STATUS, FluxMetrics.TAGVALUE_ON_COMPLETE) .tag(FluxMetrics.TAG_EXCEPTION, "") .description("Times the duration elapsed between a subscription and the onComplete termination of the sequence") .register(registry); this.subscribeToCancelTimer = Timer .builder(FluxMetrics.METER_FLOW_DURATION) .tags(commonTags) .tag(FluxMetrics.TAG_STATUS, FluxMetrics.TAGVALUE_CANCEL) .tag(FluxMetrics.TAG_EXCEPTION, "") .description("Times the duration elapsed between a subscription and the cancellation of the sequence") .register(registry); .tags(commonTags) .tag(FluxMetrics.TAG_STATUS, FluxMetrics.TAGVALUE_ON_ERROR) .description("Times the duration elapsed between a subscription and the onError termination of the sequence, with the exception name as a tag."); this.subscribeToErrorTimerFactory = e -> { return subscribeToErrorTimerBuilder .tag(FluxMetrics.TAG_EXCEPTION, e.getClass().getName()) .register(registry); };
Timer.Builder builder = Timer.builder(this.name).tags(tags); if (publishPercentileHistogram) { builder.publishPercentileHistogram(); builder.publishPercentiles(percentiles); builder.sla(sla); builder.minimumExpectedValue(minimumExpectedValue); builder.maximumExpectedValue(maximumExpectedValue); builder.register(this.registry).record(spanData.getDuration(), TimeUnit.MICROSECONDS);
@Override public ListenableFuture<ClientHttpResponse> intercept(HttpRequest request, byte[] body, AsyncClientHttpRequestExecution execution) throws IOException { final String urlTemplate = urlTemplateHolder.get(); urlTemplateHolder.remove(); final Clock clock = meterRegistry.config().clock(); final long startTime = clock.monotonicTime(); ListenableFuture<ClientHttpResponse> future; try { future = execution.executeAsync(request, body); } catch (IOException e) { getTimeBuilder(urlTemplate, request, null).register(meterRegistry) .record(clock.monotonicTime() - startTime, TimeUnit.NANOSECONDS); throw e; } future.addCallback(new ListenableFutureCallback<ClientHttpResponse>() { @Override public void onSuccess(final ClientHttpResponse response) { getTimeBuilder(urlTemplate, request, response).register(meterRegistry) .record(clock.monotonicTime() - startTime, TimeUnit.NANOSECONDS); } @Override public void onFailure(final Throwable ex) { getTimeBuilder(urlTemplate, request, null).register(meterRegistry) .record(clock.monotonicTime() - startTime, TimeUnit.NANOSECONDS); } }); return future; }
/** * Creates a new timer function using the given template. This method initializes the default timers. * * @param timerTemplate The template to create the instances from. * @return The newly created function that returns a timer for a given code. */ protected Function<Code, Timer> asTimerFunction(final Supplier<Timer.Builder> timerTemplate) { final Map<Code, Timer> cache = new EnumMap<>(Code.class); final Function<Code, Timer> creator = code -> timerTemplate.get() .tag(TAG_STATUS_CODE, code.name()) .register(this.registry); final Function<Code, Timer> cacheResolver = code -> cache.computeIfAbsent(code, creator); // Eager initialize for (final Code code : this.eagerInitializedCodes) { cacheResolver.apply(code); } return cacheResolver; }
public Object metricsAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object result; MethodProceedingJoinPoint methodProceedingJoinPoint = new MethodProceedingJoinPoint(proceedingJoinPoint); final Clock clock = Metrics.globalRegistry.config().clock(); final long startTime = clock.monotonicTime(); try { result = proceedingJoinPoint.proceed(); getTimerBuilder(methodProceedingJoinPoint, null) .register(Metrics.globalRegistry) .record(clock.monotonicTime() - startTime, TimeUnit.NANOSECONDS); } catch (Throwable e) { getTimerBuilder(methodProceedingJoinPoint, e) .register(Metrics.globalRegistry) .record(clock.monotonicTime() - startTime, TimeUnit.NANOSECONDS); throw e; } return result; }
private Object timedProceed(ProceedingJoinPoint pjp, Timed timed) throws Throwable { if (timed.value().isEmpty()) { return pjp.proceed(); } Timer.Sample sample = Timer.start(registry); try { return pjp.proceed(); } finally { sample.stop( Timer.builder(timed.value()) .description(timed.description().isEmpty() ? null : timed.description()) .tags(timed.extraTags()) .tags(tagsBasedOnJoinpoint.apply(pjp)) .publishPercentileHistogram(timed.histogram()) .publishPercentiles(timed.percentiles().length == 0 ? null : timed.percentiles()) .register(registry)); } } }
private Set<Timer> shortTimers(Set<Timed> timed, RequestEvent event) { /* * Given we didn't find any matching resource method, 404s will be only * recorded when auto-time-requests is enabled. On par with WebMVC * instrumentation. */ if ((timed == null || timed.isEmpty()) && autoTimeRequests) { return Collections.singleton(registry.timer(metricName, tagsProvider.httpRequestTags(event))); } if (timed == null) { return Collections.emptySet(); } return timed.stream() .map(t -> Timer.builder(t, metricName).tags(tagsProvider.httpRequestTags(event)).register(registry)) .collect(Collectors.toSet()); }
@Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { final String urlTemplate = urlTemplateHolder.get(); urlTemplateHolder.remove(); final Clock clock = meterRegistry.config().clock(); final long startTime = clock.monotonicTime(); ClientHttpResponse response = null; try { response = execution.execute(request, body); return response; } finally { getTimeBuilder(urlTemplate, request, response).register(this.meterRegistry) .record(clock.monotonicTime() - startTime, TimeUnit.NANOSECONDS); } }
private void record(TimingSampleContext timingContext, HttpServletResponse response, HttpServletRequest request, Object handlerObject, Throwable e) { for (Timed timedAnnotation : timingContext.timedAnnotations) { timingContext.timerSample.stop(Timer.builder(timedAnnotation, metricName) .tags(tagsProvider.httpRequestTags(request, response, handlerObject, e)) .register(registry)); } if (timingContext.timedAnnotations.isEmpty() && autoTimeRequests) { timingContext.timerSample.stop(Timer.builder(metricName) .tags(tagsProvider.httpRequestTags(request, response, handlerObject, e)) .register(registry)); } for (LongTaskTimer.Sample sample : timingContext.longTaskTimerSamples) { sample.stop(); } }
/** * Creates a new timer builder for the given method. * * @param method The method the timer will be created for. * @param name The name of the timer to use. * @param description The description of the timer to use. * @return The newly created timer builder. */ public static Timer.Builder prepareTimerFor(final MethodDescriptor<?, ?> method, final String name, final String description) { return Timer.builder(name) .description(description) .tag(TAG_SERVICE_NAME, extractServiceName(method)) .tag(TAG_METHOD_NAME, extractMethodName(method)); }
private void time(MethodInvocation invocation, long startTime, Exception exception) { Timer .builder(THRIFT_REQUEST_DURATION_METRIC) .publishPercentileHistogram() .description("Thrift handler request duration") .tags( "handler", invocation.getThis().getClass().getCanonicalName(), "method", invocation.getMethod().getName(), "status", exception == null ? "ok" : exception.getClass().getCanonicalName() ) .register(meterRegistry) .record(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); } }
@Override public void action(StateMachine<S, E> stateMachine, Action<S, E> action, long duration) { String actionName = actionToName(action); getActionCounterBuilder(action).register(meterRegistry).increment(); getActionTimerBuilder(action).register(meterRegistry).record(duration, TimeUnit.MILLISECONDS); Map<String, Object> traceInfo = new HashMap<>(); traceInfo.put("action", actionName); traceInfo.put("duration", duration); traceInfo.put("machine", stateMachine.getId()); traceRepository.add(traceInfo); }
private Timer.Builder getTimeBuilder(@Nullable String urlTemplate, HttpRequest request, @Nullable ClientHttpResponse response) { return Timer.builder(this.metricName) .tags(this.tagProvider.getTags(urlTemplate, request, response)) .description("Timer of RestTemplate operation"); } }