From edbc2c9a01cff66199999b9b91cde462498539df Mon Sep 17 00:00:00 2001 From: John Casey Date: Sun, 19 Jan 2020 15:57:43 +0100 Subject: [PATCH 1/2] Refactor metrics and sync with current Indy for features. This commit refactors the metrics subsystem to generalize the interceptor + wrap-with-metrics features away from dropwizard's metrics API. Dropwizard now becomes a provider for the metric implementation, without affecting the way metrics are triggered. Accordingly, the console / graphite reporters are factored out, with the graphite reporter put in a separate module from the dropwizard core. This commit also synchronizes with the current Indy master branch, bringing in cumulative metrics functions (for reporting to logging systems currently) and support for wrapping arbitrary code blocks with metrics (using a lambda). Note that with this commit, the following control levels are available: - global enable/disable of metrics - dropwizard-subsystem enable/disable/selection of metrics (choose which ones to report in DW) - graphite / console reporter enable/disable/selection of metrics - control over whether to report a metric cumulatively, using ThreadContext from weft each of these will get a config section (metrics.global, metrics.dropwizard, metrics.dropwizard.graphite, metrics.dropwizard.console) to allow separate selection of metrics for each. The zabbix and elasticsearch reporters have been removed, since they have never been used, and won't be in the forseeable future. --- metrics/core/pom.xml | 16 +- .../propulsor/metrics/InitializerUtil.java | 6 +- .../propulsor/metrics/MetricsConstants.java | 15 ++ .../propulsor/metrics/MetricsInterceptor.java | 77 ++------ .../propulsor/metrics/MetricsManager.java | 174 ++++++++++++------ .../propulsor/metrics/MetricsUtils.java | 54 ++++++ .../metrics/annotation/MetricNamed.java | 3 +- ...edMetrics.java => MetricSubsetConfig.java} | 27 +-- .../propulsor/metrics/conf/MetricsConfig.java | 10 +- .../CumulativeTimingContextWrapper.java | 64 +++++++ .../metrics/spi/MetricsProvider.java | 14 ++ .../propulsor/metrics/spi/TimingContext.java | 10 + .../pom.xml | 22 +-- .../dropwizard/DropwizardConstants.java | 5 + .../metrics/dropwizard/DropwizardMetrics.java | 114 ++++++++++++ .../dropwizard/DropwizardTimingContext.java | 48 +++++ .../config}/ConsoleReporterConfig.java | 9 +- .../dropwizard/config/DropwizardConfig.java | 16 ++ .../console}/ConsoleReporterInitializer.java | 11 +- .../dropwizard}/jvm/JVMInitializer.java | 4 +- .../jvm/ThreadDeadlockHealthCheck.java | 6 +- .../dropwizard/spi/CompoundHealthCheck.java | 10 + .../dropwizard}/spi/EnabledMetricFilter.java | 8 +- .../dropwizard/spi}/ManagedHealthCheck.java | 4 +- .../dropwizard/spi/MetricSetProvider.java | 23 +++ .../dropwizard}/spi/MetricsInitializer.java | 11 +- .../spi/ReporterConfiguration.java} | 17 +- metrics/pom.xml | 5 +- .../pom.xml | 6 +- .../graphite/GraphiteReporterInitializer.java | 9 +- .../graphite/conf/GraphiteReporterConfig.java | 6 +- .../metrics/es/ESReporterInitializer.java | 74 -------- .../metrics/es/conf/ESReporterConfig.java | 84 --------- pom.xml | 24 ++- 34 files changed, 593 insertions(+), 393 deletions(-) create mode 100644 metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsUtils.java rename metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/{EnabledMetrics.java => MetricSubsetConfig.java} (84%) create mode 100644 metrics/core/src/main/java/org/commonjava/propulsor/metrics/cumulative/CumulativeTimingContextWrapper.java create mode 100644 metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/MetricsProvider.java create mode 100644 metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/TimingContext.java rename metrics/{reporter-elasticsearch => dropwizard}/pom.xml (85%) create mode 100644 metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardConstants.java create mode 100644 metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardMetrics.java create mode 100644 metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardTimingContext.java rename metrics/{core/src/main/java/org/commonjava/propulsor/metrics/conf => dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/config}/ConsoleReporterConfig.java (90%) create mode 100644 metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/config/DropwizardConfig.java rename metrics/{core/src/main/java/org/commonjava/propulsor/metrics/reporter => dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/console}/ConsoleReporterInitializer.java (86%) rename metrics/{core/src/main/java/org/commonjava/propulsor/metrics => dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard}/jvm/JVMInitializer.java (95%) rename metrics/{core/src/main/java/org/commonjava/propulsor/metrics => dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard}/jvm/ThreadDeadlockHealthCheck.java (92%) create mode 100644 metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/CompoundHealthCheck.java rename metrics/{core/src/main/java/org/commonjava/propulsor/metrics => dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard}/spi/EnabledMetricFilter.java (79%) rename metrics/{core/src/main/java/org/commonjava/propulsor/metrics/healthcheck => dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi}/ManagedHealthCheck.java (90%) create mode 100644 metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/MetricSetProvider.java rename metrics/{core/src/main/java/org/commonjava/propulsor/metrics => dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard}/spi/MetricsInitializer.java (74%) rename metrics/{core/src/main/java/org/commonjava/propulsor/metrics/spi/ReporterConfigurator.java => dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/spi/ReporterConfiguration.java} (64%) rename metrics/{reporter-graphite => reporter-dw-graphite}/pom.xml (89%) rename metrics/{reporter-graphite => reporter-dw-graphite}/src/main/java/org/commonjava/propulsor/metrics/graphite/GraphiteReporterInitializer.java (89%) rename metrics/{reporter-graphite => reporter-dw-graphite}/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/GraphiteReporterConfig.java (87%) delete mode 100644 metrics/reporter-elasticsearch/src/main/java/org/commonjava/propulsor/metrics/es/ESReporterInitializer.java delete mode 100644 metrics/reporter-elasticsearch/src/main/java/org/commonjava/propulsor/metrics/es/conf/ESReporterConfig.java 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/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..c873c6b 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,29 @@ */ 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 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.Set; +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.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 +48,136 @@ public class MetricsManager private static final Logger logger = LoggerFactory.getLogger( MetricsManager.class ); - @Inject - private Instance healthChecks; + private final MetricsProvider metricsProvider; - @Inject - private Instance initializers; + private final MetricsConfig config; @Inject - private MetricsConfig config; + public MetricsManager( MetricsProvider provider, + MetricsConfig config ) + { + this.metricsProvider = provider; + this.config = config; - @Inject - private Instance> reporterConfigurators; + if ( !config.isEnabled() ) + { + logger.info( "Metrics subsystem is not enabled" ); + return; + } - @Inject - private HealthCheckRegistry healthCheckRegistry; + logger.info( "Init metrics subsystem..." ); + } - @Inject - private MetricRegistry metricRegistry; + public void mark( Set names ) + { + metricsProvider.mark( names ); + } - @PostConstruct - public void init() + public void mark( String... names ) { - if ( !config.isEnabled() ) + metricsProvider.mark( names ); + } + + 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 ) ) { - logger.info( "Indy metrics subsystem not enabled" ); - return; + return method.get(); } - logger.info( "Init metrics subsystem..." ); + String nodePrefix = config.getInstancePrefix(); + + String metricName = name( nodePrefix, name ); + String startName = name( metricName, "starts" ); - if ( healthChecks != null ) + String timerName = name( metricName, TIMER ); + String errorName = name( name, EXCEPTION ); + String eClassName = null; + + TimingContext timingContext = metricsProvider.time( timerName ); + if ( isMeteredCumulatively() ) { - healthChecks.forEach( hc -> healthCheckRegistry.register( hc.getName(), hc ) ); + timingContext = new CumulativeTimingContextWrapper( timingContext, metricName ); } - if ( initializers != null ) + timingContext.start(); + + logger.trace( "START: {}", metricName ); + + try { - 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(); - } - } ); + metricsProvider.mark( startName ); + + return method.get(); } + catch ( Throwable e ) + { + eClassName = name( name, EXCEPTION, e.getClass().getSimpleName() ); + metricsProvider.mark( errorName, eClassName ); - if ( reporterConfigurators != null ) + throw e; + } + finally { - reporterConfigurators.forEach( rc -> rc.computeEnabled( config ) ); + timingContext.stop(); + metricsProvider.mark( metricName ); } } - public Timer getTimer( String name ) + public boolean isMeteredCumulatively() + { + return isMeteredCumulatively( null ); + } + + public boolean isMeteredCumulatively( ThreadContext ctx ) { - return this.metricRegistry.timer( name ); + if ( ctx == null ) + { + ctx = ThreadContext.getContext( false ); + } + + return ( ctx == null || ((Boolean) ctx.getOrDefault( CUMULATIVELY_METERED, Boolean.TRUE ) ) ); + } + + /** + * 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 ); + } + + /** + * 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 ) ) + { + name = defaultName; + } + return name( instancePrefix, name, suffix ); } - public Meter getMeter( String name ) + public TimingContext timeAll( final Set timerNames ) { - return metricRegistry.meter( name ); + return metricsProvider.time( timerNames ); } } 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..a19426d 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,12 +39,6 @@ public class MetricsConfig private String instancePrefix; - @Override - protected String getEnabledPrefix() - { - return ""; - } - public String getInstancePrefix() { return instancePrefix; 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..0eacf11 --- /dev/null +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/cumulative/CumulativeTimingContextWrapper.java @@ -0,0 +1,64 @@ +package org.commonjava.propulsor.metrics.cumulative; + +import org.commonjava.cdi.util.weft.ThreadContext; +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 Set names; + + private long start; + + public CumulativeTimingContextWrapper( TimingContext context, String... names ) + { + this.context = context; + 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; + + 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 ); + } + } ); + + 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..f9cfb6c --- /dev/null +++ b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/spi/MetricsProvider.java @@ -0,0 +1,14 @@ +package org.commonjava.propulsor.metrics.spi; + +import java.util.Set; + +public interface MetricsProvider +{ + TimingContext time( Set timerNames ); + + TimingContext time( String... timerNames ); + + void mark( Set metricNames ); + + void mark( String... metricNames ); +} 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..4dfae76 --- /dev/null +++ b/metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardMetrics.java @@ -0,0 +1,114 @@ +/** + * 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.MetricRegistry; +import com.codahale.metrics.health.HealthCheckRegistry; +import org.commonjava.propulsor.metrics.conf.MetricsConfig; +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.Set; +import java.util.stream.Collectors; + +/** + * 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 String... metricNames ) + { + mark( new HashSet<>( Arrays.asList( metricNames ) ) ); + } +} 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/pom.xml b/metrics/pom.xml index 24181d4..9673d48 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -88,9 +88,8 @@ core - reporter-zabbix - reporter-elasticsearch - reporter-graphite + dropwizard + reporter-dw-graphite 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-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/pom.xml b/pom.xml index 1a7ec22..f2e1d12 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 @@ -110,17 +113,12 @@ org.commonjava.propulsor.metrics - propulsor-metrics-reporter-zabbix - 1.5-SNAPSHOT - - - org.commonjava.propulsor.metrics - propulsor-metrics-reporter-graphite + propulsor-metrics-dropwizard 1.5-SNAPSHOT org.commonjava.propulsor.metrics - propulsor-metrics-reporter-elasticsearch + propulsor-metrics-reporter-dw-graphite 1.5-SNAPSHOT @@ -146,6 +144,18 @@ 1.5-SNAPSHOT + + org.commonjava.maven.galley + galley-api + ${galleyVersion} + + + + org.commonjava.cdi.util + weft + ${weftVersion} + + commons-io commons-io From fb6a068f8dc590c863a975efe1a379d78623b655 Mon Sep 17 00:00:00 2001 From: John Casey Date: Sun, 19 Jan 2020 22:24:04 +0100 Subject: [PATCH 2/2] Add servlet support for metrics, and add prometheus support. --- .../propulsor/metrics/MeteringContext.java | 26 +++++ .../propulsor/metrics/MetricsManager.java | 97 +++++++++++++++++-- .../propulsor/metrics/conf/MetricsConfig.java | 12 +++ .../CumulativeTimingContextWrapper.java | 25 ++--- .../metrics/spi/MetricsProvider.java | 6 +- .../metrics/dropwizard/DropwizardMetrics.java | 21 +++- .../dropwizard/DropwizardProducer.java | 24 +++++ metrics/dw-servlet/pom.xml | 69 +++++++++++++ ...zardHealthCheckServletContextListener.java | 31 ++++++ .../DropwizardMetricServletProvider.java | 38 ++++++++ .../servlet/DropwizardServletConfig.java | 26 +++++ metrics/pom.xml | 21 ++-- metrics/reporter-dw-prometheus/pom.xml | 69 +++++++++++++ .../graphite/DWPrometheusSampleBuilder.java | 51 ++++++++++ .../PrometheusDeploymentProvider.java | 80 +++++++++++++++ .../conf/PrometheusReporterConfig.java | 43 ++++++++ metrics/servlet/pom.xml | 60 ++++++++++++ .../servlet/MetricServletProvider.java | 8 ++ .../MetricsDeploymentInfoProvider.java | 48 +++++++++ pom.xml | 16 +++ .../undertow/util/DeploymentInfoUtils.java | 5 + 21 files changed, 736 insertions(+), 40 deletions(-) create mode 100644 metrics/core/src/main/java/org/commonjava/propulsor/metrics/MeteringContext.java create mode 100644 metrics/dropwizard/src/main/java/org/commonjava/propulsor/metrics/dropwizard/DropwizardProducer.java create mode 100644 metrics/dw-servlet/pom.xml create mode 100644 metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardHealthCheckServletContextListener.java create mode 100644 metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardMetricServletProvider.java create mode 100644 metrics/dw-servlet/src/main/java/org/commonjava/propulsor/metrics/dropwizard/servlet/DropwizardServletConfig.java create mode 100644 metrics/reporter-dw-prometheus/pom.xml create mode 100644 metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/DWPrometheusSampleBuilder.java create mode 100644 metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/PrometheusDeploymentProvider.java create mode 100644 metrics/reporter-dw-prometheus/src/main/java/org/commonjava/propulsor/metrics/graphite/conf/PrometheusReporterConfig.java create mode 100644 metrics/servlet/pom.xml create mode 100644 metrics/servlet/src/main/java/org/commonjava/propulsor/metrics/servlet/MetricServletProvider.java create mode 100644 metrics/servlet/src/main/java/org/commonjava/propulsor/metrics/servlet/MetricsDeploymentInfoProvider.java 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/MetricsManager.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/MetricsManager.java index c873c6b..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,6 +15,7 @@ */ package org.commonjava.propulsor.metrics; +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; @@ -27,13 +28,22 @@ import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; 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; @@ -48,6 +58,8 @@ public class MetricsManager private static final Logger logger = LoggerFactory.getLogger( MetricsManager.class ); + private final Random random = new Random(); + private final MetricsProvider metricsProvider; private final MetricsConfig config; @@ -73,9 +85,9 @@ public void mark( Set names ) metricsProvider.mark( names ); } - public void mark( String... names ) + public void mark( Set names, long count ) { - metricsProvider.mark( names ); + metricsProvider.mark( names, count ); } public TimingContext time( final Set timerNames ) @@ -108,7 +120,7 @@ public T wrapWithStandardMetrics( final Supplier method, final Supplier T wrapWithStandardMetrics( final Supplier method, final Supplier( Arrays.asList( errorName, eClassName ) ) ); throw e; } finally { timingContext.stop(); - metricsProvider.mark( metricName ); + metricsProvider.mark( Collections.singleton( metricName ) ); } } @@ -150,6 +162,21 @@ public boolean isMeteredCumulatively( ThreadContext ctx ) 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 ) + { + 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 */ @@ -176,8 +203,66 @@ public String getName( String instancePrefix, MetricNamed named, String defaultN return name( instancePrefix, name, suffix ); } + /** + * 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 ) ) + { + 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 MeteringContext getMeter( final Set names ) + { + return new MeteringContext( names, this ); + } + + public void registerGauges( final String baseName, final Map> gauges ) + { + 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/conf/MetricsConfig.java b/metrics/core/src/main/java/org/commonjava/propulsor/metrics/conf/MetricsConfig.java index a19426d..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 @@ -39,6 +39,8 @@ public class MetricsConfig private String instancePrefix; + private Integer meterRatio; + public String getInstancePrefix() { return instancePrefix; @@ -50,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 index 0eacf11..c187848 100644 --- 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 @@ -1,6 +1,7 @@ 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; @@ -18,13 +19,16 @@ public class CumulativeTimingContextWrapper { private final TimingContext context; + private MetricsManager manager; + private Set names; private long start; - public CumulativeTimingContextWrapper( TimingContext context, String... names ) + public CumulativeTimingContextWrapper( TimingContext context, MetricsManager manager, String... names ) { this.context = context; + this.manager = manager; this.names = new HashSet<>( Arrays.asList( names ) ); } @@ -40,24 +44,9 @@ public Set stop() { Set results = context.stop(); - double elapsed = (System.nanoTime() - start) / NANOS_PER_MILLISECOND; - - 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 ); - } - } ); + 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 index f9cfb6c..7c3bdd2 100644 --- 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 @@ -1,6 +1,8 @@ package org.commonjava.propulsor.metrics.spi; +import java.util.Map; import java.util.Set; +import java.util.function.Supplier; public interface MetricsProvider { @@ -10,5 +12,7 @@ public interface MetricsProvider void mark( Set metricNames ); - void mark( String... metricNames ); + void mark( Set names, long count ); + + void registerGauges( Map> gauges ); } 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 index 4dfae76..9ced266 100644 --- 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 @@ -15,9 +15,9 @@ */ 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.conf.MetricsConfig; import org.commonjava.propulsor.metrics.dropwizard.config.DropwizardConfig; import org.commonjava.propulsor.metrics.dropwizard.spi.MetricsInitializer; import org.commonjava.propulsor.metrics.spi.MetricsProvider; @@ -30,9 +30,13 @@ 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. */ @@ -107,8 +111,19 @@ public void mark( final Set metricNames ) } @Override - public void mark( final String... metricNames ) + 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 ) { - mark( new HashSet<>( Arrays.asList( metricNames ) ) ); + 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/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 9673d48..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,8 +82,11 @@ core + servlet dropwizard + dw-servlet reporter-dw-graphite + reporter-dw-prometheus 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/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 f2e1d12..b1f6b7d 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ 1.2.3 1.7.25 4.0.2 + 0.7.0 1.8 ${javaVersion} @@ -116,11 +117,26 @@ propulsor-metrics-dropwizard 1.5-SNAPSHOT + + org.commonjava.propulsor.metrics + propulsor-metrics-servlet + 1.5-SNAPSHOT + + + org.commonjava.propulsor.metrics + propulsor-metrics-dw-servlet + 1.5-SNAPSHOT + org.commonjava.propulsor.metrics propulsor-metrics-reporter-dw-graphite 1.5-SNAPSHOT + + org.commonjava.propulsor.metrics + propulsor-metrics-reporter-dw-prometheus + 1.5-SNAPSHOT + org.commonjava.propulsor.config 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 ) {