-
Notifications
You must be signed in to change notification settings - Fork 215
/
KamonHistogram.java
137 lines (113 loc) · 3.99 KB
/
KamonHistogram.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* Copyright (c) 2017 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.ditto.internal.utils.metrics.instruments.histogram;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import kamon.Kamon;
import kamon.metric.Distribution;
import kamon.tag.TagSet;
import scala.collection.Seq;
import scala.jdk.javaapi.CollectionConverters;
/**
* Kamon based implementation of {@link Histogram}.
*/
@Immutable
public class KamonHistogram implements Histogram {
private static final Logger LOGGER = LoggerFactory.getLogger(KamonHistogram.class);
private final Map<String, String> tags;
private final String name;
private KamonHistogram(final String name, final Map<String, String> tags) {
this.name = name;
this.tags = Collections.unmodifiableMap(new HashMap<>(tags));
}
public static Histogram newHistogram(final String name) {
return new KamonHistogram(name, Collections.emptyMap());
}
@Override
public Histogram tag(final String key, final String value) {
final HashMap<String, String> newMap = new HashMap<>(tags);
newMap.put(key, value);
return new KamonHistogram(name, newMap);
}
@Override
public Histogram tags(final Map<String, String> tags) {
final HashMap<String, String> newMap = new HashMap<>(this.tags);
newMap.putAll(tags);
return new KamonHistogram(name, newMap);
}
@Nullable
@Override
public String getTag(final String key) {
return tags.get(key);
}
@Override
public Map<String, String> getTags() {
return tags;
}
@Override
public boolean reset() {
try {
getSnapshot(true);
LOGGER.trace("Reset histogram with name <{}>.", name);
} catch (IllegalStateException e) {
LOGGER.warn("Could not reset Kamon timer.", e);
return false;
}
return true;
}
@Override
public Histogram record(final Long value) {
getKamonInternalHistogram().record(value);
return this;
}
@Override
public Long[] getRecordedValues() {
final List<Long> values = new ArrayList<>();
final Seq<Distribution.Bucket> buckets = getSnapshot(false).map(Distribution::buckets)
.orElseGet(() -> CollectionConverters.asScala(Collections.<Distribution.Bucket>emptyList()).toSeq());
buckets.foreach(bucket -> addBucketValuesToList(bucket, values));
return values.toArray(new Long[0]);
}
private List<Long> addBucketValuesToList(Distribution.Bucket bucket, List<Long> values) {
for (int i = 0; i < bucket.frequency(); i++) {
values.add(bucket.value());
}
return values;
}
private Optional<Distribution> getSnapshot(final boolean reset) {
final kamon.metric.Histogram histogram = getKamonInternalHistogram();
if (histogram instanceof kamon.metric.Histogram.Atomic atomic) {
return Optional.of(atomic.snapshot(reset));
}
LOGGER.warn("Could not get snapshot of kamon internal histogram");
return Optional.empty();
}
private kamon.metric.Histogram getKamonInternalHistogram() {
return Kamon.histogram(name).withTags(TagSet.from(new HashMap<>(tags)));
}
@Override
public String toString() {
return getClass().getSimpleName() + " [" +
"name=" + name +
", tags=" + tags +
"]";
}
}