diff --git a/.gitignore b/.gitignore index bf3e9b4..dcf033c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,4 @@ /.classpath /.project /.gradle -/build -/plugins \ No newline at end of file +build diff --git a/build.gradle b/build.gradle index 6fce17d..103dce9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,66 +1,108 @@ plugins { - id "org.sonarqube" version "2.6.1" - id "io.codearte.nexus-staging" version "0.11.0" + id "org.sonarqube" version "2.8" + id "io.codearte.nexus-staging" version "0.21.1" } -printf "Host: %s\nOS: %s %s %s\nJVM: %s %s %s %s\nGroovy: %s\nGradle: %s\n" + - "Build: group: ${project.group} name: ${project.name} version: ${project.version}\n", - InetAddress.getLocalHost(), - System.getProperty("os.name"), - System.getProperty("os.arch"), - System.getProperty("os.version"), - System.getProperty("java.version"), - System.getProperty("java.vm.version"), - System.getProperty("java.vm.vendor"), - System.getProperty("java.vm.name"), - GroovySystem.getVersion(), - gradle.gradleVersion +subprojects { -apply plugin: 'java' -apply plugin: 'maven' -apply plugin: 'signing' + apply plugin: 'java' + apply plugin: 'maven' -apply from: 'gradle/ext.gradle' + dependencies { + testCompile "junit:junit:${project.property('junit.version')}" + testCompile "org.apache.logging.log4j:log4j-core:${project.property('log4j.version')}" + testCompile "org.apache.logging.log4j:log4j-slf4j-impl:${project.property('log4j.version')}" + } -configurations { - wagon -} + compileJava { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + compileTestJava { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + tasks.withType(JavaCompile) { + options.compilerArgs << "-Xlint:all" + } + + task javadocJar(type: Jar, dependsOn: classes) { + from javadoc + classifier 'javadoc' + } + + task sourcesJar(type: Jar, dependsOn: classes) { + from sourceSets.main.allSource + classifier 'sources' + } + + artifacts { + archives javadocJar, sourcesJar + } -dependencies { - testCompile "junit:junit:4.12" - testCompile "org.apache.logging.log4j:log4j-core:2.10.0" - testCompile "org.apache.logging.log4j:log4j-slf4j-impl:2.10.0" - wagon 'org.apache.maven.wagon:wagon-ssh:3.0.0' -} + ext { + user = 'jprante' + name = 'metrics' + description = 'A stripped-down and modified version of Coda Hale Metrics' + scmUrl = 'https://github.com/' + user + '/' + name + scmConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git' + scmDeveloperConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git' + } -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:all" << "-profile" << "compact3" -} - -task javadocJar(type: Jar, dependsOn: classes) { - from javadoc - into "build/tmp" - classifier 'javadoc' -} - -task sourcesJar(type: Jar, dependsOn: classes) { - from sourceSets.main.allSource - into "build/tmp" - classifier 'sources' -} - -artifacts { - archives javadocJar, sourcesJar -} - -if (project.hasProperty('signing.keyId')) { - signing { - sign configurations.archives + task sonaTypeUpload(type: Upload) { + group = 'publish' + configuration = configurations.archives + uploadDescriptor = true + repositories { + if (project.hasProperty('ossrhUsername')) { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2') { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots') { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + pom.project { + groupId project.group + artifactId project.name + version project.version + name project.name + description description + packaging 'jar' + inceptionYear '2016' + url scmUrl + organization { + name 'xbib' + url 'http://xbib.org' + } + developers { + developer { + id user + name 'Jörg Prante' + email 'joergprante@gmail.com' + url 'https://github.com/jprante' + } + } + scm { + url scmUrl + connection scmConnection + developerConnection scmDeveloperConnection + } + licenses { + license { + name 'The Apache License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + } + } + } + } } } -apply from: 'gradle/publish.gradle' +nexusStaging { + packageGroup = "org.xbib" +} diff --git a/gradle.properties b/gradle.properties index 8056dc3..d240468 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,7 @@ group = org.xbib name = metrics -version = 1.1.0 +version = 2.0.0 +# test +log4j.version = 2.12.1 junit.version = 4.12 -wagon.version = 3.0.0 diff --git a/gradle/ext.gradle b/gradle/ext.gradle deleted file mode 100644 index 3b01be1..0000000 --- a/gradle/ext.gradle +++ /dev/null @@ -1,8 +0,0 @@ -ext { - user = 'jprante' - name = 'metrics' - description = 'A stripped-down and modified version of Coda Hale Metrics' - scmUrl = 'https://github.com/' + user + '/' + name - scmConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git' - scmDeveloperConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git' -} diff --git a/gradle/publish.gradle b/gradle/publish.gradle deleted file mode 100644 index 376f190..0000000 --- a/gradle/publish.gradle +++ /dev/null @@ -1,72 +0,0 @@ - -task xbibUpload(type: Upload) { - group = 'publish' - configuration = configurations.archives - uploadDescriptor = true - repositories { - if (project.hasProperty("xbibUsername")) { - mavenDeployer { - configuration = configurations.wagon - repository(url: project.property('xbibUrl')) { - authentication(userName: xbibUsername, privateKey: xbibPrivateKey) - } - } - } - } -} - -task sonaTypeUpload(type: Upload) { - group = 'publish' - configuration = configurations.archives - uploadDescriptor = true - repositories { - if (project.hasProperty('ossrhUsername')) { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2') { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots') { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - pom.project { - groupId project.group - artifactId project.name - version project.version - name project.name - description description - packaging 'jar' - inceptionYear '2016' - url scmUrl - organization { - name 'xbib' - url 'http://xbib.org' - } - developers { - developer { - id user - name 'Jörg Prante' - email 'joergprante@gmail.com' - url 'https://github.com/jprante' - } - } - scm { - url scmUrl - connection scmConnection - developerConnection scmDeveloperConnection - } - licenses { - license { - name 'The Apache License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - } - } - } - } -} - -nexusStaging { - packageGroup = "org.xbib" -} diff --git a/gradle/sonarqube.gradle b/gradle/sonarqube.gradle deleted file mode 100644 index 6d4c3fa..0000000 --- a/gradle/sonarqube.gradle +++ /dev/null @@ -1,41 +0,0 @@ -tasks.withType(FindBugs) { - ignoreFailures = true - reports { - xml.enabled = true - html.enabled = false - } -} -tasks.withType(Pmd) { - ignoreFailures = true - reports { - xml.enabled = true - html.enabled = true - } -} -tasks.withType(Checkstyle) { - ignoreFailures = true - reports { - xml.enabled = true - html.enabled = true - } -} - -jacocoTestReport { - reports { - xml.enabled true - csv.enabled false - xml.destination "${buildDir}/reports/jacoco-xml" - html.destination "${buildDir}/reports/jacoco-html" - } -} - -sonarqube { - properties { - property "sonar.projectName", "${project.group} ${project.name}" - property "sonar.sourceEncoding", "UTF-8" - property "sonar.tests", "src/test/java" - property "sonar.scm.provider", "git" - property "sonar.java.coveragePlugin", "jacoco" - property "sonar.junit.reportsPath", "build/test-results/test/" - } -} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 8252d7e..5c2d1cf 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index eac7de5..80c4ad3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Thu Nov 07 15:59:31 CET 2019 +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-rc-1-bin.zip -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index cccdd3d..83f2acf 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -109,8 +125,8 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` diff --git a/gradlew.bat b/gradlew.bat index e95643d..24467a1 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/metrics-api/src/main/java/org/xbib/metrics/api/Clock.java b/metrics-api/src/main/java/org/xbib/metrics/api/Clock.java new file mode 100644 index 0000000..459b1a6 --- /dev/null +++ b/metrics-api/src/main/java/org/xbib/metrics/api/Clock.java @@ -0,0 +1,21 @@ +package org.xbib.metrics.api; + +/** + * An interface for how time passes. + */ +public interface Clock { + + /** + * Returns the current time tick. + * + * @return time tick in nanoseconds + */ + long getTick(); + + /** + * Returns the current time in milliseconds. + * + * @return time in milliseconds + */ + long getTime(); +} diff --git a/src/main/java/org/xbib/metrics/Count.java b/metrics-api/src/main/java/org/xbib/metrics/api/Count.java similarity index 94% rename from src/main/java/org/xbib/metrics/Count.java rename to metrics-api/src/main/java/org/xbib/metrics/api/Count.java index 6c885dd..4e0673f 100644 --- a/src/main/java/org/xbib/metrics/Count.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/Count.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; /** * An interface for metric types which have counts. diff --git a/src/main/java/org/xbib/metrics/Gauge.java b/metrics-api/src/main/java/org/xbib/metrics/api/Gauge.java similarity index 95% rename from src/main/java/org/xbib/metrics/Gauge.java rename to metrics-api/src/main/java/org/xbib/metrics/api/Gauge.java index f3f53ad..0c8a3ff 100644 --- a/src/main/java/org/xbib/metrics/Gauge.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/Gauge.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; /** * A gauge metric is an instantaneous reading of a particular value. To instrument a queue's depth, diff --git a/src/main/java/org/xbib/metrics/Metered.java b/metrics-api/src/main/java/org/xbib/metrics/api/Metered.java similarity index 96% rename from src/main/java/org/xbib/metrics/Metered.java rename to metrics-api/src/main/java/org/xbib/metrics/api/Metered.java index 476ef97..7f4c08b 100644 --- a/src/main/java/org/xbib/metrics/Metered.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/Metered.java @@ -1,4 +1,6 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; + +import org.xbib.metrics.api.Metric; /** * An object which maintains mean and exponentially-weighted rate. diff --git a/src/main/java/org/xbib/metrics/Metric.java b/metrics-api/src/main/java/org/xbib/metrics/api/Metric.java similarity index 57% rename from src/main/java/org/xbib/metrics/Metric.java rename to metrics-api/src/main/java/org/xbib/metrics/api/Metric.java index 9679413..f1f05b6 100644 --- a/src/main/java/org/xbib/metrics/Metric.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/Metric.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; /** * diff --git a/src/main/java/org/xbib/metrics/MetricFilter.java b/metrics-api/src/main/java/org/xbib/metrics/api/MetricFilter.java similarity index 95% rename from src/main/java/org/xbib/metrics/MetricFilter.java rename to metrics-api/src/main/java/org/xbib/metrics/api/MetricFilter.java index 0be8511..a6939d8 100644 --- a/src/main/java/org/xbib/metrics/MetricFilter.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/MetricFilter.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; /** * A filter used to determine whether or not a metric should be reported, among other things. diff --git a/src/main/java/org/xbib/metrics/MetricName.java b/metrics-api/src/main/java/org/xbib/metrics/api/MetricName.java similarity index 99% rename from src/main/java/org/xbib/metrics/MetricName.java rename to metrics-api/src/main/java/org/xbib/metrics/api/MetricName.java index 0ef8668..a867102 100644 --- a/src/main/java/org/xbib/metrics/MetricName.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/MetricName.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; import java.util.Collections; import java.util.HashMap; @@ -10,8 +10,11 @@ import java.util.TreeSet; * A metric name with the ability to include semantic tags. */ public class MetricName implements Comparable { + public static final String SEPARATOR = "."; + public static final Map EMPTY_TAGS = Collections.unmodifiableMap(new HashMap()); + public static final MetricName EMPTY = new MetricName(); private final String key; diff --git a/src/main/java/org/xbib/metrics/MetricSet.java b/metrics-api/src/main/java/org/xbib/metrics/api/MetricSet.java similarity index 77% rename from src/main/java/org/xbib/metrics/MetricSet.java rename to metrics-api/src/main/java/org/xbib/metrics/api/MetricSet.java index 7a6ead4..0221f41 100644 --- a/src/main/java/org/xbib/metrics/MetricSet.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/MetricSet.java @@ -1,11 +1,9 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; import java.util.Map; /** * A set of named metrics. - * - * @see MetricRegistry#registerAll(MetricSet) */ @FunctionalInterface public interface MetricSet extends Metric { diff --git a/src/main/java/org/xbib/metrics/Reservoir.java b/metrics-api/src/main/java/org/xbib/metrics/api/Reservoir.java similarity index 94% rename from src/main/java/org/xbib/metrics/Reservoir.java rename to metrics-api/src/main/java/org/xbib/metrics/api/Reservoir.java index db3e6b6..4bc826b 100644 --- a/src/main/java/org/xbib/metrics/Reservoir.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/Reservoir.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; /** * A statistically representative reservoir of a data stream. diff --git a/src/main/java/org/xbib/metrics/Sampling.java b/metrics-api/src/main/java/org/xbib/metrics/api/Sampling.java similarity index 88% rename from src/main/java/org/xbib/metrics/Sampling.java rename to metrics-api/src/main/java/org/xbib/metrics/api/Sampling.java index 793225e..6dfed5d 100644 --- a/src/main/java/org/xbib/metrics/Sampling.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/Sampling.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; /** * An object which samples values. diff --git a/src/main/java/org/xbib/metrics/Snapshot.java b/metrics-api/src/main/java/org/xbib/metrics/api/Snapshot.java similarity index 98% rename from src/main/java/org/xbib/metrics/Snapshot.java rename to metrics-api/src/main/java/org/xbib/metrics/api/Snapshot.java index c6e1ca3..7450f11 100644 --- a/src/main/java/org/xbib/metrics/Snapshot.java +++ b/metrics-api/src/main/java/org/xbib/metrics/api/Snapshot.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.api; import java.io.OutputStream; diff --git a/metrics-api/src/main/java/org/xbib/metrics/api/package-info.java b/metrics-api/src/main/java/org/xbib/metrics/api/package-info.java new file mode 100644 index 0000000..772933d --- /dev/null +++ b/metrics-api/src/main/java/org/xbib/metrics/api/package-info.java @@ -0,0 +1,4 @@ +/** + * API interfaces for metrics. + */ +package org.xbib.metrics.api; diff --git a/metrics-common/build.gradle b/metrics-common/build.gradle new file mode 100644 index 0000000..740edb1 --- /dev/null +++ b/metrics-common/build.gradle @@ -0,0 +1,3 @@ +dependencies { + compile project(':metrics-api') +} diff --git a/src/main/java/org/xbib/metrics/CountMetric.java b/metrics-common/src/main/java/org/xbib/metrics/common/CountMetric.java similarity index 88% rename from src/main/java/org/xbib/metrics/CountMetric.java rename to metrics-common/src/main/java/org/xbib/metrics/common/CountMetric.java index 4dd3aea..bf40573 100644 --- a/src/main/java/org/xbib/metrics/CountMetric.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/CountMetric.java @@ -1,4 +1,7 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Count; +import org.xbib.metrics.api.Metric; import java.nio.charset.StandardCharsets; import java.util.HashMap; @@ -49,7 +52,8 @@ public class CountMetric implements Metric, Count { checksumIn.put(index + "/" + type, crc32); } if (id != null) { - crc32.update(id.getBytes(StandardCharsets.UTF_8)); + byte[] b = id.getBytes(StandardCharsets.UTF_8); + crc32.update(b, 0, b.length); } } @@ -79,7 +83,8 @@ public class CountMetric implements Metric, Count { checksumOut.put(index + "/" + type, crc32); } if (id != null) { - crc32.update(id.getBytes(StandardCharsets.UTF_8)); + byte[] b = id.getBytes(StandardCharsets.UTF_8); + crc32.update(b, 0, b.length); } } diff --git a/src/main/java/org/xbib/metrics/CpuTimeClock.java b/metrics-common/src/main/java/org/xbib/metrics/common/CpuTimeClock.java similarity index 87% rename from src/main/java/org/xbib/metrics/CpuTimeClock.java rename to metrics-common/src/main/java/org/xbib/metrics/common/CpuTimeClock.java index 05a7669..3dcf61d 100644 --- a/src/main/java/org/xbib/metrics/CpuTimeClock.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/CpuTimeClock.java @@ -1,4 +1,6 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Clock; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; diff --git a/src/main/java/org/xbib/metrics/ExpWeightedMovingAverage.java b/metrics-common/src/main/java/org/xbib/metrics/common/ExpWeightedMovingAverage.java similarity index 97% rename from src/main/java/org/xbib/metrics/ExpWeightedMovingAverage.java rename to metrics-common/src/main/java/org/xbib/metrics/common/ExpWeightedMovingAverage.java index 4f30f24..fea9dde 100644 --- a/src/main/java/org/xbib/metrics/ExpWeightedMovingAverage.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/ExpWeightedMovingAverage.java @@ -1,4 +1,4 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.LongAdder; @@ -11,14 +11,22 @@ import java.util.concurrent.atomic.LongAdder; * Average */ public class ExpWeightedMovingAverage { + private static final double M1_ALPHA = 1 - Math.exp(-5 / 60.0); + private static final double M5_ALPHA = 1 - Math.exp(-5 / 60.0 / 5); + private static final double M15_ALPHA = 1 - Math.exp(-5 / 60.0 / 15); + private final LongAdder uncounted = new LongAdder(); + private final double alpha; + private final double interval; + private volatile boolean initialized = false; - private volatile double rate = 0.0; + + private double rate = 0.0; /** * Create a new EWMA with a specific smoothing constant. diff --git a/src/main/java/org/xbib/metrics/ExponentiallyDecayingReservoir.java b/metrics-common/src/main/java/org/xbib/metrics/common/ExponentiallyDecayingReservoir.java similarity index 96% rename from src/main/java/org/xbib/metrics/ExponentiallyDecayingReservoir.java rename to metrics-common/src/main/java/org/xbib/metrics/common/ExponentiallyDecayingReservoir.java index c0b2325..b1cd32f 100644 --- a/src/main/java/org/xbib/metrics/ExponentiallyDecayingReservoir.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/ExponentiallyDecayingReservoir.java @@ -1,4 +1,8 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Clock; +import org.xbib.metrics.api.Reservoir; +import org.xbib.metrics.api.Snapshot; import static java.lang.Math.exp; import static java.lang.Math.min; @@ -24,7 +28,7 @@ public class ExponentiallyDecayingReservoir implements Reservoir { private static final double DEFAULT_ALPHA = 0.015; private static final long RESCALE_THRESHOLD = TimeUnit.HOURS.toNanos(1); - private final ConcurrentSkipListMap values; + private final ConcurrentSkipListMap values; private final ReentrantReadWriteLock lock; private final double alpha; private final int size; @@ -50,7 +54,7 @@ public class ExponentiallyDecayingReservoir implements Reservoir { * will be towards newer values */ public ExponentiallyDecayingReservoir(int size, double alpha) { - this(size, alpha, Clock.defaultClock()); + this(size, alpha, UserTimeClock.defaultClock()); } /** diff --git a/src/main/java/org/xbib/metrics/Histogram.java b/metrics-common/src/main/java/org/xbib/metrics/common/Histogram.java similarity index 88% rename from src/main/java/org/xbib/metrics/Histogram.java rename to metrics-common/src/main/java/org/xbib/metrics/common/Histogram.java index 4f4beda..1682f1e 100644 --- a/src/main/java/org/xbib/metrics/Histogram.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/Histogram.java @@ -1,4 +1,10 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Count; +import org.xbib.metrics.api.Metric; +import org.xbib.metrics.api.Reservoir; +import org.xbib.metrics.api.Sampling; +import org.xbib.metrics.api.Snapshot; import java.util.concurrent.atomic.LongAdder; @@ -9,7 +15,9 @@ import java.util.concurrent.atomic.LongAdder; * variance */ public class Histogram implements Metric, Sampling, Count { + private final Reservoir reservoir; + private final LongAdder count; /** diff --git a/src/main/java/org/xbib/metrics/Meter.java b/metrics-common/src/main/java/org/xbib/metrics/common/Meter.java similarity index 95% rename from src/main/java/org/xbib/metrics/Meter.java rename to metrics-common/src/main/java/org/xbib/metrics/common/Meter.java index 9b45fc1..29d5994 100644 --- a/src/main/java/org/xbib/metrics/Meter.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/Meter.java @@ -1,4 +1,7 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Clock; +import org.xbib.metrics.api.Metered; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -38,7 +41,7 @@ public class Meter implements Metered { * @param executorService the executor service */ public Meter(ScheduledExecutorService executorService) { - this(executorService, Clock.defaultClock()); + this(executorService, UserTimeClock.defaultClock()); } /** diff --git a/src/main/java/org/xbib/metrics/MetricRegistry.java b/metrics-common/src/main/java/org/xbib/metrics/common/MetricRegistry.java similarity index 79% rename from src/main/java/org/xbib/metrics/MetricRegistry.java rename to metrics-common/src/main/java/org/xbib/metrics/common/MetricRegistry.java index 08001fd..20022de 100644 --- a/src/main/java/org/xbib/metrics/MetricRegistry.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/MetricRegistry.java @@ -1,4 +1,10 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Gauge; +import org.xbib.metrics.api.Metric; +import org.xbib.metrics.api.MetricFilter; +import org.xbib.metrics.api.MetricName; +import org.xbib.metrics.api.MetricSet; import java.util.Collections; import java.util.List; @@ -20,8 +26,10 @@ import java.util.logging.Logger; public class MetricRegistry implements MetricSet { private static final Logger logger = Logger.getLogger(MetricRegistry.class.getName()); + private final ConcurrentMap metrics; - private final List listeners; + + private final List listeners; /** * Creates a new {@link MetricRegistry}. @@ -234,13 +242,13 @@ public class MetricRegistry implements MetricSet { } /** - * Adds a {@link MetricRegistryListener} to a collection of listeners that will be notified on + * Adds a {@link Listener} to a collection of listeners that will be notified on * metric creation. Listeners will be notified in the order in which they are added. * The listener will be notified of all existing metrics when it first registers. * * @param listener the listener that will be notified */ - public void addListener(MetricRegistryListener listener) { + public void addListener(Listener listener) { listeners.add(listener); for (Map.Entry entry : metrics.entrySet()) { @@ -249,11 +257,11 @@ public class MetricRegistry implements MetricSet { } /** - * Removes a {@link MetricRegistryListener} from this registry's collection of listeners. + * Removes a {@link Listener} from this registry's collection of listeners. * * @param listener the listener that will be removed */ - public void removeListener(MetricRegistryListener listener) { + public void removeListener(Listener listener) { listeners.remove(listener); } @@ -397,12 +405,12 @@ public class MetricRegistry implements MetricSet { } private void onMetricAdded(MetricName name, Metric metric) { - for (MetricRegistryListener listener : listeners) { + for (Listener listener : listeners) { notifyListenerOfAddedMetric(listener, metric, name); } } - private void notifyListenerOfAddedMetric(MetricRegistryListener listener, Metric metric, MetricName name) { + private void notifyListenerOfAddedMetric(Listener listener, Metric metric, MetricName name) { if (metric instanceof Gauge) { listener.onGaugeAdded(name, (Gauge) metric); } else if (metric instanceof CountMetric) { @@ -419,12 +427,12 @@ public class MetricRegistry implements MetricSet { } private void onMetricRemoved(MetricName name, Metric metric) { - for (MetricRegistryListener listener : listeners) { + for (Listener listener : listeners) { notifyListenerOfRemovedMetric(name, metric, listener); } } - private void notifyListenerOfRemovedMetric(MetricName name, Metric metric, MetricRegistryListener listener) { + private void notifyListenerOfRemovedMetric(MetricName name, Metric metric, Listener listener) { if (metric instanceof Gauge) { listener.onGaugeRemoved(name); } else if (metric instanceof CountMetric) { @@ -456,6 +464,132 @@ public class MetricRegistry implements MetricSet { return Collections.unmodifiableMap(metrics); } + + /** + * Listeners for events from the registry. Listeners must be thread-safe. + */ + public interface Listener { + /** + * Called when a {@link Gauge} is added to the registry. + * + * @param name the gauge's name + * @param gauge the gauge + */ + void onGaugeAdded(MetricName name, Gauge gauge); + + /** + * Called when a {@link Gauge} is removed from the registry. + * + * @param name the gauge's name + */ + void onGaugeRemoved(MetricName name); + + /** + * Called when a {@link CountMetric} is added to the registry. + * + * @param name the counter's name + * @param counter the counter + */ + void onCounterAdded(MetricName name, CountMetric counter); + + /** + * Called when a {@link CountMetric} is removed from the registry. + * + * @param name the counter's name + */ + void onCounterRemoved(MetricName name); + + /** + * Called when a {@link Histogram} is added to the registry. + * + * @param name the histogram's name + * @param histogram the histogram + */ + void onHistogramAdded(MetricName name, Histogram histogram); + + /** + * Called when a {@link Histogram} is removed from the registry. + * + * @param name the histogram's name + */ + void onHistogramRemoved(MetricName name); + + /** + * Called when a {@link Meter} is added to the registry. + * + * @param name the meter's name + * @param meter the meter + */ + void onMeterAdded(MetricName name, Meter meter); + + /** + * Called when a {@link Meter} is removed from the registry. + * + * @param name the meter's name + */ + void onMeterRemoved(MetricName name); + + /** + * Called when a {@link Sampler} is added to the registry. + * + * @param name the sampler's name + * @param sampler the sampler + */ + void onTimerAdded(MetricName name, Sampler sampler); + + /** + * Called when a {@link Sampler} is removed from the registry. + * + * @param name the timer's name + */ + void onTimerRemoved(MetricName name); + } + + /** + * A no-op implementation of {@link Listener}. + */ + abstract class Base implements Listener { + @Override + public void onGaugeAdded(MetricName name, Gauge gauge) { + } + + @Override + public void onGaugeRemoved(MetricName name) { + } + + @Override + public void onCounterAdded(MetricName name, CountMetric counter) { + } + + @Override + public void onCounterRemoved(MetricName name) { + } + + @Override + public void onHistogramAdded(MetricName name, Histogram histogram) { + } + + @Override + public void onHistogramRemoved(MetricName name) { + } + + @Override + public void onMeterAdded(MetricName name, Meter meter) { + } + + @Override + public void onMeterRemoved(MetricName name) { + } + + @Override + public void onTimerAdded(MetricName name, Sampler sampler) { + } + + @Override + public void onTimerRemoved(MetricName name) { + } + } + /** * A quick and easy way of capturing the notion of default metrics. */ diff --git a/src/main/java/org/xbib/metrics/Sampler.java b/metrics-common/src/main/java/org/xbib/metrics/common/Sampler.java similarity index 94% rename from src/main/java/org/xbib/metrics/Sampler.java rename to metrics-common/src/main/java/org/xbib/metrics/common/Sampler.java index f4680db..3562ecd 100644 --- a/src/main/java/org/xbib/metrics/Sampler.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/Sampler.java @@ -1,4 +1,10 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Clock; +import org.xbib.metrics.api.Metered; +import org.xbib.metrics.api.Reservoir; +import org.xbib.metrics.api.Sampling; +import org.xbib.metrics.api.Snapshot; import java.io.Closeable; import java.util.concurrent.Callable; @@ -12,7 +18,9 @@ import java.util.concurrent.TimeUnit; public class Sampler implements Metered, Sampling { private final Meter meter; + private final Histogram histogram; + private final Clock clock; /** @@ -31,7 +39,7 @@ public class Sampler implements Metered, Sampling { * @param executorService the executor service */ public Sampler(Reservoir reservoir, ScheduledExecutorService executorService) { - this(reservoir, Clock.defaultClock(), executorService); + this(reservoir, UserTimeClock.defaultClock(), executorService); } /** diff --git a/src/main/java/org/xbib/metrics/UserTimeClock.java b/metrics-common/src/main/java/org/xbib/metrics/common/UserTimeClock.java similarity index 55% rename from src/main/java/org/xbib/metrics/UserTimeClock.java rename to metrics-common/src/main/java/org/xbib/metrics/common/UserTimeClock.java index 3b229d4..5ce51c0 100644 --- a/src/main/java/org/xbib/metrics/UserTimeClock.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/UserTimeClock.java @@ -1,10 +1,23 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Clock; /** * A clock implementation which returns the current time in epoch nanoseconds. */ class UserTimeClock implements Clock { + /** + * The default clock to use. + * + * @return the default {@link Clock} instance + * @see UserTimeClock + */ + static Clock defaultClock() { + return UserTimeClock.DEFAULT; + } + + static final Clock DEFAULT = new UserTimeClock(); @Override @@ -17,4 +30,4 @@ class UserTimeClock implements Clock { return System.currentTimeMillis(); } -} \ No newline at end of file +} diff --git a/src/main/java/org/xbib/metrics/WeightedSnapshot.java b/metrics-common/src/main/java/org/xbib/metrics/common/WeightedSnapshot.java similarity index 96% rename from src/main/java/org/xbib/metrics/WeightedSnapshot.java rename to metrics-common/src/main/java/org/xbib/metrics/common/WeightedSnapshot.java index 493a291..9cfd1d5 100644 --- a/src/main/java/org/xbib/metrics/WeightedSnapshot.java +++ b/metrics-common/src/main/java/org/xbib/metrics/common/WeightedSnapshot.java @@ -1,4 +1,6 @@ -package org.xbib.metrics; +package org.xbib.metrics.common; + +import org.xbib.metrics.api.Snapshot; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -6,6 +8,7 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; /** * A statistical snapshot of a {@link WeightedSnapshot}. @@ -13,7 +16,9 @@ import java.util.Collection; public class WeightedSnapshot implements Snapshot { private final long[] values; + private final double[] normWeights; + private final double[] quantiles; /** @@ -24,15 +29,7 @@ public class WeightedSnapshot implements Snapshot { public WeightedSnapshot(Collection values) { final WeightedSample[] copy = values.toArray(new WeightedSample[]{}); - Arrays.sort(copy, (o1, o2) -> { - if (o1.value > o2.value) { - return 1; - } - if (o1.value < o2.value) { - return -1; - } - return 0; - }); + Arrays.sort(copy, Comparator.comparingLong(o -> o.value)); this.values = new long[copy.length]; this.normWeights = new double[copy.length]; diff --git a/metrics-common/src/main/java/org/xbib/metrics/common/package-info.java b/metrics-common/src/main/java/org/xbib/metrics/common/package-info.java new file mode 100644 index 0000000..0915c7f --- /dev/null +++ b/metrics-common/src/main/java/org/xbib/metrics/common/package-info.java @@ -0,0 +1,4 @@ +/** + * Implementation classes for metrics. + */ +package org.xbib.metrics.common; diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..5a42197 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +include 'metrics-api' +include 'metrics-common' \ No newline at end of file diff --git a/src/main/java/org/xbib/metrics/Clock.java b/src/main/java/org/xbib/metrics/Clock.java deleted file mode 100644 index 8562ac7..0000000 --- a/src/main/java/org/xbib/metrics/Clock.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.xbib.metrics; - -/** - * An interface for how time passes. It is passed to {@link Sampler} to track timing. - */ -public interface Clock { - - /** - * The default clock to use. - * - * @return the default {@link Clock} instance - * @see UserTimeClock - */ - static Clock defaultClock() { - return UserTimeClock.DEFAULT; - } - - /** - * Returns the current time tick. - * - * @return time tick in nanoseconds - */ - long getTick(); - - /** - * Returns the current time in milliseconds. - * - * @return time in milliseconds - */ - long getTime(); - -} diff --git a/src/main/java/org/xbib/metrics/MetricRegistryListener.java b/src/main/java/org/xbib/metrics/MetricRegistryListener.java deleted file mode 100644 index 10de733..0000000 --- a/src/main/java/org/xbib/metrics/MetricRegistryListener.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.xbib.metrics; - -import java.util.EventListener; - -/** - * Listeners for events from the registry. Listeners must be thread-safe. - */ -public interface MetricRegistryListener extends EventListener { - /** - * Called when a {@link Gauge} is added to the registry. - * - * @param name the gauge's name - * @param gauge the gauge - */ - void onGaugeAdded(MetricName name, Gauge gauge); - - /** - * Called when a {@link Gauge} is removed from the registry. - * - * @param name the gauge's name - */ - void onGaugeRemoved(MetricName name); - - /** - * Called when a {@link CountMetric} is added to the registry. - * - * @param name the counter's name - * @param counter the counter - */ - void onCounterAdded(MetricName name, CountMetric counter); - - /** - * Called when a {@link CountMetric} is removed from the registry. - * - * @param name the counter's name - */ - void onCounterRemoved(MetricName name); - - /** - * Called when a {@link Histogram} is added to the registry. - * - * @param name the histogram's name - * @param histogram the histogram - */ - void onHistogramAdded(MetricName name, Histogram histogram); - - /** - * Called when a {@link Histogram} is removed from the registry. - * - * @param name the histogram's name - */ - void onHistogramRemoved(MetricName name); - - /** - * Called when a {@link Meter} is added to the registry. - * - * @param name the meter's name - * @param meter the meter - */ - void onMeterAdded(MetricName name, Meter meter); - - /** - * Called when a {@link Meter} is removed from the registry. - * - * @param name the meter's name - */ - void onMeterRemoved(MetricName name); - - /** - * Called when a {@link Sampler} is added to the registry. - * - * @param name the sampler's name - * @param sampler the sampler - */ - void onTimerAdded(MetricName name, Sampler sampler); - - /** - * Called when a {@link Sampler} is removed from the registry. - * - * @param name the timer's name - */ - void onTimerRemoved(MetricName name); - - /** - * A no-op implementation of {@link MetricRegistryListener}. - */ - abstract class Base implements MetricRegistryListener { - @Override - public void onGaugeAdded(MetricName name, Gauge gauge) { - } - - @Override - public void onGaugeRemoved(MetricName name) { - } - - @Override - public void onCounterAdded(MetricName name, CountMetric counter) { - } - - @Override - public void onCounterRemoved(MetricName name) { - } - - @Override - public void onHistogramAdded(MetricName name, Histogram histogram) { - } - - @Override - public void onHistogramRemoved(MetricName name) { - } - - @Override - public void onMeterAdded(MetricName name, Meter meter) { - } - - @Override - public void onMeterRemoved(MetricName name) { - } - - @Override - public void onTimerAdded(MetricName name, Sampler sampler) { - } - - @Override - public void onTimerRemoved(MetricName name) { - } - } -} diff --git a/src/main/java/org/xbib/metrics/package-info.java b/src/main/java/org/xbib/metrics/package-info.java deleted file mode 100644 index 0023339..0000000 --- a/src/main/java/org/xbib/metrics/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes for metrics. - */ -package org.xbib.metrics;