Skip to content

Commit b202d50

Browse files
Importing fix for Issue#877 in micrometer library
1 parent a2ab4c5 commit b202d50

File tree

6 files changed

+557
-334
lines changed

6 files changed

+557
-334
lines changed

build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,16 @@ subprojects { subProject ->
6666
compileOnly "com.netflix.spinnaker.kork:kork-core:${korkVersion}"
6767
compileOnly "com.netflix.spinnaker.kork:kork-web:${korkVersion}"
6868

69+
implementation("io.micrometer:micrometer-core:1.7.1")
6970
// Start Prometheus deps
70-
implementation("io.micrometer:micrometer-registry-prometheus:1.3.5") {
71+
implementation("io.micrometer:micrometer-registry-prometheus:1.7.1") {
7172
exclude group: 'io.micrometer', module: 'micrometer-core'
7273
}
73-
implementation group: 'io.prometheus', name: 'simpleclient_common', version: '0.7.0'// needs to match micrometer-registry-prometheus
74+
implementation group: 'io.prometheus', name: 'simpleclient_common', version: '0.11.0'// needs to match micrometer-registry-prometheus
7475
// End Prometheus deps
7576

7677
// Start New Relic Deps
77-
implementation('com.newrelic.telemetry:micrometer-registry-new-relic:0.5.0') {
78+
implementation('com.newrelic.telemetry:micrometer-registry-new-relic:0.8.0') {
7879
exclude group: 'io.micrometer', module: 'micrometer-core'
7980
exclude group: 'org.slf4j', module: 'slf4j-api'
8081
}

common/src/main/java/io/armory/plugin/observability/newrelic/NewRelicRegistryConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/**
2626
* New Relic config wrapper that sources its config from the Spring Context Plugin Configuration.
2727
*/
28-
public class NewRelicRegistryConfig implements io.micrometer.NewRelicRegistryConfig {
28+
public class NewRelicRegistryConfig implements com.newrelic.telemetry.micrometer.NewRelicRegistryConfig {
2929

3030
private final PluginMetricsNewRelicConfig newRelicConfig;
3131

common/src/main/java/io/armory/plugin/observability/newrelic/NewRelicRegistrySupplier.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
import io.armory.plugin.observability.model.PluginMetricsNewRelicConfig;
2121
import io.armory.plugin.observability.registry.RegistryConfigWrapper;
2222
import io.armory.plugin.observability.service.TagsService;
23-
import io.micrometer.newrelic.NewRelicRegistry;
23+
//import io.micrometer.newrelic.NewRelicRegistry;
24+
import com.newrelic.telemetry.micrometer.NewRelicRegistry;
2425
import java.util.List;
2526
import java.util.concurrent.Executors;
2627
import java.util.function.Supplier;
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/**
2+
* Copyright 2017 VMware, Inc.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.micrometer.prometheus;
17+
18+
import io.micrometer.core.instrument.Meter;
19+
import io.micrometer.core.instrument.Tag;
20+
import io.micrometer.core.instrument.config.NamingConvention;
21+
import io.prometheus.client.Collector;
22+
23+
import java.util.*;
24+
import java.util.concurrent.ConcurrentHashMap;
25+
import java.util.stream.Stream;
26+
27+
import static java.util.stream.Collectors.toList;
28+
29+
/**
30+
* {@link Collector} for Micrometer.
31+
*
32+
* @author Jon Schneider
33+
* @author Johnny Lim
34+
*/
35+
class MutatedMicrometerCollector extends Collector implements Collector.Describable {
36+
37+
static final class TagsHolder {
38+
final List<String> keys;
39+
final List<String> values;
40+
41+
private TagsHolder(List<String> keys, List<String> values) {
42+
this.keys = keys;
43+
this.values = values;
44+
}
45+
46+
static TagsHolder from(List<Tag> tags) {
47+
Objects.requireNonNull(tags, "tags");
48+
49+
List<String> keys = new ArrayList<>(tags.size());
50+
List<String> values = new ArrayList<>(tags.size());
51+
52+
for (Tag tag : tags) {
53+
keys.add(tag.getKey());
54+
values.add(tag.getValue());
55+
}
56+
57+
return new TagsHolder(
58+
Collections.unmodifiableList(keys),
59+
Collections.unmodifiableList(values)
60+
);
61+
}
62+
63+
public List<String> getKeys() {
64+
return keys;
65+
}
66+
67+
public List<String> getValues() {
68+
return values;
69+
}
70+
71+
@Override
72+
public boolean equals(Object o) {
73+
if (this == o) return true;
74+
if (o == null || getClass() != o.getClass()) return false;
75+
TagsHolder that = (TagsHolder) o;
76+
return keys.equals(that.keys) && values.equals(that.values);
77+
}
78+
79+
@Override
80+
public int hashCode() {
81+
return Objects.hash(keys, values);
82+
}
83+
}
84+
85+
private final Meter.Id id;
86+
private final Map<TagsHolder, Child> children = new ConcurrentHashMap<>();
87+
private final String conventionName;
88+
private final String help;
89+
90+
public MutatedMicrometerCollector(Meter.Id id, NamingConvention convention, PrometheusConfig config) {
91+
this.id = id;
92+
this.conventionName = id.getConventionName(convention);
93+
this.help = config.descriptions() ? Optional.ofNullable(id.getDescription()).orElse(" ") : " ";
94+
}
95+
96+
public void add(List<Tag> tags, Child child) {
97+
children.put(TagsHolder.from(tags), child);
98+
}
99+
100+
public void remove(List<Tag> tags) {
101+
children.remove(TagsHolder.from(tags));
102+
}
103+
104+
public boolean isEmpty() {
105+
return children.isEmpty();
106+
}
107+
108+
@Override
109+
public List<MetricFamilySamples> collect() {
110+
Map<String, Family> families = new HashMap<>();
111+
112+
for (Map.Entry<TagsHolder, Child> e : children.entrySet()) {
113+
TagsHolder tags = e.getKey();
114+
Child child = e.getValue();
115+
116+
child.samples(conventionName, tags).forEach(family -> {
117+
families.compute(family.getConventionName(), (name, matchingFamily) -> matchingFamily != null ?
118+
matchingFamily.addSamples(family.samples) : family);
119+
});
120+
}
121+
122+
return families.values().stream()
123+
.map(family -> new MetricFamilySamples(family.conventionName, family.type, help, family.samples))
124+
.collect(toList());
125+
}
126+
127+
@Override
128+
public List<MetricFamilySamples> describe() {
129+
switch (id.getType()) {
130+
case COUNTER:
131+
return Collections.singletonList(
132+
new MetricFamilySamples(conventionName, Type.COUNTER, help, Collections.emptyList()));
133+
134+
case GAUGE:
135+
return Collections.singletonList(
136+
new MetricFamilySamples(conventionName, Type.GAUGE, help, Collections.emptyList()));
137+
138+
case TIMER:
139+
case DISTRIBUTION_SUMMARY:
140+
return Arrays.asList(
141+
new MetricFamilySamples(conventionName, Type.HISTOGRAM, help, Collections.emptyList()),
142+
new MetricFamilySamples(conventionName + "_max", Type.GAUGE, help, Collections.emptyList()));
143+
144+
case LONG_TASK_TIMER:
145+
return Arrays.asList(
146+
new MetricFamilySamples(conventionName, Type.HISTOGRAM, help, Collections.emptyList()),
147+
new MetricFamilySamples(conventionName, Type.UNKNOWN, help, Collections.emptyList()));
148+
149+
default:
150+
return Collections.singletonList(
151+
new MetricFamilySamples(conventionName, Type.UNKNOWN, help, Collections.emptyList()));
152+
}
153+
}
154+
155+
interface Child {
156+
Stream<Family> samples(String conventionName, TagsHolder tags);
157+
}
158+
159+
static class Family {
160+
final Type type;
161+
final String conventionName;
162+
final List<MetricFamilySamples.Sample> samples = new ArrayList<>();
163+
164+
Family(Type type, String conventionName, MetricFamilySamples.Sample... samples) {
165+
this.type = type;
166+
this.conventionName = conventionName;
167+
Collections.addAll(this.samples, samples);
168+
}
169+
170+
Family(Type type, String conventionName, Stream<MetricFamilySamples.Sample> samples) {
171+
this.type = type;
172+
this.conventionName = conventionName;
173+
samples.forEach(this.samples::add);
174+
}
175+
176+
String getConventionName() {
177+
return conventionName;
178+
}
179+
180+
Family addSamples(Collection<MetricFamilySamples.Sample> samples) {
181+
this.samples.addAll(samples);
182+
return this;
183+
}
184+
}
185+
}

0 commit comments

Comments
 (0)