diff --git a/metrics/core/pom.xml b/metrics/core/pom.xml index 616468a..d978633 100644 --- a/metrics/core/pom.xml +++ b/metrics/core/pom.xml @@ -36,20 +36,8 @@ - io.dropwizard.metrics - metrics-core - - - io.dropwizard.metrics - metrics-jvm - - - io.dropwizard.metrics - metrics-healthchecks - - - org.commonjava.util - http-testserver + org.commonjava.cdi.util + weft org.apache.commons diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/InitializerUtil.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/InitializerUtil.java index b2363c0..8ad9d8b 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/InitializerUtil.java +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/InitializerUtil.java @@ -19,7 +19,7 @@ import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.health.HealthCheck; import com.codahale.metrics.health.HealthCheckRegistry; -import org.commonjava.propulsor.metrics.conf.EnabledMetrics; +import org.commonjava.propulsor.metrics.conf.MetricSubsetConfig; /** * Utility methods to make initializing metrics in a registry simpler and more consistent. @@ -30,7 +30,7 @@ private InitializerUtil() { } - public static void registerIfEnabled( String key, Metric metric, EnabledMetrics enabledMetrics, + public static void registerIfEnabled( String key, Metric metric, MetricSubsetConfig enabledMetrics, MetricRegistry registry ) { if ( enabledMetrics.isEnabled() && enabledMetrics.isEnabled( key ) ) @@ -39,7 +39,7 @@ public static void registerIfEnabled( String key, Metric metric, EnabledMetrics< } } - public static void registerIfEnabled( String key, HealthCheck healthCheck, EnabledMetrics enabledMetrics, + public static void registerIfEnabled( String key, HealthCheck healthCheck, MetricSubsetConfig enabledMetrics, HealthCheckRegistry healthCheckRegistry ) { if ( enabledMetrics.isEnabled() && enabledMetrics.isEnabled( key ) ) diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MeteringContext.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MeteringContext.java new file mode 100644 index 0000000..c513d6d --- /dev/null +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MeteringContext.java @@ -0,0 +1,26 @@ +package org.commonjava.propulsor.metrics; + +import java.util.Set; + +public class MeteringContext +{ + private final Set names; + + private final MetricsManager metricsManager; + + public MeteringContext( final Set names, final MetricsManager metricsManager ) + { + this.names = names; + this.metricsManager = metricsManager; + } + + public void mark() + { + metricsManager.mark( names ); + } + + public void mark(long count) + { + metricsManager.mark( names, count ); + } +} diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsConstants.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsConstants.java index 91a060f..0420b94 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsConstants.java +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsConstants.java @@ -23,4 +23,19 @@ public class MetricsConstants public static final String TIMER = "timer"; + public static final String DEFAULT = "default"; + + public static final String SKIP_METRIC = "skip-this-metric"; + + public static final String CUMULATIVELY_METERED = "cumulatively-metered"; + + public static final String CUMULATIVE_TIMINGS = "cumulative-timings"; + + public static final String CUMULATIVE_COUNTS = "cumulative-counts"; + + // for measuring transfer rates... + public static final double NANOS_PER_SEC = 1E9; + + // for measuring timing in ms... + public static final double NANOS_PER_MILLISECOND = 1E6; } diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsInterceptor.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsInterceptor.java index 5d36d4c..b19b8cf 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsInterceptor.java +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsInterceptor.java @@ -30,11 +30,9 @@ */ package org.commonjava.propulsor.metrics; -import com.codahale.metrics.Meter; -import com.codahale.metrics.Timer; import org.commonjava.propulsor.metrics.annotation.Measure; -import org.commonjava.propulsor.metrics.annotation.MetricNamed; import org.commonjava.propulsor.metrics.conf.MetricsConfig; +import org.commonjava.propulsor.metrics.spi.TimingContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,14 +41,9 @@ import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; import java.lang.reflect.Method; -import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import static com.codahale.metrics.MetricRegistry.name; -import static org.apache.commons.lang3.ClassUtils.getAbbreviatedName; -import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.commonjava.propulsor.metrics.annotation.MetricNamed.DEFAULT; import static org.commonjava.propulsor.metrics.MetricsConstants.EXCEPTION; import static org.commonjava.propulsor.metrics.MetricsConstants.METER; import static org.commonjava.propulsor.metrics.MetricsConstants.TIMER; @@ -91,16 +84,12 @@ public Object operation( InvocationContext context ) throws Exception logger.trace( "Gathering metrics for: {}", context.getContextData() ); String nodePrefix = config.getInstancePrefix(); - String defaultName = getDefaultName( context ); + String defaultName = metricsManager.getDefaultName( context ); + + TimingContext timing = metricsManager.timeAll( Stream.of( measure.timers() ) + .map( n -> metricsManager.getName( nodePrefix, n, defaultName, TIMER ) ) + .collect( Collectors.toSet() ) ); - List timers = Stream.of( measure.timers() ).map( named -> - { - String name = getName( nodePrefix, named, defaultName, TIMER ); - Timer.Context tc = metricsManager.getTimer( name ).time(); - logger.trace( "START: {} ({})", name, tc ); - return tc; - } ) - .collect( Collectors.toList() ); try { @@ -108,60 +97,20 @@ public Object operation( InvocationContext context ) throws Exception } catch ( Exception e ) { - Stream.of( measure.exceptions() ).forEach( ( named ) -> - { - String name = getName( nodePrefix, named, defaultName, EXCEPTION ); - Meter meter = metricsManager.getMeter( name ); - logger.trace( "ERRORS++ {}", name ); - meter.mark(); - } ); + metricsManager.mark( Stream.of( measure.exceptions() ) + .map( n -> metricsManager.getName( nodePrefix, n, defaultName, EXCEPTION ) ) + .collect( Collectors.toSet() ) ); throw e; } finally { - if ( timers != null ) - { - timers.forEach( timer->{ - logger.trace( "STOP: {}", timer ); - timer.stop(); - } ); - - } - Stream.of( measure.meters() ).forEach( ( named ) -> - { - String name = getName( nodePrefix, named, defaultName, METER ); - Meter meter = metricsManager.getMeter( name ); - logger.trace( "CALLS++ {}", name ); - meter.mark(); - } ); - } - } - - /** - * Get default metric name. Use abbreviated package name, e.g., foo.bar.ClassA.methodB -> f.b.ClassA.methodB - */ - private String getDefaultName( InvocationContext context ) - { - // minimum len 1 shortens the package name and keeps class name - String cls = getAbbreviatedName( context.getMethod().getDeclaringClass().getName(), 1 ); - String method = context.getMethod().getName(); - return name( cls, method ); - } + timing.stop(); - /** - * Get the metric fullname. - * @param named user specified name - * @param defaultName 'class name + method name', not null. - */ - private String getName( String instancePrefix, MetricNamed named, String defaultName, String suffix ) - { - String name = named.value(); - if ( isBlank( name ) || name.equals( DEFAULT ) ) - { - name = defaultName; + metricsManager.mark( Stream.of( measure.meters() ) + .map( n -> metricsManager.getName( nodePrefix, n, defaultName, METER ) ) + .collect( Collectors.toSet() ) ); } - return name( instancePrefix, name, suffix ); } } diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsManager.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsManager.java index 63c7d58..a2ae62e 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsManager.java +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsManager.java @@ -15,22 +15,39 @@ */ package org.commonjava.propulsor.metrics; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.Timer; -import com.codahale.metrics.health.HealthCheckRegistry; +import com.codahale.metrics.Gauge; +import org.commonjava.cdi.util.weft.ThreadContext; +import org.commonjava.propulsor.metrics.annotation.MetricNamed; import org.commonjava.propulsor.metrics.conf.MetricsConfig; -import org.commonjava.propulsor.metrics.healthcheck.ManagedHealthCheck; -import org.commonjava.propulsor.metrics.spi.MetricsInitializer; -import org.commonjava.propulsor.metrics.spi.ReporterConfigurator; +import org.commonjava.propulsor.metrics.cumulative.CumulativeTimingContextWrapper; +import org.commonjava.propulsor.metrics.spi.MetricsProvider; +import org.commonjava.propulsor.metrics.spi.TimingContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Instance; import javax.inject.Inject; -import java.io.IOException; +import javax.interceptor.InvocationContext; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; + +import static com.codahale.metrics.MetricRegistry.name; +import static org.apache.commons.lang3.ClassUtils.getAbbreviatedName; +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.commonjava.propulsor.metrics.MetricsConstants.CUMULATIVELY_METERED; +import static org.commonjava.propulsor.metrics.MetricsConstants.CUMULATIVE_COUNTS; +import static org.commonjava.propulsor.metrics.MetricsConstants.CUMULATIVE_TIMINGS; +import static org.commonjava.propulsor.metrics.MetricsConstants.DEFAULT; +import static org.commonjava.propulsor.metrics.MetricsConstants.EXCEPTION; +import static org.commonjava.propulsor.metrics.MetricsConstants.SKIP_METRIC; +import static org.commonjava.propulsor.metrics.MetricsConstants.TIMER; /** * Manager class that it responsible for orchestrating initialization of the metrics / health check registries. @@ -41,73 +58,211 @@ public class MetricsManager private static final Logger logger = LoggerFactory.getLogger( MetricsManager.class ); - @Inject - private Instance healthChecks; - - @Inject - private Instance initializers; - - @Inject - private MetricsConfig config; + private final Random random = new Random(); - @Inject - private Instance> reporterConfigurators; + private final MetricsProvider metricsProvider; - @Inject - private HealthCheckRegistry healthCheckRegistry; + private final MetricsConfig config; @Inject - private MetricRegistry metricRegistry; - - @PostConstruct - public void init() + public MetricsManager( MetricsProvider provider, + MetricsConfig config ) { + this.metricsProvider = provider; + this.config = config; + if ( !config.isEnabled() ) { - logger.info( "Indy metrics subsystem not enabled" ); + logger.info( "Metrics subsystem is not enabled" ); return; } logger.info( "Init metrics subsystem..." ); + } + + public void mark( Set names ) + { + metricsProvider.mark( names ); + } + + public void mark( Set names, long count ) + { + metricsProvider.mark( names, count ); + } + + public TimingContext time( final Set timerNames ) + { + return metricsProvider.time( timerNames ); + } + + public TimingContext time( final String... timerNames ) + { + return metricsProvider.time( timerNames ); + } + + public T wrapWithStandardMetrics( final Supplier method, final Supplier classifier ) + { + String name = classifier.get(); + if ( !isMeteredCumulatively() || SKIP_METRIC.equals( name ) ) + { + return method.get(); + } + + String nodePrefix = config.getInstancePrefix(); + + String metricName = name( nodePrefix, name ); + String startName = name( metricName, "starts" ); + + String timerName = name( metricName, TIMER ); + String errorName = name( name, EXCEPTION ); + String eClassName = null; + + TimingContext timingContext = metricsProvider.time( timerName ); + if ( isMeteredCumulatively() ) + { + timingContext = new CumulativeTimingContextWrapper( timingContext, this, metricName ); + } + + timingContext.start(); + + logger.trace( "START: {}", metricName ); + + try + { + metricsProvider.mark( Collections.singleton( startName ) ); + + return method.get(); + } + catch ( Throwable e ) + { + eClassName = name( name, EXCEPTION, e.getClass().getSimpleName() ); + metricsProvider.mark( new HashSet<>( Arrays.asList( errorName, eClassName ) ) ); - if ( healthChecks != null ) + throw e; + } + finally + { + timingContext.stop(); + metricsProvider.mark( Collections.singleton( metricName ) ); + } + } + + public boolean isMeteredCumulatively() + { + return isMeteredCumulatively( null ); + } + + public boolean isMeteredCumulatively( ThreadContext ctx ) + { + if ( ctx == null ) + { + ctx = ThreadContext.getContext( false ); + } + + return ( ctx == null || ((Boolean) ctx.getOrDefault( CUMULATIVELY_METERED, Boolean.TRUE ) ) ); + } + + public boolean isMetered( Supplier meteringOverride ) + { + int meterRatio = config.getMeterRatio(); + if ( meterRatio <= 1 || random.nextInt() % meterRatio == 0 ) { - healthChecks.forEach( hc -> healthCheckRegistry.register( hc.getName(), hc ) ); + return true; } + else if ( meteringOverride != null && Boolean.TRUE.equals( meteringOverride.get() ) ) + { + return true; + } + + return false; + } + + /** + * Get default metric name. Use abbreviated package name, e.g., foo.bar.ClassA.methodB -> f.b.ClassA.methodB + */ + public String getDefaultName( InvocationContext context ) + { + // minimum len 1 shortens the package name and keeps class name + String cls = getAbbreviatedName( context.getMethod().getDeclaringClass().getName(), 1 ); + String method = context.getMethod().getName(); + return name( cls, method ); + } - if ( initializers != null ) + /** + * Get the metric fullname. + * @param named user specified name + * @param defaultName 'class name + method name', not null. + */ + public String getName( String instancePrefix, MetricNamed named, String defaultName, String suffix ) + { + String name = named.value(); + if ( isBlank( name ) || name.equals( DEFAULT ) ) { - initializers.forEach( init -> { - try - { - init.initialize( metricRegistry, healthCheckRegistry ); - } - catch ( IOException e ) - { - final Logger logger = LoggerFactory.getLogger( getClass() ); - logger.error( String.format( "Failed to initialize metrics subsystem: %s. Error: %s", init, - e.getMessage() ), e ); - } - catch ( ManagedMetricsException e ) - { - e.printStackTrace(); - } - } ); + name = defaultName; } + return name( instancePrefix, name, suffix ); + } - if ( reporterConfigurators != null ) + /** + * Get the metric fullname. + * @param name user specified name + * @param defaultName 'class name + method name', not null. + */ + public String getName( String instancePrefix, String name, String defaultName, String suffix ) + { + if ( isBlank( name ) || name.equals( DEFAULT ) ) { - reporterConfigurators.forEach( rc -> rc.computeEnabled( config ) ); + name = defaultName; } + return name( instancePrefix, name, suffix ); + } + + public TimingContext timeAll( final Set timerNames ) + { + return metricsProvider.time( timerNames ); + } + + public void accumulate( final String name, final Double elapsed ) + { + accumulate( Collections.singleton( name ), elapsed ); + } + + public void accumulate( final Set names, final Double elapsed ) + { + names.forEach( name->{ + ThreadContext ctx = ThreadContext.getContext( true ); + if ( ctx != null ) + { + ctx.putIfAbsent( CUMULATIVE_TIMINGS, new ConcurrentHashMap<>() ); + Map timingMap = (Map) ctx.get( CUMULATIVE_TIMINGS ); + + timingMap.merge( name, elapsed, Double::sum ); + + ctx.putIfAbsent( CUMULATIVE_COUNTS, new ConcurrentHashMap<>() ); + Map countMap = + (Map) ctx.get( CUMULATIVE_COUNTS ); + + countMap.merge( name, 1, ( existingVal, newVal ) -> existingVal + 1 ); + } + } ); + } + + public MeteringContext getMeter( final String name ) + { + return getMeter( Collections.singleton( name ) ); } - public Timer getTimer( String name ) + public MeteringContext getMeter( final Set names ) { - return this.metricRegistry.timer( name ); + return new MeteringContext( names, this ); } - public Meter getMeter( String name ) + public void registerGauges( final String baseName, final Map> gauges ) { - return metricRegistry.meter( name ); + Map> fullyNamed = new HashMap<>(); + gauges.forEach( (name, gauge)->{ + fullyNamed.put(getName( config.getInstancePrefix(), DEFAULT, baseName, name ), gauge); + } ); + metricsProvider.registerGauges( fullyNamed ); } } diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsUtils.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsUtils.java new file mode 100644 index 0000000..4cbe2fd --- /dev/null +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsUtils.java @@ -0,0 +1,54 @@ +package org.commonjava.propulsor.metrics; + +import org.apache.commons.lang3.ClassUtils; + +import static com.codahale.metrics.MetricRegistry.name; +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.commonjava.propulsor.metrics.MetricsConstants.DEFAULT; + +public class MetricsUtils +{ + /** + * Get default metric name. Use abbreviated package name, e.g., foo.bar.ClassA.methodB -> f.b.ClassA.methodB + */ + public static String getDefaultName( Class declaringClass, String method ) + { + // minimum len 1 shortens the package name and keeps class name + String cls = ClassUtils.getAbbreviatedName( declaringClass.getName(), 1 ); + return name( cls, method ); + } + + /** + * Get default metric name. Use abbreviated package name, e.g., foo.bar.ClassA.methodB -> f.b.ClassA.methodB + */ + public static String getDefaultName( String declaringClass, String method ) + { + // minimum len 1 shortens the package name and keeps class name + String cls = ClassUtils.getAbbreviatedName( declaringClass, 1 ); + return name( cls, method ); + } + + /** + * Get the metric fullname with no default value. + * @param nameParts user specified name parts + */ + public static String getSupername( String nodePrefix, String... nameParts ) + { + return name( nodePrefix, nameParts ); + } + + /** + * Get the metric fullname. + * @param name user specified name + * @param defaultName 'class name + method name', not null. + */ + public static String getName( String nodePrefix, String name, String defaultName, String... suffix ) + { + if ( isBlank( name ) || name.equals( DEFAULT ) ) + { + name = defaultName; + } + + return name( name( nodePrefix, name ), suffix ); + } +} diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/annotation/MetricNamed.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/annotation/MetricNamed.java index 1236de3..2999919 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/annotation/MetricNamed.java +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/annotation/MetricNamed.java @@ -21,12 +21,11 @@ import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.commonjava.propulsor.metrics.MetricsConstants.DEFAULT; @Target( { METHOD, TYPE } ) @Retention( RUNTIME ) public @interface MetricNamed { - String DEFAULT = "default"; - String value() default DEFAULT; } \ No newline at end of file diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/EnabledMetrics.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/MetricSubsetConfig.java similarity index 84% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/EnabledMetrics.java rename to metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/MetricSubsetConfig.java index df02367..1132a93 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/EnabledMetrics.java +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/MetricSubsetConfig.java @@ -18,15 +18,12 @@ import org.commonjava.propulsor.config.ConfigurationException; import org.commonjava.propulsor.config.annotation.ConfigName; import org.commonjava.propulsor.config.section.BeanSectionListener; -import org.commonjava.propulsor.config.section.ConfigurationSectionListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Stream; @@ -41,16 +38,18 @@ * In practice, metrics will probably be topical, not arranged around class / package hierarchies. But the same logic * applies. */ -public abstract class EnabledMetrics +public abstract class MetricSubsetConfig extends BeanSectionListener { public static final String ENABLED = "enabled"; + private static final String ENABLED_METRIC_PREFIX = "m."; + private Map enabledMetricMap = new HashMap<>(); private transient Map denormalized = new HashMap<>(); - public void set(String name, boolean enabled) + public void enableMetric( String name, boolean enabled) { enabledMetricMap.put( name, enabled ); } @@ -124,26 +123,18 @@ public void setMapParameters( final Map params ) params.forEach( (name,v)->{ String value = v == null ? null : String.valueOf( v ); - String enabledPrefix = getEnabledPrefix(); - if ( enabledPrefix == null ) + if ( name.startsWith( ENABLED_METRIC_PREFIX ) && name.endsWith( ENABLED ) && name.length() > ( + ENABLED_METRIC_PREFIX.length() + ENABLED.length() + 1 ) ) { - enabledPrefix = ""; - } - - if ( name.startsWith( enabledPrefix ) && name.endsWith( ENABLED ) && name.length() > ( - enabledPrefix.length() + ENABLED.length() + 1 ) ) - { - String trimmed = name.substring( enabledPrefix.length(), name.length() - ENABLED.length() - 1 ); - set( trimmed, Boolean.valueOf( value ) ); + String trimmed = name.substring( ENABLED_METRIC_PREFIX.length(), name.length() - ENABLED.length() - 1 ); + enableMetric( trimmed, Boolean.valueOf( value ) ); } } ); } - protected abstract String getEnabledPrefix(); - public final void computeEnabled( MetricsConfig config ) { - final EnabledMetrics mine = this; + final MetricSubsetConfig mine = this; config.getEnabledMetrics().forEach( (name,flag)->{ mine.computeEnabledIfAbsent( name, n -> flag ); } ); diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/MetricsConfig.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/MetricsConfig.java index 0b0b84c..f782f0e 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/MetricsConfig.java +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/MetricsConfig.java @@ -29,9 +29,9 @@ @Named @SectionName( MetricsConfig.SECTION_NAME ) public class MetricsConfig - extends EnabledMetrics + extends MetricSubsetConfig { - public static final String SECTION_NAME = "metrics"; + public static final String SECTION_NAME = "metrics.global"; public static final TimeUnit RATE_TIMEUNIT = TimeUnit.MILLISECONDS; @@ -39,11 +39,7 @@ public class MetricsConfig private String instancePrefix; - @Override - protected String getEnabledPrefix() - { - return ""; - } + private Integer meterRatio; public String getInstancePrefix() { @@ -56,4 +52,14 @@ public void setInstancePrefix( final String instancePrefix ) this.instancePrefix = instancePrefix; } + public int getMeterRatio() + { + return meterRatio == null ? 1 : meterRatio; + } + + @ConfigName( "meter.ratio" ) + public void setMeterRatio( Integer ratio ) + { + this.meterRatio = meterRatio; + } } diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/cumulative/CumulativeTimingContextWrapper.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/cumulative/CumulativeTimingContextWrapper.java new file mode 100644 index 0000000..c187848 --- /dev/null +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/cumulative/CumulativeTimingContextWrapper.java @@ -0,0 +1,53 @@ +package org.commonjava.propulsor.metrics.cumulative; + +import org.commonjava.cdi.util.weft.ThreadContext; +import org.commonjava.propulsor.metrics.MetricsManager; +import org.commonjava.propulsor.metrics.spi.TimingContext; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import static org.commonjava.propulsor.metrics.MetricsConstants.CUMULATIVE_COUNTS; +import static org.commonjava.propulsor.metrics.MetricsConstants.CUMULATIVE_TIMINGS; +import static org.commonjava.propulsor.metrics.MetricsConstants.NANOS_PER_MILLISECOND; + +public class CumulativeTimingContextWrapper + implements TimingContext +{ + private final TimingContext context; + + private MetricsManager manager; + + private Set names; + + private long start; + + public CumulativeTimingContextWrapper( TimingContext context, MetricsManager manager, String... names ) + { + this.context = context; + this.manager = manager; + this.names = new HashSet<>( Arrays.asList( names ) ); + } + + @Override + public void start() + { + context.start(); + start = System.nanoTime(); + } + + @Override + public Set stop() + { + Set results = context.stop(); + + + double elapsed = (System.nanoTime() - start) / NANOS_PER_MILLISECOND; + manager.accumulate( names, elapsed ); + + return results; + } +} diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/MetricsProvider.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/MetricsProvider.java new file mode 100644 index 0000000..7c3bdd2 --- /dev/null +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/MetricsProvider.java @@ -0,0 +1,18 @@ +package org.commonjava.propulsor.metrics.spi; + +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +public interface MetricsProvider +{ + TimingContext time( Set timerNames ); + + TimingContext time( String... timerNames ); + + void mark( Set metricNames ); + + void mark( Set names, long count ); + + void registerGauges( Map> gauges ); +} diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/TimingContext.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/TimingContext.java new file mode 100644 index 0000000..3c9bb1d --- /dev/null +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/TimingContext.java @@ -0,0 +1,10 @@ +package org.commonjava.propulsor.metrics.spi; + +import java.util.Set; + +public interface TimingContext +{ + void start(); + + Set stop(); +} diff --git a/metrics/reporter-elasticsearch/pom.xml b/metrics/dropwizard/pom.xml similarity index 85% rename from metrics/reporter-elasticsearch/pom.xml rename to metrics/dropwizard/pom.xml index fc36035..a21e271 100644 --- a/metrics/reporter-elasticsearch/pom.xml +++ b/metrics/dropwizard/pom.xml @@ -25,19 +25,19 @@ 1.5-SNAPSHOT - propulsor-metrics-reporter-elasticsearch + propulsor-metrics-dropwizard - Propulsor :: Metrics Reporter :: Elasticsearch + Propulsor :: Metrics Dropwizard Adapter - org.commonjava.propulsor.metrics - propulsor-metrics-core + org.commonjava.propulsor.config + propulsor-configuration-core - org.commonjava.propulsor.config - propulsor-configuration-core + org.commonjava.propulsor.metrics + propulsor-metrics-core @@ -46,19 +46,19 @@ io.dropwizard.metrics - metrics-healthchecks + metrics-jvm - javax.enterprise - cdi-api + io.dropwizard.metrics + metrics-healthchecks org.commonjava.util http-testserver - org.elasticsearch - metrics-elasticsearch-reporter + org.apache.commons + commons-lang3 diff --git a/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardConstants.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardConstants.java new file mode 100644 index 0000000..18d32af --- /dev/null +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardConstants.java @@ -0,0 +1,5 @@ +package org.commonjava.propulsor.metrics.dropwizard; + +public final class DropwizardConstants +{ +} diff --git a/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardMetrics.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardMetrics.java new file mode 100644 index 0000000..9ced266 --- /dev/null +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardMetrics.java @@ -0,0 +1,129 @@ +/** + * Copyright (C) 2011-2020 Red Hat, Inc. (https://github.com/Commonjava/indy) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.commonjava.propulsor.metrics.dropwizard; + +import com.codahale.metrics.Gauge; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.health.HealthCheckRegistry; +import org.commonjava.propulsor.metrics.dropwizard.config.DropwizardConfig; +import org.commonjava.propulsor.metrics.dropwizard.spi.MetricsInitializer; +import org.commonjava.propulsor.metrics.spi.MetricsProvider; +import org.commonjava.propulsor.metrics.spi.TimingContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static com.codahale.metrics.MetricRegistry.name; + +/** + * Created by xiabai on 2/27/17. Adapted to propulsor by John Casey, 2020. + */ +@ApplicationScoped +public class DropwizardMetrics + implements MetricsProvider +{ + + public static final String METRIC_LOGGER_NAME = "org.commonjava.propulsor.metrics"; + + private static final Logger logger = LoggerFactory.getLogger( METRIC_LOGGER_NAME ); + + private MetricRegistry metricRegistry; + + private HealthCheckRegistry healthCheckRegistry; + + private DropwizardConfig config; + + @Inject + public DropwizardMetrics( MetricRegistry metricRegistry, HealthCheckRegistry healthCheckRegistry, + DropwizardConfig dropwizardConfig, Instance metricsInitializers ) + { + this.metricRegistry = metricRegistry; + this.healthCheckRegistry = healthCheckRegistry; + this.config = dropwizardConfig; + init( metricsInitializers ); + } + + public DropwizardMetrics( MetricRegistry metricRegistry, HealthCheckRegistry healthCheckRegistry, + DropwizardConfig dropwizardConfig, Set metricsInitializers ) + { + this.metricRegistry = metricRegistry; + this.healthCheckRegistry = healthCheckRegistry; + this.config = dropwizardConfig; + init( metricsInitializers ); + } + + public void init( final Iterable metricsInitializers ) + { + if ( !config.isEnabled() ) + { + logger.info( "Metrics subsystem not enabled" ); + return; + } + + logger.info( "Init metrics subsystem..." ); + + metricsInitializers.forEach( mi -> mi.initialize( metricRegistry, healthCheckRegistry ) ); + } + + @Override + public DropwizardTimingContext time( Set timers ) + { + Set filteredTimers = + timers.stream().filter( name -> config.isEnabled( name ) ).collect( Collectors.toSet() ); + + return new DropwizardTimingContext( metricRegistry, filteredTimers ); + } + + @Override + public TimingContext time( final String... timerNames ) + { + return time( new HashSet<>( Arrays.asList( timerNames ) ) ); + } + + @Override + public void mark( final Set metricNames ) + { + metricNames.stream() + .filter( name -> config.isEnabled( name ) ) + .forEach( name -> metricRegistry.meter( name ).mark() ); + } + + @Override + public void mark( final Set metricNames, long count ) + { + metricNames.stream() + .filter( name -> config.isEnabled( name ) ) + .forEach( name -> metricRegistry.meter( name ).mark( count ) ); + } + + @Override + public void registerGauges( final Map> gauges ) + { + gauges.forEach( (name, supplier)->{ + Gauge gauge = () -> supplier.get(); + metricRegistry.gauge( name, () -> gauge); + } ); + } +} diff --git a/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardProducer.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardProducer.java new file mode 100644 index 0000000..4862e74 --- /dev/null +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardProducer.java @@ -0,0 +1,24 @@ +package org.commonjava.propulsor.metrics.dropwizard; + +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.health.HealthCheckRegistry; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; + +@ApplicationScoped +public class DropwizardProducer +{ + @ApplicationScoped + @Produces + public MetricRegistry getMetricRegistry() + { + return new MetricRegistry(); + } + + @ApplicationScoped + @Produces + public HealthCheckRegistry getHealthCheckRegistry() { + return new HealthCheckRegistry(); + } +} diff --git a/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardTimingContext.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardTimingContext.java new file mode 100644 index 0000000..35324ba --- /dev/null +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardTimingContext.java @@ -0,0 +1,48 @@ +package org.commonjava.propulsor.metrics.dropwizard; + +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.Timer; +import org.commonjava.propulsor.metrics.spi.TimingContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; + +public class DropwizardTimingContext + implements TimingContext +{ + private final MetricRegistry metricRegistry; + + private final Set timerNames; + + private final Logger logger = LoggerFactory.getLogger( getClass() ); + + private final Set timers; + + private Set started; + + public DropwizardTimingContext( final MetricRegistry metricRegistry, final Set timerNames ) + { + this.metricRegistry = metricRegistry; + this.timerNames = timerNames; + this.timers = timerNames.stream().map( name ->metricRegistry.timer( name ) ) + .collect( Collectors.toSet() ); + } + + public void start() + { + this.started = timers.stream().map(t->t.time()).collect( Collectors.toSet() ); + } + + public Set stop() + { + if ( started != null ) + { + return started.stream().map( t->t.stop() ).collect( Collectors.toSet() ); + } + + return Collections.emptySet(); + } +} diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/ConsoleReporterConfig.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/config/ConsoleReporterConfig.java similarity index 90% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/ConsoleReporterConfig.java rename to metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/config/ConsoleReporterConfig.java index d6c22d9..150b30f 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/ConsoleReporterConfig.java +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/config/ConsoleReporterConfig.java @@ -13,21 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.commonjava.propulsor.metrics.conf; +package org.commonjava.propulsor.metrics.dropwizard.config; import org.commonjava.propulsor.config.annotation.ConfigName; import org.commonjava.propulsor.config.annotation.SectionName; -import org.commonjava.propulsor.metrics.spi.ReporterConfigurator; +import org.commonjava.propulsor.metrics.dropwizard.spi.ReporterConfiguration; import javax.enterprise.context.ApplicationScoped; -import java.io.PrintStream; import java.util.Locale; import java.util.TimeZone; @ApplicationScoped -@SectionName( "metrics.console" ) +@SectionName( "metrics.dropwizard.console" ) public class ConsoleReporterConfig - extends ReporterConfigurator + extends ReporterConfiguration { private transient TimeZone timeZone; diff --git a/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/config/DropwizardConfig.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/config/DropwizardConfig.java new file mode 100644 index 0000000..6872901 --- /dev/null +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/config/DropwizardConfig.java @@ -0,0 +1,16 @@ +package org.commonjava.propulsor.metrics.dropwizard.config; + +import org.commonjava.propulsor.config.annotation.SectionName; +import org.commonjava.propulsor.metrics.conf.MetricSubsetConfig; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Named; + +@ApplicationScoped +@Named +@SectionName("metrics.dropwizard") +public class DropwizardConfig + extends MetricSubsetConfig +{ + +} diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/reporter/ConsoleReporterInitializer.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/console/ConsoleReporterInitializer.java similarity index 86% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/reporter/ConsoleReporterInitializer.java rename to metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/console/ConsoleReporterInitializer.java index 6296d62..39f4907 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/reporter/ConsoleReporterInitializer.java +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/console/ConsoleReporterInitializer.java @@ -13,21 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.commonjava.propulsor.metrics.reporter; +package org.commonjava.propulsor.metrics.dropwizard.console; import com.codahale.metrics.ConsoleReporter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.health.HealthCheckRegistry; -import org.commonjava.propulsor.metrics.ManagedMetricsException; -import org.commonjava.propulsor.metrics.conf.ConsoleReporterConfig; import org.commonjava.propulsor.metrics.conf.MetricsConfig; -import org.commonjava.propulsor.metrics.spi.MetricsInitializer; +import org.commonjava.propulsor.metrics.dropwizard.config.ConsoleReporterConfig; +import org.commonjava.propulsor.metrics.dropwizard.spi.MetricsInitializer; +import org.commonjava.propulsor.metrics.dropwizard.spi.EnabledMetricFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import java.io.IOException; import java.util.concurrent.TimeUnit; import static org.commonjava.propulsor.metrics.conf.MetricsConfig.DURATION_TIMEUNIT; @@ -50,7 +49,6 @@ public ConsoleReporterInitializer( ConsoleReporterConfig config, MetricsConfig m @Override public void initialize( MetricRegistry registry, HealthCheckRegistry healthCheckRegistry ) - throws IOException, ManagedMetricsException { if ( config.isEnabled() ) { @@ -62,6 +60,7 @@ public void initialize( MetricRegistry registry, HealthCheckRegistry healthCheck .convertRatesTo( RATE_TIMEUNIT ) .formattedFor( config.getTimeZone() ) .formattedFor( config.getLocale() ) + .filter( new EnabledMetricFilter( config ) ) .build() .start( config.getReportSeconds(), TimeUnit.SECONDS ); } diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/jvm/JVMInitializer.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/jvm/JVMInitializer.java similarity index 95% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/jvm/JVMInitializer.java rename to metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/jvm/JVMInitializer.java index 6de2a0d..1362264 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/jvm/JVMInitializer.java +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/jvm/JVMInitializer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.commonjava.propulsor.metrics.jvm; +package org.commonjava.propulsor.metrics.dropwizard.jvm; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.health.HealthCheckRegistry; @@ -24,7 +24,7 @@ import com.codahale.metrics.jvm.MemoryUsageGaugeSet; import com.codahale.metrics.jvm.ThreadStatesGaugeSet; import org.commonjava.propulsor.metrics.conf.MetricsConfig; -import org.commonjava.propulsor.metrics.spi.MetricsInitializer; +import org.commonjava.propulsor.metrics.dropwizard.spi.MetricsInitializer; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/jvm/ThreadDeadlockHealthCheck.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/jvm/ThreadDeadlockHealthCheck.java similarity index 92% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/jvm/ThreadDeadlockHealthCheck.java rename to metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/jvm/ThreadDeadlockHealthCheck.java index 63e0d6c..51eeef7 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/jvm/ThreadDeadlockHealthCheck.java +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/jvm/ThreadDeadlockHealthCheck.java @@ -13,15 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.commonjava.propulsor.metrics.jvm; +package org.commonjava.propulsor.metrics.dropwizard.jvm; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.health.HealthCheck; import com.codahale.metrics.health.HealthCheckRegistry; import com.codahale.metrics.jvm.ThreadDeadlockDetector; import org.commonjava.propulsor.metrics.conf.MetricsConfig; -import org.commonjava.propulsor.metrics.healthcheck.ManagedHealthCheck; -import org.commonjava.propulsor.metrics.spi.MetricsInitializer; +import org.commonjava.propulsor.metrics.dropwizard.spi.ManagedHealthCheck; +import org.commonjava.propulsor.metrics.dropwizard.spi.MetricsInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/CompoundHealthCheck.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/CompoundHealthCheck.java new file mode 100644 index 0000000..7b4587f --- /dev/null +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/CompoundHealthCheck.java @@ -0,0 +1,10 @@ +package org.commonjava.propulsor.metrics.dropwizard.spi; + +import com.codahale.metrics.health.HealthCheck; + +import java.util.Map; + +public interface CompoundHealthCheck +{ + Map getHealthChecks(); +} diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/EnabledMetricFilter.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/EnabledMetricFilter.java similarity index 79% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/EnabledMetricFilter.java rename to metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/EnabledMetricFilter.java index 9e167a4..191d04d 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/EnabledMetricFilter.java +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/EnabledMetricFilter.java @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.commonjava.propulsor.metrics.spi; +package org.commonjava.propulsor.metrics.dropwizard.spi; import com.codahale.metrics.Metric; import com.codahale.metrics.MetricFilter; -import org.commonjava.propulsor.metrics.conf.EnabledMetrics; +import org.commonjava.propulsor.metrics.conf.MetricSubsetConfig; public class EnabledMetricFilter implements MetricFilter { - private EnabledMetrics enabledMetrics; + private MetricSubsetConfig enabledMetrics; - public EnabledMetricFilter( EnabledMetrics enabledMetrics ) + public EnabledMetricFilter( MetricSubsetConfig enabledMetrics ) { this.enabledMetrics = enabledMetrics; } diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/healthcheck/ManagedHealthCheck.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/ManagedHealthCheck.java similarity index 90% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/healthcheck/ManagedHealthCheck.java rename to metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/ManagedHealthCheck.java index 79c4134..60c39e8 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/healthcheck/ManagedHealthCheck.java +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/ManagedHealthCheck.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.commonjava.propulsor.metrics.healthcheck; +package org.commonjava.propulsor.metrics.dropwizard.spi; import com.codahale.metrics.health.HealthCheck; import static org.apache.commons.lang3.ClassUtils.getAbbreviatedName; public abstract class ManagedHealthCheck - extends HealthCheck + extends HealthCheck { public String getName() diff --git a/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/MetricSetProvider.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/MetricSetProvider.java new file mode 100644 index 0000000..420fc01 --- /dev/null +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/MetricSetProvider.java @@ -0,0 +1,23 @@ +/** + * Copyright (C) 2011-2020 Red Hat, Inc. (https://github.com/Commonjava/indy) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.commonjava.propulsor.metrics.dropwizard.spi; + +import com.codahale.metrics.MetricRegistry; + +public interface MetricSetProvider +{ + void registerMetricSet( MetricRegistry registry ); +} diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/MetricsInitializer.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/MetricsInitializer.java similarity index 74% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/MetricsInitializer.java rename to metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/MetricsInitializer.java index a3dce6a..a57ab07 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/MetricsInitializer.java +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/MetricsInitializer.java @@ -13,21 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.commonjava.propulsor.metrics.spi; +package org.commonjava.propulsor.metrics.dropwizard.spi; import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.Reporter; import com.codahale.metrics.health.HealthCheckRegistry; -import org.commonjava.propulsor.metrics.ManagedMetricsException; - -import java.io.IOException; /** - * Interface designed to inject a subclass of {@link ReporterConfigurator} and initialize a Metrics reporter based on + * Interface designed to inject a subclass of {@link ReporterConfiguration} and initialize a Metrics reporter based on * its configuration. */ public interface MetricsInitializer { - void initialize( MetricRegistry registry, HealthCheckRegistry healthCheckRegistry ) - throws IOException, ManagedMetricsException; + void initialize( MetricRegistry registry, HealthCheckRegistry healthCheckRegistry ); } diff --git a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/ReporterConfigurator.java b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/ReporterConfiguration.java similarity index 64% rename from metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/ReporterConfigurator.java rename to metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/ReporterConfiguration.java index 0440548..de63348 100644 --- a/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/ReporterConfigurator.java +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/ReporterConfiguration.java @@ -13,27 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.commonjava.propulsor.metrics.spi; +package org.commonjava.propulsor.metrics.dropwizard.spi; -import org.commonjava.propulsor.config.ConfigurationException; -import org.commonjava.propulsor.config.section.ConfigurationSectionListener; -import org.commonjava.propulsor.metrics.conf.EnabledMetrics; -import org.commonjava.propulsor.metrics.conf.MetricsConfig; +import org.commonjava.propulsor.metrics.conf.MetricSubsetConfig; /** * Reporters can configure themselves by implementing this. */ -public abstract class ReporterConfigurator - extends EnabledMetrics +public abstract class ReporterConfiguration + extends MetricSubsetConfig { private long reportPeriod; - @Override - protected final String getEnabledPrefix() - { - return "m."; - } - public long getReportSeconds() { return reportPeriod; diff --git a/metrics/dw-servlet/pom.xml b/metrics/dw-servlet/pom.xml new file mode 100644 index 0000000..29fb5fd --- /dev/null +++ b/metrics/dw-servlet/pom.xml @@ -0,0 +1,69 @@ + + + + 4.0.0 + + + org.commonjava.propulsor.metrics + propulsor-metrics + 1.5-SNAPSHOT + + + propulsor-metrics-dw-servlet + + Propulsor :: Metrics :: Dropwizard Servlet + + + + org.commonjava.propulsor.metrics + propulsor-metrics-core + + + org.commonjava.propulsor.metrics + propulsor-metrics-dropwizard + + + org.commonjava.propulsor.metrics + propulsor-metrics-servlet + + + io.undertow + undertow-servlet + + + + org.commonjava.propulsor.config + propulsor-configuration-core + + + + io.dropwizard.metrics + metrics-core + + + io.dropwizard.metrics + metrics-healthchecks + + + io.dropwizard.metrics + metrics-servlets + + + + diff --git a/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardHealthCheckServletContextListener.java b/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardHealthCheckServletContextListener.java new file mode 100644 index 0000000..bb9f645 --- /dev/null +++ b/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardHealthCheckServletContextListener.java @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2011-2020 Red Hat, Inc. (https://github.com/Commonjava/indy) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.commonjava.propulsor.metrics.dropwizard.servlet; + +import com.codahale.metrics.health.HealthCheckRegistry; +import com.codahale.metrics.servlets.HealthCheckServlet; + +import javax.enterprise.inject.spi.CDI; + +public class DropwizardHealthCheckServletContextListener + extends HealthCheckServlet.ContextListener +{ + @Override + protected HealthCheckRegistry getHealthCheckRegistry() + { + return CDI.current().select( HealthCheckRegistry.class ).get(); + } +} diff --git a/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardMetricServletProvider.java b/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardMetricServletProvider.java new file mode 100644 index 0000000..e76dcd0 --- /dev/null +++ b/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardMetricServletProvider.java @@ -0,0 +1,38 @@ +package org.commonjava.propulsor.metrics.dropwizard.servlet; + +import com.codahale.metrics.servlets.HealthCheckServlet; +import io.undertow.servlet.Servlets; +import io.undertow.servlet.api.DeploymentInfo; +import org.commonjava.propulsor.metrics.servlet.MetricServletProvider; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.inject.Named; + +@ApplicationScoped +@Named +public class DropwizardMetricServletProvider + implements MetricServletProvider +{ + + private final DropwizardServletConfig config; + + @Inject + public DropwizardMetricServletProvider( DropwizardServletConfig config ) + { + + this.config = config; + } + + @Override + public DeploymentInfo get() + { + return new DeploymentInfo().addListener( + Servlets.listener( DropwizardHealthCheckServletContextListener.class ) ) + .setContextPath( config.getContextPath() ) + .addServlet( Servlets.servlet( "healthcheck", HealthCheckServlet.class ) + .addMapping( config.getContextPath() ) ) + .setDeploymentName( "Dropwizard HealthCheck Deployment" ) + .setClassLoader( ClassLoader.getSystemClassLoader() ); + } +} diff --git a/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardServletConfig.java b/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardServletConfig.java new file mode 100644 index 0000000..e106960 --- /dev/null +++ b/metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardServletConfig.java @@ -0,0 +1,26 @@ +package org.commonjava.propulsor.metrics.dropwizard.servlet; + +import org.commonjava.propulsor.config.annotation.ConfigName; +import org.commonjava.propulsor.config.annotation.SectionName; + +import javax.enterprise.context.ApplicationScoped; + +@SectionName("metrics.dropwizard.servlet") +@ApplicationScoped +public class DropwizardServletConfig +{ + private static final String DEFAULT_CONTEXT_PATH = "/healthchecks"; + + private String contextPath; + + public String getContextPath() + { + return contextPath == null ? DEFAULT_CONTEXT_PATH : contextPath; + } + + @ConfigName( "context.path" ) + public void setContextPath( final String contextPath ) + { + this.contextPath = contextPath; + } +} diff --git a/metrics/pom.xml b/metrics/pom.xml index 24181d4..96b9d01 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -67,20 +67,14 @@ - com.internetitem - logback-elasticsearch-appender - 1.6 + io.prometheus + simpleclient_servlet + ${prometheusClientVersion} - - io.github.hengyunabc - zabbix-api - 0.0.2 - - - io.github.hengyunabc - zabbix-sender - 0.0.4 + io.prometheus + simpleclient_dropwizard + ${prometheusClientVersion} @@ -88,9 +82,11 @@ core - reporter-zabbix - reporter-elasticsearch - reporter-graphite + servlet + dropwizard + dw-servlet + reporter-dw-graphite + reporter-dw-prometheus diff --git a/metrics/reporter-graphite/pom.xml b/metrics/reporter-dw-graphite/pom.xml similarity index 89% rename from metrics/reporter-graphite/pom.xml rename to metrics/reporter-dw-graphite/pom.xml index 5d8f448..ba7907f 100644 --- a/metrics/reporter-graphite/pom.xml +++ b/metrics/reporter-dw-graphite/pom.xml @@ -25,7 +25,7 @@ 1.5-SNAPSHOT - propulsor-metrics-reporter-graphite + propulsor-metrics-reporter-dw-graphite Propulsor :: Metrics Reporter :: Graphite @@ -34,6 +34,10 @@ org.commonjava.propulsor.metrics propulsor-metrics-core + + org.commonjava.propulsor.metrics + propulsor-metrics-dropwizard + org.commonjava.propulsor.config diff --git a/metrics/reporter-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/GraphiteReporterInitializer.java b/metrics/reporter-dw-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/GraphiteReporterInitializer.java similarity index 89% rename from metrics/reporter-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/GraphiteReporterInitializer.java rename to metrics/reporter-dw-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/GraphiteReporterInitializer.java index d4a8d83..c54a3d3 100644 --- a/metrics/reporter-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/GraphiteReporterInitializer.java +++ b/metrics/reporter-dw-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/GraphiteReporterInitializer.java @@ -19,17 +19,15 @@ import com.codahale.metrics.graphite.Graphite; import com.codahale.metrics.graphite.GraphiteReporter; import com.codahale.metrics.health.HealthCheckRegistry; -import org.commonjava.propulsor.metrics.ManagedMetricsException; import org.commonjava.propulsor.metrics.conf.MetricsConfig; import org.commonjava.propulsor.metrics.graphite.conf.GraphiteReporterConfig; -import org.commonjava.propulsor.metrics.spi.EnabledMetricFilter; -import org.commonjava.propulsor.metrics.spi.MetricsInitializer; +import org.commonjava.propulsor.metrics.dropwizard.spi.EnabledMetricFilter; +import org.commonjava.propulsor.metrics.dropwizard.spi.MetricsInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import java.io.IOException; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; @@ -53,9 +51,8 @@ public GraphiteReporterInitializer( GraphiteReporterConfig config, MetricsConfig @Override public void initialize( MetricRegistry registry, HealthCheckRegistry healthCheckRegistry ) - throws IOException, ManagedMetricsException { - if ( config.isEnabled() ) + if ( metricsConfig.isEnabled() ) { Logger logger = LoggerFactory.getLogger( getClass() ); logger.debug( "Setting up Graphite metrics reporter" ); diff --git a/metrics/reporter-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/GraphiteReporterConfig.java b/metrics/reporter-dw-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/GraphiteReporterConfig.java similarity index 87% rename from metrics/reporter-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/GraphiteReporterConfig.java rename to metrics/reporter-dw-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/GraphiteReporterConfig.java index 0bf96e8..d5f9265 100644 --- a/metrics/reporter-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/GraphiteReporterConfig.java +++ b/metrics/reporter-dw-graphite/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/GraphiteReporterConfig.java @@ -17,14 +17,14 @@ import org.commonjava.propulsor.config.annotation.ConfigName; import org.commonjava.propulsor.config.annotation.SectionName; -import org.commonjava.propulsor.metrics.spi.ReporterConfigurator; +import org.commonjava.propulsor.metrics.dropwizard.spi.ReporterConfiguration; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped -@SectionName( "metrics.graphite" ) +@SectionName( "metrics.dropwizard.graphite" ) public class GraphiteReporterConfig - extends ReporterConfigurator + extends ReporterConfiguration { private String host; diff --git a/metrics/reporter-dw-prometheus/pom.xml b/metrics/reporter-dw-prometheus/pom.xml new file mode 100644 index 0000000..86244d1 --- /dev/null +++ b/metrics/reporter-dw-prometheus/pom.xml @@ -0,0 +1,69 @@ + + + + 4.0.0 + + + org.commonjava.propulsor.metrics + propulsor-metrics + 1.5-SNAPSHOT + + + propulsor-metrics-reporter-dw-prometheus + + Propulsor :: Metrics Reporter :: Prometheus + + + + org.commonjava.propulsor.metrics + propulsor-metrics-core + + + org.commonjava.propulsor.metrics + propulsor-metrics-dropwizard + + + org.commonjava.propulsor.metrics + propulsor-metrics-dw-servlet + + + + org.commonjava.propulsor.config + propulsor-configuration-core + + + + io.dropwizard.metrics + metrics-core + + + io.dropwizard.metrics + metrics-healthchecks + + + + io.prometheus + simpleclient_servlet + + + io.prometheus + simpleclient_dropwizard + + + diff --git a/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/DWPrometheusSampleBuilder.java b/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/DWPrometheusSampleBuilder.java new file mode 100644 index 0000000..c8b87be --- /dev/null +++ b/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/DWPrometheusSampleBuilder.java @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2011-2020 Red Hat, Inc. (https://github.com/Commonjava/indy) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.commonjava.propulsor.metrics.graphite; + +import io.prometheus.client.Collector; +import io.prometheus.client.dropwizard.samplebuilder.DefaultSampleBuilder; + +import java.util.ArrayList; +import java.util.List; + +public class DWPrometheusSampleBuilder + extends DefaultSampleBuilder +{ + private static final String NODE_NAME_LABEL = "node"; + + private String nodeName; + + public DWPrometheusSampleBuilder( String nodeName ) + { + super(); + this.nodeName = nodeName; + } + + @Override + public Collector.MetricFamilySamples.Sample createSample( final String dropwizardName, final String nameSuffix, + final List additionalLabelNames, + final List additionalLabelValues, + final double value ) + { + List labelNames = new ArrayList( additionalLabelNames ); + labelNames.add( NODE_NAME_LABEL ); + + List labelValues = new ArrayList( additionalLabelValues ); + labelValues.add( nodeName ); + + return super.createSample( dropwizardName, nameSuffix, labelNames, labelValues, value ); + } +} diff --git a/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/PrometheusDeploymentProvider.java b/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/PrometheusDeploymentProvider.java new file mode 100644 index 0000000..d381494 --- /dev/null +++ b/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/PrometheusDeploymentProvider.java @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2011-2020 Red Hat, Inc. (https://github.com/Commonjava/indy) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.commonjava.propulsor.metrics.graphite; + +import com.codahale.metrics.MetricRegistry; +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.dropwizard.DropwizardExports; +import io.prometheus.client.exporter.MetricsServlet; +import io.undertow.servlet.Servlets; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.ServletInfo; +import org.commonjava.propulsor.metrics.conf.MetricsConfig; +import org.commonjava.propulsor.metrics.dropwizard.servlet.DropwizardHealthCheckServletContextListener; +import org.commonjava.propulsor.metrics.graphite.conf.PrometheusReporterConfig; +import org.commonjava.propulsor.metrics.servlet.MetricServletProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.inject.Named; + +@ApplicationScoped +@Named +public class PrometheusDeploymentProvider + implements MetricServletProvider +{ + private final Logger logger = LoggerFactory.getLogger( getClass() ); + + private MetricsConfig config; + + private PrometheusReporterConfig reporterConfig; + + private MetricRegistry metricRegistry; + + @Inject + public PrometheusDeploymentProvider( final MetricRegistry metricRegistry, final MetricsConfig config, + final PrometheusReporterConfig reporterConfig ) + { + this.config = config; + this.reporterConfig = reporterConfig; + this.metricRegistry = metricRegistry; + } + + public DeploymentInfo get() + { + if ( !config.isEnabled() || !reporterConfig.isEnabled() ) + { + return null; + } + + CollectorRegistry.defaultRegistry.register( new DropwizardExports( metricRegistry, new DWPrometheusSampleBuilder( config.getInstancePrefix() ) ) ); + + final ServletInfo servlet = + Servlets.servlet( "prometheus-metrics", MetricsServlet.class ).addMapping( reporterConfig.getContextPath() ); + + final DeploymentInfo di = new DeploymentInfo().addListener( + Servlets.listener( DropwizardHealthCheckServletContextListener.class ) ) + .setContextPath( reporterConfig.getContextPath() ) + .addServlet( servlet ) + .setDeploymentName( "Dropwizard-Prometheus Metrics Exporter" ) + .setClassLoader( ClassLoader.getSystemClassLoader() ); + + logger.info( "Returning deployment info for Prometheus metrics servlet" ); + return di; + } +} diff --git a/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/PrometheusReporterConfig.java b/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/PrometheusReporterConfig.java new file mode 100644 index 0000000..eb76d98 --- /dev/null +++ b/metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/PrometheusReporterConfig.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2015 John Casey (jdcasey@commonjava.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.commonjava.propulsor.metrics.graphite.conf; + +import org.commonjava.propulsor.config.annotation.ConfigName; +import org.commonjava.propulsor.config.annotation.SectionName; +import org.commonjava.propulsor.metrics.dropwizard.spi.ReporterConfiguration; + +import javax.enterprise.context.ApplicationScoped; + +@ApplicationScoped +@SectionName( "metrics.dropwizard.prometheus" ) +public class PrometheusReporterConfig + extends ReporterConfiguration +{ + public static final String DEFAULT_CONTEXT_PATH = "/metrics"; + + private String contextPath; + + public String getContextPath() + { + return contextPath == null ? DEFAULT_CONTEXT_PATH : contextPath; + } + + @ConfigName( "context.path" ) + public void setContextPath( final String contextPath ) + { + this.contextPath = contextPath; + } +} diff --git a/metrics/reporter-elasticsearch/src/main/java/org/commonjava/propulsor/metrics/es/ESReporterInitializer.java b/metrics/reporter-elasticsearch/src/main/java/org/commonjava/propulsor/metrics/es/ESReporterInitializer.java deleted file mode 100644 index c4a381a..0000000 --- a/metrics/reporter-elasticsearch/src/main/java/org/commonjava/propulsor/metrics/es/ESReporterInitializer.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (C) 2015 John Casey (jdcasey@commonjava.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.commonjava.propulsor.metrics.es; - -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.health.HealthCheckRegistry; -import org.commonjava.propulsor.metrics.conf.MetricsConfig; -import org.commonjava.propulsor.metrics.es.conf.ESReporterConfig; -import org.commonjava.propulsor.metrics.spi.EnabledMetricFilter; -import org.commonjava.propulsor.metrics.spi.MetricsInitializer; -import org.elasticsearch.metrics.ElasticsearchReporter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import java.io.IOException; - -import static java.util.concurrent.TimeUnit.SECONDS; - -/** - * Initialize a new Elasticsearch metrics reporter. - */ -@ApplicationScoped -public class ESReporterInitializer - implements MetricsInitializer -{ - private ESReporterConfig config; - - private MetricsConfig metricsConfig; - - @Override - public void initialize( MetricRegistry registry, HealthCheckRegistry healthCheckRegistry ) throws IOException - { - if ( config.isEnabled() ) - { - Logger logger = LoggerFactory.getLogger( getClass() ); - logger.debug( "Setting up Elasticsearch metrics reporter" ); - - ElasticsearchReporter.forRegistry( registry ) - .hosts( config.getHosts().split( "(\\s|[,;])+" ) ) - .index( config.getIndexName() ) - .convertDurationsTo( MetricsConfig.DURATION_TIMEUNIT ) - .convertRatesTo( MetricsConfig.RATE_TIMEUNIT ) - .prefixedWith( metricsConfig.getInstancePrefix() ) - .timeout( config.getTimeout() ) - .indexDateFormat( config.getIndexDateFormat() ) - .filter( new EnabledMetricFilter( config ) ) - .build() - .start( config.getReportSeconds(), SECONDS ); - } - } - - @Inject - public ESReporterInitializer( ESReporterConfig config, MetricsConfig metricsConfig ) - { - this.config = config; - this.metricsConfig = metricsConfig; - } - -} diff --git a/metrics/reporter-elasticsearch/src/main/java/org/commonjava/propulsor/metrics/es/conf/ESReporterConfig.java b/metrics/reporter-elasticsearch/src/main/java/org/commonjava/propulsor/metrics/es/conf/ESReporterConfig.java deleted file mode 100644 index 12dfb55..0000000 --- a/metrics/reporter-elasticsearch/src/main/java/org/commonjava/propulsor/metrics/es/conf/ESReporterConfig.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (C) 2015 John Casey (jdcasey@commonjava.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.commonjava.propulsor.metrics.es.conf; - -import org.commonjava.propulsor.config.annotation.ConfigName; -import org.commonjava.propulsor.config.annotation.SectionName; -import org.commonjava.propulsor.metrics.spi.ReporterConfigurator; - -import javax.enterprise.context.ApplicationScoped; - -@ApplicationScoped -@SectionName( "metrics.elasticsearch" ) -public class ESReporterConfig - extends ReporterConfigurator -{ - private static final String DEFAULT_INDEX_DATE_FORMAT = "YYYY-MM-dd"; - - private static final Integer DEFAULT_TIMEOUT = Integer.valueOf( 2000 ); - - private String indexDateFormat; - - private String indexName; - - private String hosts; - - private Integer timeout; - - public String getIndexDateFormat() - { - return indexDateFormat == null ? DEFAULT_INDEX_DATE_FORMAT : indexDateFormat; - } - - @ConfigName( "index.date.format" ) - public void setIndexDateFormat( String indexDateFormat ) - { - this.indexDateFormat = indexDateFormat; - } - - public String getIndexName() - { - return indexName; - } - - @ConfigName( "index.name" ) - public void setIndexName( String indexName ) - { - this.indexName = indexName; - } - - public String getHosts() - { - return hosts; - } - - @ConfigName( "hosts" ) - public void setHosts( String hosts ) - { - this.hosts = hosts; - } - - public int getTimeout() - { - return timeout == null ? DEFAULT_TIMEOUT : timeout; - } - - @ConfigName( "timeout" ) - public void setTimeout( Integer timeout ) - { - this.timeout = timeout; - } -} diff --git a/metrics/servlet/pom.xml b/metrics/servlet/pom.xml new file mode 100644 index 0000000..02a4b84 --- /dev/null +++ b/metrics/servlet/pom.xml @@ -0,0 +1,60 @@ + + + + 4.0.0 + + + org.commonjava.propulsor.metrics + propulsor-metrics + 1.5-SNAPSHOT + + + propulsor-metrics-servlet + + Propulsor :: Metrics :: Servlet Configurator + + + + org.commonjava.propulsor.metrics + propulsor-metrics-core + + + org.commonjava.propulsor + propulsor-undertow + + + + org.commonjava.propulsor.config + propulsor-configuration-core + + + + io.dropwizard.metrics + metrics-core + + + io.dropwizard.metrics + metrics-graphite + + + io.dropwizard.metrics + metrics-healthchecks + + + diff --git a/metrics/servlet/src/main/java/org/commonjava/propulsor/metrics/servlet/MetricServletProvider.java b/metrics/servlet/src/main/java/org/commonjava/propulsor/metrics/servlet/MetricServletProvider.java new file mode 100644 index 0000000..0d89cae --- /dev/null +++ b/metrics/servlet/src/main/java/org/commonjava/propulsor/metrics/servlet/MetricServletProvider.java @@ -0,0 +1,8 @@ +package org.commonjava.propulsor.metrics.servlet; + +import io.undertow.servlet.api.DeploymentInfo; + +public interface MetricServletProvider +{ + DeploymentInfo get(); +} diff --git a/metrics/servlet/src/main/java/org/commonjava/propulsor/metrics/servlet/MetricsDeploymentInfoProvider.java b/metrics/servlet/src/main/java/org/commonjava/propulsor/metrics/servlet/MetricsDeploymentInfoProvider.java new file mode 100644 index 0000000..201bd14 --- /dev/null +++ b/metrics/servlet/src/main/java/org/commonjava/propulsor/metrics/servlet/MetricsDeploymentInfoProvider.java @@ -0,0 +1,48 @@ +package org.commonjava.propulsor.metrics.servlet; + +import io.undertow.servlet.api.DeploymentInfo; +import org.commonjava.propulsor.deploy.undertow.UndertowDeploymentProvider; + +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import static org.commonjava.propulsor.deploy.undertow.util.DeploymentInfoUtils.merge; + +public class MetricsDeploymentInfoProvider + implements UndertowDeploymentProvider +{ + private final Set metricDeploymentInfos; + + @Inject + public MetricsDeploymentInfoProvider( Instance metricServletProviders ) + { + Set providerSet = new HashSet<>(); + metricServletProviders.forEach( msp -> providerSet.add( msp.get() ) ); + + this.metricDeploymentInfos = providerSet; + } + + public MetricsDeploymentInfoProvider( Set metricServletProviders ) + { + Set providerSet = new HashSet<>(); + metricServletProviders.forEach( msp -> providerSet.add( msp.get() ) ); + + this.metricDeploymentInfos = providerSet; + } + + public MetricsDeploymentInfoProvider( DeploymentInfo metricServletDeployment ) + { + this.metricDeploymentInfos = Collections.singleton( metricServletDeployment ); + } + + public DeploymentInfo getDeploymentInfo() + { + DeploymentInfo di = new DeploymentInfo(); + + merge( di, metricDeploymentInfos ); + return di; + } +} diff --git a/pom.xml b/pom.xml index 1a7ec22..b1f6b7d 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,9 @@ 1.6 1.3 + 1.15 + 1.0 + 3.1.4.Final 2.0.27.Final 2.10.1 @@ -47,6 +50,7 @@ 1.2.3 1.7.25 4.0.2 + 0.7.0 1.8 ${javaVersion} @@ -110,17 +114,27 @@ org.commonjava.propulsor.metrics - propulsor-metrics-reporter-zabbix + propulsor-metrics-dropwizard + 1.5-SNAPSHOT + + + org.commonjava.propulsor.metrics + propulsor-metrics-servlet 1.5-SNAPSHOT org.commonjava.propulsor.metrics - propulsor-metrics-reporter-graphite + propulsor-metrics-dw-servlet 1.5-SNAPSHOT org.commonjava.propulsor.metrics - propulsor-metrics-reporter-elasticsearch + propulsor-metrics-reporter-dw-graphite + 1.5-SNAPSHOT + + + org.commonjava.propulsor.metrics + propulsor-metrics-reporter-dw-prometheus 1.5-SNAPSHOT @@ -146,6 +160,18 @@ 1.5-SNAPSHOT + + org.commonjava.maven.galley + galley-api + ${galleyVersion} + + + + org.commonjava.cdi.util + weft + ${weftVersion} + + commons-io commons-io diff --git a/undertow/src/main/java/org/commonjava/propulsor/deploy/undertow/util/DeploymentInfoUtils.java b/undertow/src/main/java/org/commonjava/propulsor/deploy/undertow/util/DeploymentInfoUtils.java index 4f9ec19..b73d4f7 100644 --- a/undertow/src/main/java/org/commonjava/propulsor/deploy/undertow/util/DeploymentInfoUtils.java +++ b/undertow/src/main/java/org/commonjava/propulsor/deploy/undertow/util/DeploymentInfoUtils.java @@ -70,6 +70,11 @@ public static void merge( final DeploymentInfo into, final Set f public static void merge( final DeploymentInfo into, final DeploymentInfo from ) { + if ( from == null ) + { + return; + } + final Map authMechs = from.getAuthenticationMechanisms(); if ( authMechs != null ) {