From 1524512f949e765417ba31459b60ec257629c00f Mon Sep 17 00:00:00 2001 From: ardetrick Date: Sun, 29 Oct 2023 14:21:21 -0500 Subject: [PATCH 1/3] Add Git commit and build info metrics --- .gitignore | 1 + .../core/instrument/binder/MeterBinder.java | 2 + .../instrument/binder/build/BuildInfo.java | 112 ++++++++++++++++++ .../binder/build/BuildInfoMetrics.java | 50 ++++++++ .../instrument/binder/build/package-info.java | 20 ++++ .../instrument/binder/git/GitCommitInfo.java | 101 ++++++++++++++++ .../binder/git/GitCommitInfoMetrics.java | 49 ++++++++ .../instrument/binder/git/package-info.java | 20 ++++ .../git/GitCommitInfoMetricsMetricsTest.java | 108 +++++++++++++++++ 9 files changed, 463 insertions(+) create mode 100644 micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfo.java create mode 100644 micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java create mode 100644 micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/package-info.java create mode 100644 micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/GitCommitInfo.java create mode 100644 micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/GitCommitInfoMetrics.java create mode 100644 micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/package-info.java create mode 100644 micrometer-core/src/test/java/io/micrometer/core/instrument/binder/git/GitCommitInfoMetricsMetricsTest.java diff --git a/.gitignore b/.gitignore index 2c109640c6..8738d8fdd9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build/ +!micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build .gradle/ out/ diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/MeterBinder.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/MeterBinder.java index 667570e996..b8fcc6517a 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/MeterBinder.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/MeterBinder.java @@ -27,6 +27,8 @@ */ public interface MeterBinder { + String DEFAULT_TAG_VALUE = "unknown"; + void bindTo(@NonNull MeterRegistry registry); } diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfo.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfo.java new file mode 100644 index 0000000000..443e2ba3b9 --- /dev/null +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfo.java @@ -0,0 +1,112 @@ +/* + * Copyright 2023 VMware, Inc. + * + * 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. + */ + +package io.micrometer.core.instrument.binder.build; + +import java.time.Instant; +import java.util.Optional; + +public class BuildInfo { + + private final String group; + + private final String artifact; + + private final String name; + + private final String version; + + private final Instant timestamp; + + private BuildInfo(String group, String artifact, String name, String version, Instant timestamp) { + this.group = group; + this.artifact = artifact; + this.name = name; + this.version = version; + this.timestamp = timestamp; + } + + public static BuildInfo.Builder builder() { + return new BuildInfo.Builder(); + } + + public Optional getGroup() { + return Optional.ofNullable(group); + } + + public Optional getArtifact() { + return Optional.ofNullable(artifact); + } + + public Optional getName() { + return Optional.ofNullable(name); + } + + public Optional getVersion() { + return Optional.ofNullable(version); + } + + public Optional getTimestamp() { + return Optional.ofNullable(timestamp); + } + + public static class Builder { + + private String group; + + private String artifact; + + private String name; + + private String version; + + private Instant timestamp; + + private Builder() { + } + + public BuildInfo build() { + return new BuildInfo(group, artifact, name, version, timestamp); + } + + public Builder group(String group) { + this.group = group; + return this; + } + + public Builder artifact(String artifact) { + this.artifact = artifact; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder version(String version) { + this.version = version; + return this; + } + + public Builder timestamp(Instant timestamp) { + this.timestamp = timestamp; + return this; + } + + } + +} diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java new file mode 100644 index 0000000000..1516ed7f72 --- /dev/null +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java @@ -0,0 +1,50 @@ +/* + * Copyright 2023 VMware, Inc. + * + * 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. + */ + +package io.micrometer.core.instrument.binder.build; + +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.MeterBinder; + +import java.time.Instant; + +import static java.util.Objects.requireNonNull; + +public class BuildInfoMetrics implements MeterBinder { + + private final BuildInfo buildInfo; + + public BuildInfoMetrics(BuildInfo buildInfo) { + requireNonNull(buildInfo, "buildInfo"); + this.buildInfo = buildInfo; + } + + @Override + public void bindTo(MeterRegistry registry) { + requireNonNull(registry, "registry"); + Gauge.builder("build.info", () -> 1L) + .description("Build information") + .strongReference(true) + .tag("group", buildInfo.getGroup().orElse(DEFAULT_TAG_VALUE)) + .tag("artifact", buildInfo.getArtifact().orElse(DEFAULT_TAG_VALUE)) + .tag("name", buildInfo.getName().orElse(DEFAULT_TAG_VALUE)) + .tag("version", buildInfo.getVersion().orElse(DEFAULT_TAG_VALUE)) + .tag("timestamp", buildInfo.getTimestamp().map(Instant::toString).orElse(DEFAULT_TAG_VALUE)) + .register(registry); + } + +} diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/package-info.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/package-info.java new file mode 100644 index 0000000000..c56def0d73 --- /dev/null +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2023 VMware, Inc. + * + * 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. + */ + +/** + * Meter binders for build info. + */ +package io.micrometer.core.instrument.binder.build; diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/GitCommitInfo.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/GitCommitInfo.java new file mode 100644 index 0000000000..43f98e33a5 --- /dev/null +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/GitCommitInfo.java @@ -0,0 +1,101 @@ +/* + * Copyright 2023 VMware, Inc. + * + * 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. + */ + +package io.micrometer.core.instrument.binder.git; + +import java.time.Instant; +import java.util.Optional; + +/** + * Information from a Git commit. + */ +public class GitCommitInfo { + + private final String branch; + + private final String commitId; + + private final String commitIdShort; + + private final Instant commitTime; + + private GitCommitInfo(String branch, String commitId, String commitIdShort, Instant commitTime) { + this.branch = branch; + this.commitId = commitId; + this.commitIdShort = commitIdShort; + this.commitTime = commitTime; + } + + public static GitCommitInfo.Builder builder() { + return new GitCommitInfo.Builder(); + } + + public Optional getBranch() { + return Optional.ofNullable(branch); + } + + public Optional getCommitId() { + return Optional.ofNullable(commitId); + } + + public Optional getShortCommitId() { + return Optional.ofNullable(commitIdShort); + } + + public Optional getCommitTime() { + return Optional.ofNullable(commitTime); + } + + public static class Builder { + + private String branch; + + private String commitId; + + private String commitIdShort; + + private Instant commitTime; + + private Builder() { + } + + public GitCommitInfo build() { + return new GitCommitInfo(branch, commitId, commitIdShort, commitTime); + } + + public Builder branch(String branch) { + this.branch = branch; + return this; + } + + public Builder commitId(String commitId) { + this.commitId = commitId; + return this; + } + + public Builder commitIdShort(String commitIdShort) { + this.commitIdShort = commitIdShort; + return this; + } + + public Builder commitTime(Instant commitTime) { + this.commitTime = commitTime; + return this; + } + + } + +} diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/GitCommitInfoMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/GitCommitInfoMetrics.java new file mode 100644 index 0000000000..a41d0059f2 --- /dev/null +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/GitCommitInfoMetrics.java @@ -0,0 +1,49 @@ +/* + * Copyright 2023 VMware, Inc. + * + * 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. + */ + +package io.micrometer.core.instrument.binder.git; + +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.MeterBinder; + +import java.time.Instant; + +import static java.util.Objects.requireNonNull; + +public class GitCommitInfoMetrics implements MeterBinder { + + private final GitCommitInfo gitCommitInfo; + + public GitCommitInfoMetrics(GitCommitInfo gitCommitInfo) { + requireNonNull(gitCommitInfo, "gitCommitInfo"); + this.gitCommitInfo = gitCommitInfo; + } + + @Override + public void bindTo(MeterRegistry registry) { + requireNonNull(registry, "registry"); + Gauge.builder("git.commit.info", () -> 1L) + .description("Git commit information") + .strongReference(true) + .tag("branch", gitCommitInfo.getBranch().orElse(DEFAULT_TAG_VALUE)) + .tag("commit.id", gitCommitInfo.getCommitId().orElse(DEFAULT_TAG_VALUE)) + .tag("commit.id.short", gitCommitInfo.getShortCommitId().orElse(DEFAULT_TAG_VALUE)) + .tag("commit.timestamp", gitCommitInfo.getCommitTime().map(Instant::toString).orElse(DEFAULT_TAG_VALUE)) + .register(registry); + } + +} diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/package-info.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/package-info.java new file mode 100644 index 0000000000..a0fa202c94 --- /dev/null +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/git/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2023 VMware, Inc. + * + * 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. + */ + +/** + * Meter binders for git info. + */ +package io.micrometer.core.instrument.binder.git; diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/git/GitCommitInfoMetricsMetricsTest.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/git/GitCommitInfoMetricsMetricsTest.java new file mode 100644 index 0000000000..c6634117ee --- /dev/null +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/git/GitCommitInfoMetricsMetricsTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2023 VMware, Inc. + * + * 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. + */ + +package io.micrometer.core.instrument.binder.git; + +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.search.Search; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.util.Collection; + +import static java.time.ZoneOffset.UTC; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class GitCommitInfoMetricsTest { + + @Test + void shouldTagAllGitCommitInfoWithValuesWhenPresent() { + MeterRegistry registry = new SimpleMeterRegistry(); + + GitCommitInfo gitCommitInfo = GitCommitInfo.builder() + .branch("my-branch") + .commitId("1234567890123456789012345678901234567890") + .commitIdShort("12345678") + .commitTime(LocalDateTime.of(2023, 1, 2, 3, 4, 5).toInstant(UTC)) + .build(); + + GitCommitInfoMetrics gitCommitInfoMetrics = new GitCommitInfoMetrics(gitCommitInfo); + + gitCommitInfoMetrics.bindTo(registry); + + Collection gauges = Search.in(registry).name("git.commit.info").gauges(); + + assertThat(gauges).hasSize(1); + + Gauge gitCommitInfoGauge = gauges.iterator().next(); + + assertThat(gitCommitInfoGauge.value()).isEqualTo(1); + + Meter.Id id = gitCommitInfoGauge.getId(); + + assertThat(id.getName()).isEqualTo("git.commit.info"); + assertThat(id.getTags()).containsExactlyInAnyOrder(Tag.of("branch", "my-branch"), + Tag.of("commit.id", "1234567890123456789012345678901234567890"), Tag.of("commit.id.short", "12345678"), + Tag.of("commit.timestamp", "2023-01-02T03:04:05Z")); + } + + @Test + void shouldTagAllGitCommitInfoWithUnknownWhenNotPresent() { + MeterRegistry registry = new SimpleMeterRegistry(); + + GitCommitInfo gitCommitInfo = GitCommitInfo.builder().build(); + + GitCommitInfoMetrics gitCommitInfoMetrics = new GitCommitInfoMetrics(gitCommitInfo); + + gitCommitInfoMetrics.bindTo(registry); + + Collection gauges = Search.in(registry).name("git.commit.info").gauges(); + + assertThat(gauges).hasSize(1); + + Gauge gitCommitInfoGauge = gauges.iterator().next(); + + assertThat(gitCommitInfoGauge.value()).isEqualTo(1); + + Meter.Id id = gitCommitInfoGauge.getId(); + + assertThat(id.getName()).isEqualTo("git.commit.info"); + assertThat(id.getTags()).containsExactlyInAnyOrder(Tag.of("branch", "unknown"), Tag.of("commit.id", "unknown"), + Tag.of("commit.id.short", "unknown"), Tag.of("commit.timestamp", "unknown")); + } + + @Test + void throwsWhenGitCommitInfoIsNull() { + assertThatThrownBy(() -> new GitCommitInfoMetrics(null)).isInstanceOf(NullPointerException.class) + .hasMessageContaining("gitCommitInfo"); + } + + @Test + void throwsWhenRegistryIsNull() { + GitCommitInfo gitCommitInfo = GitCommitInfo.builder().build(); + + GitCommitInfoMetrics gitCommitInfoMetrics = new GitCommitInfoMetrics(gitCommitInfo); + + assertThatThrownBy(() -> gitCommitInfoMetrics.bindTo(null)).isInstanceOf(NullPointerException.class) + .hasMessageContaining("registry"); + } + +} From c467a76710dc0cba22c59596b244737264ab9142 Mon Sep 17 00:00:00 2001 From: ardetrick Date: Mon, 6 Nov 2023 08:54:32 -0600 Subject: [PATCH 2/3] Add additional constructor to BuildInfoMetrics to support additional client provided tags. --- .gitignore | 2 +- .../binder/build/BuildInfoMetrics.java | 10 ++ .../binder/build/BuildInfoMetricsTest.java | 159 ++++++++++++++++++ 3 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 micrometer-core/src/test/java/io/micrometer/core/instrument/binder/build/BuildInfoMetricsTest.java diff --git a/.gitignore b/.gitignore index 8738d8fdd9..d437846758 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ build/ -!micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build +!micrometer-core/src/*/*/io/micrometer/core/instrument/binder/build .gradle/ out/ diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java index 1516ed7f72..6dc8e27159 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java @@ -18,19 +18,28 @@ import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; import java.time.Instant; +import static java.util.Collections.emptyList; import static java.util.Objects.requireNonNull; public class BuildInfoMetrics implements MeterBinder { private final BuildInfo buildInfo; + private final Iterable tags; public BuildInfoMetrics(BuildInfo buildInfo) { + this(buildInfo, emptyList()); + } + + public BuildInfoMetrics(BuildInfo buildInfo, Iterable tags) { requireNonNull(buildInfo, "buildInfo"); + requireNonNull(tags, "tags"); this.buildInfo = buildInfo; + this.tags = tags; } @Override @@ -44,6 +53,7 @@ public void bindTo(MeterRegistry registry) { .tag("name", buildInfo.getName().orElse(DEFAULT_TAG_VALUE)) .tag("version", buildInfo.getVersion().orElse(DEFAULT_TAG_VALUE)) .tag("timestamp", buildInfo.getTimestamp().map(Instant::toString).orElse(DEFAULT_TAG_VALUE)) + .tags(tags) .register(registry); } diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/build/BuildInfoMetricsTest.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/build/BuildInfoMetricsTest.java new file mode 100644 index 0000000000..eea86a3a6f --- /dev/null +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/build/BuildInfoMetricsTest.java @@ -0,0 +1,159 @@ +/* + * Copyright 2023 VMware, Inc. + * + * 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. + */ + +package io.micrometer.core.instrument.binder.build; + +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.search.Search; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.List; + +import static java.time.ZoneOffset.UTC; +import static java.util.Collections.emptyList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class BuildInfoMetricsTest { + + @Test + void shouldTagBuildInfoWithValuesWhenPresent() { + MeterRegistry registry = new SimpleMeterRegistry(); + + BuildInfo buildInfo = BuildInfo.builder() + .group("my-group") + .artifact("my-artifact") + .name("my-name") + .version("0.0.0-version") + .timestamp(LocalDateTime.of(2023, 1, 2, 3, 4, 5).toInstant(UTC)) + .build(); + + BuildInfoMetrics buildInfoMetrics = new BuildInfoMetrics(buildInfo); + + buildInfoMetrics.bindTo(registry); + + Collection gauges = Search.in(registry).name("build.info").gauges(); + + assertThat(gauges).hasSize(1); + + Gauge buildInfoGauge = gauges.iterator().next(); + + assertThat(buildInfoGauge.value()).isEqualTo(1); + + Meter.Id id = buildInfoGauge.getId(); + + assertThat(id.getName()).isEqualTo("build.info"); + assertThat(id.getTags()).containsExactlyInAnyOrder(Tag.of("group", "my-group"), + Tag.of("artifact", "my-artifact"), Tag.of("name", "my-name"), Tag.of("version", "0.0.0-version"), + Tag.of("timestamp", "2023-01-02T03:04:05Z")); + } + + @Test + void shouldTagBuildInfoWithValuesAndExtraTagsWhenPresent() { + MeterRegistry registry = new SimpleMeterRegistry(); + + BuildInfo buildInfo = BuildInfo.builder() + .group("my-group") + .artifact("my-artifact") + .name("my-name") + .version("0.0.0-version") + .timestamp(LocalDateTime.of(2023, 1, 2, 3, 4, 5).toInstant(UTC)) + .build(); + List tags = List.of(Tag.of("custom-tag", "custom-tag-value")); + + BuildInfoMetrics buildInfoMetrics = new BuildInfoMetrics(buildInfo, tags); + + buildInfoMetrics.bindTo(registry); + + Collection gauges = Search.in(registry).name("build.info").gauges(); + + assertThat(gauges).hasSize(1); + + Gauge buildInfoGauge = gauges.iterator().next(); + + assertThat(buildInfoGauge.value()).isEqualTo(1); + + Meter.Id id = buildInfoGauge.getId(); + + assertThat(id.getName()).isEqualTo("build.info"); + assertThat(id.getTags()).containsExactlyInAnyOrder(Tag.of("group", "my-group"), + Tag.of("artifact", "my-artifact"), Tag.of("name", "my-name"), Tag.of("version", "0.0.0-version"), + Tag.of("timestamp", "2023-01-02T03:04:05Z"), Tag.of("custom-tag", "custom-tag-value") + ); + } + + @Test + void shouldTagAllBuildInfoWithUnknownWhenNotPresent() { + MeterRegistry registry = new SimpleMeterRegistry(); + + BuildInfo buildInfo = BuildInfo.builder().build(); + + BuildInfoMetrics buildInfoMetrics = new BuildInfoMetrics(buildInfo); + + buildInfoMetrics.bindTo(registry); + + Collection gauges = Search.in(registry).name("build.info").gauges(); + + assertThat(gauges).hasSize(1); + + Gauge buildInfoGauge = gauges.iterator().next(); + + assertThat(buildInfoGauge.value()).isEqualTo(1); + + Meter.Id id = buildInfoGauge.getId(); + + assertThat(id.getName()).isEqualTo("build.info"); + assertThat(id.getTags()).containsExactlyInAnyOrder(Tag.of("group", "unknown"), Tag.of("artifact", "unknown"), + Tag.of("name", "unknown"), Tag.of("version", "unknown"), Tag.of("timestamp", "unknown")); + } + + @Test + void throwsWhenRegistryIsNull() { + BuildInfo buildInfo = BuildInfo.builder().build(); + + BuildInfoMetrics buildInfoMetrics = new BuildInfoMetrics(buildInfo); + + assertThatThrownBy(() -> buildInfoMetrics.bindTo(null)).isInstanceOf(NullPointerException.class) + .hasMessageContaining("registry"); + } + + @Test + void throwsWhenBuildInfoIsNullForBuildInfoConstructor() { + assertThatThrownBy(() -> new BuildInfoMetrics(null)).isInstanceOf(NullPointerException.class) + .hasMessageContaining("buildInfo"); + } + + @Test + void throwsWhenBuildInfoIsNullForBuildInfoAndTagsConstructor() { + assertThatThrownBy(() -> new BuildInfoMetrics(null, emptyList())).isInstanceOf(NullPointerException.class) + .hasMessageContaining("buildInfo"); + } + + @Test + void throwsWhenTagsIsNullForBuildInfoAndTagsConstructor() { + BuildInfo buildInfo = BuildInfo.builder().build(); + + assertThatThrownBy(() -> new BuildInfoMetrics(buildInfo, null)).isInstanceOf(NullPointerException.class) + .hasMessageContaining("tags"); + } + +} From 62e96bbc16659a462cb0d73cfa1a18b438fb9b3c Mon Sep 17 00:00:00 2001 From: ardetrick Date: Mon, 6 Nov 2023 08:57:59 -0600 Subject: [PATCH 3/3] Fix formatting. --- .../instrument/binder/build/BuildInfoMetrics.java | 1 + .../instrument/binder/build/BuildInfoMetricsTest.java | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java index 6dc8e27159..90495e5501 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/build/BuildInfoMetrics.java @@ -29,6 +29,7 @@ public class BuildInfoMetrics implements MeterBinder { private final BuildInfo buildInfo; + private final Iterable tags; public BuildInfoMetrics(BuildInfo buildInfo) { diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/build/BuildInfoMetricsTest.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/build/BuildInfoMetricsTest.java index eea86a3a6f..3624fd4f61 100644 --- a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/build/BuildInfoMetricsTest.java +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/build/BuildInfoMetricsTest.java @@ -63,8 +63,8 @@ void shouldTagBuildInfoWithValuesWhenPresent() { assertThat(id.getName()).isEqualTo("build.info"); assertThat(id.getTags()).containsExactlyInAnyOrder(Tag.of("group", "my-group"), - Tag.of("artifact", "my-artifact"), Tag.of("name", "my-name"), Tag.of("version", "0.0.0-version"), - Tag.of("timestamp", "2023-01-02T03:04:05Z")); + Tag.of("artifact", "my-artifact"), Tag.of("name", "my-name"), Tag.of("version", "0.0.0-version"), + Tag.of("timestamp", "2023-01-02T03:04:05Z")); } @Test @@ -96,9 +96,8 @@ void shouldTagBuildInfoWithValuesAndExtraTagsWhenPresent() { assertThat(id.getName()).isEqualTo("build.info"); assertThat(id.getTags()).containsExactlyInAnyOrder(Tag.of("group", "my-group"), - Tag.of("artifact", "my-artifact"), Tag.of("name", "my-name"), Tag.of("version", "0.0.0-version"), - Tag.of("timestamp", "2023-01-02T03:04:05Z"), Tag.of("custom-tag", "custom-tag-value") - ); + Tag.of("artifact", "my-artifact"), Tag.of("name", "my-name"), Tag.of("version", "0.0.0-version"), + Tag.of("timestamp", "2023-01-02T03:04:05Z"), Tag.of("custom-tag", "custom-tag-value")); } @Test @@ -123,7 +122,7 @@ void shouldTagAllBuildInfoWithUnknownWhenNotPresent() { assertThat(id.getName()).isEqualTo("build.info"); assertThat(id.getTags()).containsExactlyInAnyOrder(Tag.of("group", "unknown"), Tag.of("artifact", "unknown"), - Tag.of("name", "unknown"), Tag.of("version", "unknown"), Tag.of("timestamp", "unknown")); + Tag.of("name", "unknown"), Tag.of("version", "unknown"), Tag.of("timestamp", "unknown")); } @Test