Skip to content

Commit

Permalink
Merge branch 'release/0.0.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
ihostage committed Oct 1, 2018
2 parents 00fa172 + 648d06e commit ea0ddf6
Show file tree
Hide file tree
Showing 17 changed files with 403 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ hs_err_pid*
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
*.iml
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
Expand Down
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ cache:
- $HOME/.cache
- $HOME/.m2

before_install:
- cp .travis.settings.xml $HOME/.m2/settings.xml
- echo $GPG_SECRET_KEYS | base64 --decode | gpg2 --import

install: ./mvnw dependency:resolve dependency:resolve-plugins -B -V

script: ./mvnw verify -B -V

after_success:
- bash <(curl -s https://codecov.io/bash)

before_deploy:
- cp .travis.settings.xml $HOME/.m2/settings.xml
- echo $GPG_SECRET_KEYS | base64 --decode | gpg2 --import

deploy:
# Deploy releases
- provider: script
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[![codebeat](https://codebeat.co/badges/59cdf87f-c78d-4e68-a34f-6ba220485deb)](https://codebeat.co/projects/github-com-taymyr-lagom-metrics-java-develop)
[![Build Status](https://travis-ci.org/taymyr/lagom-metrics-java.svg?branch=develop)](https://travis-ci.org/taymyr/lagom-metrics-java)
[![Javadocs](https://www.javadoc.io/badge/org.taymyr.lagom/lagom-metrics-java.svg)](https://www.javadoc.io/doc/org.taymyr.lagom/lagom-metrics-java)
[![codecov](https://codecov.io/gh/taymyr/lagom-metrics-java/branch/develop/graph/badge.svg)](https://codecov.io/gh/taymyr/lagom-metrics-java)
[![Maven](https://img.shields.io/maven-central/v/org.taymyr.lagom/lagom-metrics-java.svg)](https://search.maven.org/search?q=a:lagom-metrics-java%20AND%20g:org.taymyr.lagom)

# [Dropwizard Metrics](https://metrics.dropwizard.io) for [Lagom](https://www.lagomframework.com)/[Play](https://playframework.com)

TODO
Expand Down
26 changes: 24 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.taymyr.lagom</groupId>
<artifactId>lagom-metrics-java</artifactId>
<version>0.0.1</version>
<version>0.0.2</version>
<packaging>jar</packaging>
<name>Taymyr: Lagom Metrics</name>
<description>Metrics for Lagom framework</description>
Expand All @@ -24,6 +24,7 @@
<id>taymyr</id>
<name>Taymyr Contributors</name>
<url>https://github.com/taymyr</url>
<email>contributors@taymyr.org</email>
</developer>
</developers>
<scm>
Expand All @@ -39,9 +40,11 @@
<kotlintest.version>3.1.10</kotlintest.version>
<scala.binary.version>2.12</scala.binary.version>
<dokka.version>0.9.17</dokka.version>
<kotlin.version>1.2.70</kotlin.version>
<kotlin.version>1.2.71</kotlin.version>
<lagom.version>[1.4.0,)</lagom.version>
<akka.version>2.5.17</akka.version>
<ktlint.version>0.28.0</ktlint.version>
<mockito.kotlin.version>2.0.0-RC2</mockito.kotlin.version>
<antrun.plugin.version>1.8</antrun.plugin.version>
<source.plugin.version>3.0.1</source.plugin.version>
<jar.plugin.version>3.1.0</jar.plugin.version>
Expand Down Expand Up @@ -109,6 +112,24 @@
<version>${kotlintest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.nhaarman.mockitokotlin2</groupId>
<artifactId>mockito-kotlin</artifactId>
<version>${mockito.kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.lightbend.lagom</groupId>
<artifactId>lagom-javadsl-testkit_${scala.binary.version}</artifactId>
<version>${lagom.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-stream-testkit_${scala.binary.version}</artifactId>
<version>${akka.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
Expand All @@ -121,6 +142,7 @@
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
<arg>-Xjvm-default=enable</arg>
</args>
</configuration>
<executions>
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/org/taymyr/lagom/metrics/Metrics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ class Metrics @Inject
constructor(conf: Config, val registry: MetricRegistry) {

private val config = conf.extract<MetricsConfig>("taymyr.lagom.metrics")
private val statusCircuitBreakers: ConcurrentHashMap<String, CircuitBreakerStatus> = ConcurrentHashMap()

@Inject
private fun registerCircuitBreaker(injector: Injector, mat: Materializer) {
if (config.enableCircuitBreaker) {
val metricsService = try { injector.getInstance(MetricsServiceImpl::class.java) } catch (e: Exception) { null }
val metricsService = try { injector.getInstance(MetricsServiceImpl::class.java) } catch (_: Throwable) { null }
metricsService ?: logger.error { "Only Lagom framework module support metrics for circuit breakers" }
metricsService?.let {
it.circuitBreakers().invoke().thenAccept { source ->
logger.info { "Metrics for circuit breakers enabled" }
val statusCircuitBreakers: ConcurrentHashMap<String, CircuitBreakerStatus> = ConcurrentHashMap()
source.runForeach({ statuses ->
statuses.forEach { status ->
statusCircuitBreakers.compute(status.id) { id, prev ->
Expand Down
10 changes: 7 additions & 3 deletions src/main/kotlin/org/taymyr/lagom/metrics/MetricsFilter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,18 @@ import javax.inject.Inject
class MetricsFilter @Inject
constructor(mat: Materializer, private val metrics: Metrics) : Filter(mat) {

private fun normalize(path: String) = path.replace('?', '.').replace(Regex("[:&]"), "_")
private fun normalize(path: String) = path
.replaceFirst("/", "")
.replace(Regex("[?/]"), ".")
.replace(Regex("<.*>"), "")
.replace(Regex("[:&$\\s]"), "_")

private fun routeTimerContext(requestHeader: RequestHeader, handlerDef: Optional<HandlerDef>): Timer.Context? =
if (handlerDef.isPresent) metrics.routeTimer(normalize(handlerDef.get().path()), requestHeader.method()).time()
if (handlerDef.isPresent) metrics.routeTimer("root", normalize(handlerDef.get().path()), requestHeader.method()).time()
else null

private fun routeMeter(requestHeader: RequestHeader, handlerDef: Optional<HandlerDef>, result: Result): Meter? =
if (handlerDef.isPresent) metrics.routeMeter(normalize(handlerDef.get().path()), requestHeader.method(), "${result.status()}")
if (handlerDef.isPresent) metrics.routeMeter("root", normalize(handlerDef.get().path()), requestHeader.method(), "${result.status()}")
else null

override fun apply(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,6 @@ import java.util.concurrent.ConcurrentHashMap

class CircuitBreakersMetricSetTest : StringSpec({

val shareDataCircuitBreaker = CircuitBreakerStatus.builder()
.totalSuccessCount(2)
.totalFailureCount(3)
.throughputOneMinute(0.2)
.failedThroughputOneMinute(0.3)
.latencyMicros(Latency.builder()
.mean(111.0)
.median(222.0)
.percentile98th(333.0)
.percentile99th(444.0)
.percentile999th(555.0)
.min(666)
.max(777)
.build()
)

val openCircuitBreaker = shareDataCircuitBreaker.id("open").state("open").build()

val closedCircuitBreaker = shareDataCircuitBreaker.id("closed").state("closed").build()

val halfOpenCircuitBreaker = shareDataCircuitBreaker.id("half-open").state("half-open").build()

val unknownStateCircuitBreaker = shareDataCircuitBreaker.id("unknown").state("unknown").build()

val statusCircuitBreakers: ConcurrentHashMap<String, CircuitBreakerStatus> = ConcurrentHashMap()
statusCircuitBreakers[openCircuitBreaker.id] = openCircuitBreaker
statusCircuitBreakers[closedCircuitBreaker.id] = closedCircuitBreaker
statusCircuitBreakers[halfOpenCircuitBreaker.id] = halfOpenCircuitBreaker
statusCircuitBreakers[unknownStateCircuitBreaker.id] = unknownStateCircuitBreaker

"Metrics for open circuit breaker should be correct" {
val cbMetricSet = CircuitBreakersMetricSet(openCircuitBreaker.id, statusCircuitBreakers)
cbMetricSet.metrics.values.forAll { it shouldBe beInstanceOf(Gauge::class) }
Expand Down Expand Up @@ -114,4 +84,39 @@ class CircuitBreakersMetricSetTest : StringSpec({
cbMetricSet.metrics.values.forAll { it shouldBe beInstanceOf(Gauge::class) }
cbMetricSet.metrics.values.forAll { (it as Gauge<*>).value shouldBe null }
}
})
}) {
companion object {
private val shareDataCircuitBreaker: CircuitBreakerStatus.Builder = CircuitBreakerStatus.builder()
.totalSuccessCount(2)
.totalFailureCount(3)
.throughputOneMinute(0.2)
.failedThroughputOneMinute(0.3)
.latencyMicros(Latency.builder()
.mean(111.0)
.median(222.0)
.percentile98th(333.0)
.percentile99th(444.0)
.percentile999th(555.0)
.min(666)
.max(777)
.build()
)

val openCircuitBreaker: CircuitBreakerStatus = shareDataCircuitBreaker.id("open").state("open").build()

val closedCircuitBreaker: CircuitBreakerStatus = shareDataCircuitBreaker.id("closed").state("closed").build()

val halfOpenCircuitBreaker: CircuitBreakerStatus = shareDataCircuitBreaker.id("half-open").state("half-open").build()

val unknownStateCircuitBreaker: CircuitBreakerStatus = shareDataCircuitBreaker.id("unknown").state("unknown").build()

val statusCircuitBreakers: ConcurrentHashMap<String, CircuitBreakerStatus> = ConcurrentHashMap()

init {
statusCircuitBreakers[openCircuitBreaker.id] = openCircuitBreaker
statusCircuitBreakers[closedCircuitBreaker.id] = closedCircuitBreaker
statusCircuitBreakers[halfOpenCircuitBreaker.id] = halfOpenCircuitBreaker
statusCircuitBreakers[unknownStateCircuitBreaker.id] = unknownStateCircuitBreaker
}
}
}
76 changes: 76 additions & 0 deletions src/test/kotlin/org/taymyr/lagom/metrics/ConfigTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.taymyr.lagom.metrics

import com.typesafe.config.ConfigFactory
import io.github.config4k.extract
import io.kotlintest.matchers.string.shouldBeEmpty
import io.kotlintest.shouldBe
import io.kotlintest.shouldNotBe
import io.kotlintest.shouldThrow
import io.kotlintest.specs.WordSpec
import org.taymyr.lagom.metrics.GraphiteReporterType.PICKLE
import org.taymyr.lagom.metrics.GraphiteReporterType.TCP
import java.util.concurrent.TimeUnit.MILLISECONDS
import java.util.concurrent.TimeUnit.SECONDS

/**
* @author Sergey Morgunov
*/
class ConfigTest : WordSpec({

"MetricsConfig" should {

"be correct for reference.conf" {
val config = ConfigFactory.defaultReference().extract<MetricsConfig>("taymyr.lagom.metrics")
config.enableJVM shouldBe false
config.enableCircuitBreaker shouldBe false
config.prefix.shouldBeEmpty()
config.graphiteReporter shouldBe null
}

"be able to enable JVM metrics" {
val config = ConfigFactory.load("default.conf").extract<MetricsConfig>("taymyr.lagom.metrics")
config.enableJVM shouldBe true
}

"be able to enable circuit breakers metrics" {
val config = ConfigFactory.load("default.conf").extract<MetricsConfig>("taymyr.lagom.metrics")
config.enableCircuitBreaker shouldBe true
}

"be throw exception for incorrect settings graphite reporter" {
shouldThrow<Exception> {
ConfigFactory.load("bad_graphite.conf").extract<MetricsConfig>("taymyr.lagom.metrics")
}
}

"be correct for graphite reporter with minimal settings" {
val config = ConfigFactory.load("min_graphite.conf").extract<MetricsConfig>("taymyr.lagom.metrics")
config.graphiteReporter shouldNotBe null
config.graphiteReporter?.let {
it.type shouldBe PICKLE
it.host shouldBe "localhost"
it.port shouldBe 1000
it.batchSize shouldBe null
it.durationUnit shouldBe MILLISECONDS
it.rateUnit shouldBe SECONDS
it.period shouldBe 10
it.periodUnit shouldBe SECONDS
}
}

"be correct for graphite reporter with full settings" {
val config = ConfigFactory.load("full_graphite.conf").extract<MetricsConfig>("taymyr.lagom.metrics")
config.graphiteReporter shouldNotBe null
config.graphiteReporter?.let {
it.type shouldBe TCP
it.host shouldBe "localhost"
it.port shouldBe 1000
it.batchSize shouldBe 1000
it.durationUnit shouldBe SECONDS
it.rateUnit shouldBe MILLISECONDS
it.period shouldBe 60
it.periodUnit shouldBe MILLISECONDS
}
}
}
})
Loading

0 comments on commit ea0ddf6

Please sign in to comment.