Skip to content

Commit 7a06b65

Browse files
adinauerclaude
andcommitted
feat(micrometer): [Micrometer 1] Add active meters
Add a framework-neutral Micrometer registry that forwards counters, timers, and distribution summaries through the existing Sentry metrics API while preserving local meter behavior. Register the new integration artifact and cover naming, units, filtering, scope resolution, and composite registry coexistence. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 2b6abbb commit 7a06b65

17 files changed

Lines changed: 855 additions & 0 deletions

File tree

‎.craft.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ targets:
5555
maven:io.sentry:sentry-opentelemetry-otlp:
5656
maven:io.sentry:sentry-opentelemetry-otlp-spring:
5757
maven:io.sentry:sentry-kafka:
58+
# TODO: Add after first release of the artifact.
59+
# maven:io.sentry:sentry-micrometer:
5860
maven:io.sentry:sentry-apollo:
5961
maven:io.sentry:sentry-jdbc:
6062
maven:io.sentry:sentry-jcache:

‎.github/ISSUE_TEMPLATE/bug_report_java.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ body:
3636
- sentry-quartz
3737
- sentry-openfeign
3838
- sentry-openfeature
39+
- sentry-micrometer
3940
- sentry-launchdarkly-server
4041
- sentry-apache-http-client-5
4142
- sentry-okhttp

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Sentry SDK for Java and Android
3535
| sentry-jul | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-jul?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-jul) |
3636
| sentry-jdbc | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-jdbc?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-jdbc) |
3737
| sentry-kafka | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-kafka?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-kafka) |
38+
| sentry-micrometer | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-micrometer?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-micrometer) |
3839
| sentry-apollo | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-apollo?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-apollo) | 21 |
3940
| sentry-apollo-3 | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-apollo-3?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-apollo-3) | 21 |
4041
| sentry-apollo-4 | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-apollo-4?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-apollo-4) | 21 |

