package com.ldbc.driver.runtime.metrics; import com.ldbc.driver.control.LoggingService; import com.ldbc.driver.control.LoggingServiceFactory; import com.ldbc.driver.temporal.TemporalUtil; import java.util.Comparator; import java.util.concurrent.TimeUnit; import static java.lang.String.format; public class OperationTypeMetricsManager { private static final String METRIC_RUNTIME = "Runtime"; private final TemporalUtil temporalUtil = new TemporalUtil(); private final ContinuousMetricManager runTimeMetric; private final String name; private final TimeUnit unit; private final long highestExpectedRuntimeDurationAsNano; private final LoggingService loggingService; OperationTypeMetricsManager( String name, TimeUnit unit, long highestExpectedRuntimeDurationAsNano, LoggingServiceFactory loggingServiceFactory ) { this.name = name; this.unit = unit; this.highestExpectedRuntimeDurationAsNano = highestExpectedRuntimeDurationAsNano; loggingService = loggingServiceFactory.loggingServiceFor( getClass().getSimpleName() ); this.runTimeMetric = new ContinuousMetricManager( METRIC_RUNTIME, unit, unit.convert( highestExpectedRuntimeDurationAsNano, TimeUnit.NANOSECONDS ), 4 ); } void measure( long runDurationAsNano ) throws MetricsCollectionException { // // Measure operation runtime // if ( runDurationAsNano > highestExpectedRuntimeDurationAsNano ) { String errMsg = format( "Error recording runtime - reported value exceeds maximum allowed. Time " + "reported as maximum.\n" + "Reported: %s %s / %s\n" + "For: %s\n" + "Maximum: %s %s / %s", runDurationAsNano, TimeUnit.NANOSECONDS.name(), temporalUtil.nanoDurationToString( runDurationAsNano ), name, highestExpectedRuntimeDurationAsNano, TimeUnit.NANOSECONDS.name(), temporalUtil.nanoDurationToString( highestExpectedRuntimeDurationAsNano ) ); loggingService.info( errMsg ); runDurationAsNano = highestExpectedRuntimeDurationAsNano; } long runtimeInAppropriateUnit = unit.convert( runDurationAsNano, TimeUnit.NANOSECONDS ); try { runTimeMetric.addMeasurement( runtimeInAppropriateUnit ); } catch ( Throwable e ) { String errMsg = format( "Error encountered adding runtime: %s %s / %s %s\nTo: %s\nHighest expected value: %s %s / %s %s", runDurationAsNano, TimeUnit.NANOSECONDS.name(), runtimeInAppropriateUnit, unit.name(), name, highestExpectedRuntimeDurationAsNano, TimeUnit.NANOSECONDS.name(), unit.convert( highestExpectedRuntimeDurationAsNano, TimeUnit.NANOSECONDS ), unit.name() ); throw new MetricsCollectionException( errMsg, e ); } } public OperationMetricsSnapshot snapshot() { return new OperationMetricsSnapshot( name, unit, count(), runTimeMetric.snapshot() ); } public String name() { return name; } public long count() { return runTimeMetric.snapshot().count(); } static class OperationMetricsNameComparator implements Comparator<OperationMetricsSnapshot> { private static final String EMPTY_STRING = ""; @Override public int compare( OperationMetricsSnapshot metrics1, OperationMetricsSnapshot metrics2 ) { String metrics1Name = (metrics1.name() == null) ? EMPTY_STRING : metrics1.name(); String metrics2Name = (metrics2.name() == null) ? EMPTY_STRING : metrics2.name(); return metrics1Name.compareTo( metrics2Name ); } } }