‎buildSrc/src/main/java/Config.kt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ object Config {
7676
val SENTRY_QUARTZ_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.quartz"
7777
val SENTRY_JDBC_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.jdbc"
7878
val SENTRY_KAFKA_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.kafka"
79+
val SENTRY_MICROMETER_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.micrometer"
7980
val SENTRY_OPENFEATURE_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.openfeature"
8081
val SENTRY_LAUNCHDARKLY_SERVER_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.launchdarkly-server"
8182
val SENTRY_LAUNCHDARKLY_ANDROID_SDK_NAME = "$SENTRY_ANDROID_SDK_NAME.launchdarkly"

‎gradle/libs.versions.toml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ksp = "2.3.9"
2121
ktorClient = "3.0.0"
2222
logback = "1.2.9"
2323
log4j2 = "2.20.0"
24+
micrometer = "1.9.17"
2425
nopen = "1.0.1"
2526
# see https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compatibility-and-versioning.html#kotlin-compatibility
2627
# see https://developer.android.com/jetpack/androidx/releases/compose-kotlin
@@ -144,6 +145,7 @@ log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "lo
144145
leakcanary = { module = "com.squareup.leakcanary:leakcanary-android", version = "2.14" }
145146
lottie-compose = { module = "com.airbnb.android:lottie-compose", version = "6.7.1" }
146147
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
148+
micrometer-core = { module = "io.micrometer:micrometer-core", version.ref = "micrometer" }
147149
nopen-annotations = { module = "com.jakewharton.nopen:nopen-annotations", version.ref = "nopen" }
148150
nopen-checker = { module = "com.jakewharton.nopen:nopen-checker", version.ref = "nopen" }
149151
nullaway = { module = "com.uber.nullaway:nullaway", version = "0.9.5" }

‎sentry-micrometer/README.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# sentry-micrometer
2+
3+
This module forwards Micrometer metrics to Sentry.
4+
5+
## Install
6+
7+
Add the Sentry Micrometer module and Micrometer Core:
8+
9+
```kotlin
10+
dependencies {
11+
implementation("io.sentry:sentry-micrometer:<version>")
12+
implementation("io.micrometer:micrometer-core:<version>")
13+
}
14+
```
15+
16+
Create a `SentryMeterRegistry` and add it to Micrometer:
17+
18+
```java
19+
SentryMeterRegistry sentryRegistry = new SentryMeterRegistry();
20+
Metrics.addRegistry(sentryRegistry);
21+
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public final class io/sentry/micrometer/BuildConfig {
2+
public static final field SENTRY_MICROMETER_SDK_NAME Ljava/lang/String;
3+
public static final field VERSION_NAME Ljava/lang/String;
4+
}
5+
6+
public final class io/sentry/micrometer/SentryMeterRegistry : io/micrometer/core/instrument/MeterRegistry {
7+
public fun <init> ()V
8+
}
9+

‎sentry-micrometer/build.gradle.kts‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import net.ltgt.gradle.errorprone.errorprone
2+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
3+
4+
plugins {
5+
`java-library`
6+
id("io.sentry.javadoc")
7+
alias(libs.plugins.kotlin.jvm)
8+
alias(libs.plugins.errorprone)
9+
alias(libs.plugins.gradle.versions)
10+
alias(libs.plugins.buildconfig)
11+
id("io.sentry.animalsniffer")
12+
}
13+
14+
tasks.withType<KotlinCompile>().configureEach {
15+
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
16+
}
17+
18+
dependencies {
19+
api(projects.sentry)
20+
compileOnly(libs.micrometer.core)
21+
compileOnly(libs.jetbrains.annotations)
22+
compileOnly(libs.nopen.annotations)
23+
24+
errorprone(libs.errorprone.core)
25+
errorprone(libs.nopen.checker)
26+
errorprone(libs.nullaway)
27+
28+
// tests
29+
testImplementation(projects.sentryTestSupport)
30+
testImplementation(kotlin(Config.kotlinStdLib))
31+
testImplementation(libs.kotlin.test.junit)
32+
testImplementation(libs.google.truth)
33+
testImplementation(libs.mockito.kotlin)
34+
testImplementation(libs.micrometer.core)
35+
}
36+
37+
tasks.withType<JavaCompile>().configureEach {
38+
options.errorprone {
39+
check("NullAway", net.ltgt.gradle.errorprone.CheckSeverity.ERROR)
40+
option("NullAway:AnnotatedPackages", "io.sentry")
41+
}
42+
}
43+
44+
buildConfig {
45+
useJavaOutput()
46+
packageName("io.sentry.micrometer")
47+
buildConfigField(
48+
"String",
49+
"SENTRY_MICROMETER_SDK_NAME",
50+
"\"${Config.Sentry.SENTRY_MICROMETER_SDK_NAME}\"",
51+
)
52+
buildConfigField("String", "VERSION_NAME", "\"${project.version}\"")
53+
}
54+
55+
tasks.jar {
56+
manifest {
57+
attributes(
58+
"Sentry-Version-Name" to project.version,
59+
"Sentry-SDK-Name" to Config.Sentry.SENTRY_MICROMETER_SDK_NAME,
60+
"Sentry-SDK-Package-Name" to "maven:io.sentry:sentry-micrometer",
61+
"Implementation-Vendor" to "Sentry",
62+
"Implementation-Title" to project.name,
63+
"Implementation-Version" to project.version,
64+
)
65+
}
66+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.sentry.micrometer;
2+
3+
import io.micrometer.core.instrument.Meter;
4+
import io.micrometer.core.instrument.cumulative.CumulativeCounter;
5+
import org.jetbrains.annotations.NotNull;
6+
7+
final class SentryCounter extends CumulativeCounter {
8+
private final @NotNull SentryMeterRegistry registry;
9+
private final @NotNull SentryMetricInfo metricInfo;
10+
11+
SentryCounter(
12+
final @NotNull Meter.Id id,
13+
final @NotNull SentryMeterRegistry registry,
14+
final @NotNull SentryMetricInfo metricInfo) {
15+
super(id);
16+
this.registry = registry;
17+
this.metricInfo = metricInfo;
18+
}
19+
20+
@Override
21+
public void increment(final double amount) {
22+
super.increment(amount);
23+
if (amount > 0.0 && Double.isFinite(amount)) {
24+
registry.captureCounter(metricInfo, amount);
25+
}
26+
}
27+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.sentry.micrometer;
2+
3+
import io.micrometer.core.instrument.Clock;
4+
import io.micrometer.core.instrument.Meter;
5+
import io.micrometer.core.instrument.cumulative.CumulativeDistributionSummary;
6+
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
7+
import org.jetbrains.annotations.NotNull;
8+
9+
final class SentryDistributionSummary extends CumulativeDistributionSummary {
10+
private final @NotNull SentryMeterRegistry registry;
11+
private final @NotNull SentryMetricInfo metricInfo;
12+
13+
SentryDistributionSummary(
14+
final @NotNull Meter.Id id,
15+
final @NotNull Clock clock,
16+
final @NotNull DistributionStatisticConfig distributionStatisticConfig,
17+
final double scale,
18+
final @NotNull SentryMeterRegistry registry,
19+
final @NotNull SentryMetricInfo metricInfo) {
20+
super(id, clock, distributionStatisticConfig, scale, false);
21+
this.registry = registry;
22+
this.metricInfo = metricInfo;
23+
}
24+
25+
@Override
26+
protected void recordNonNegative(final double amount) {
27+
super.recordNonNegative(amount);
28+
if (Double.isFinite(amount)) {
29+
registry.captureDistribution(metricInfo, amount);
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)