Skip to content

Commit 2fd1300

Browse files
vjkoskelaBrandonArp
authored andcommitted
Update StatisticFactory.java (#91)
Do not preload `TPStatistic` since it lacks a default constructor; but do preload specified TPStatistics.
1 parent 0675f68 commit 2fd1300

File tree

1 file changed

+39
-17
lines changed

1 file changed

+39
-17
lines changed

src/main/java/com/arpnetworking/tsdcore/statistics/StatisticFactory.java

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
*/
1616
package com.arpnetworking.tsdcore.statistics;
1717

18+
import com.arpnetworking.steno.Logger;
19+
import com.arpnetworking.steno.LoggerFactory;
1820
import com.arpnetworking.utility.InterfaceDatabase;
1921
import com.arpnetworking.utility.ReflectionsDatabase;
22+
import com.google.common.collect.ImmutableList;
2023
import com.google.common.collect.Maps;
21-
import org.slf4j.Logger;
22-
import org.slf4j.LoggerFactory;
2324

2425
import java.lang.reflect.Constructor;
2526
import java.lang.reflect.InvocationTargetException;
@@ -62,25 +63,33 @@ public Optional<Statistic> tryGetStatistic(final String name) {
6263
final Optional<Statistic> registeredStatistic =
6364
Optional.ofNullable(STATISTICS_BY_NAME_AND_ALIAS.get(name));
6465
if (!registeredStatistic.isPresent()) {
65-
final Matcher matcher = PERCENTILE_STATISTIC_PATTERN.matcher(name);
66-
if (matcher.matches()) {
67-
try {
68-
final String percentileString = matcher.group("percentile").replace('p', '.');
69-
final double percentile = Double.parseDouble(percentileString);
70-
final Statistic statistic = new TPStatistic(percentile);
71-
checkedPut(STATISTICS_BY_NAME_AND_ALIAS, statistic);
72-
return Optional.of(statistic);
73-
} catch (final NumberFormatException e) {
74-
LOGGER.error(String.format(
75-
"Invalid percentile statistic; name=%s",
76-
name));
77-
return registeredStatistic;
78-
}
66+
final Optional<Statistic> statistic = getPercentileStatistic(name);
67+
if (statistic.isPresent()) {
68+
checkedPut(STATISTICS_BY_NAME_AND_ALIAS, statistic.get());
69+
return statistic;
7970
}
8071
}
8172
return registeredStatistic;
8273
}
8374

75+
private static Optional<Statistic> getPercentileStatistic(final String name) {
76+
final Matcher matcher = PERCENTILE_STATISTIC_PATTERN.matcher(name);
77+
if (matcher.matches()) {
78+
try {
79+
final String percentileString = matcher.group("percentile").replace('p', '.');
80+
final double percentile = Double.parseDouble(percentileString);
81+
final Statistic statistic = new TPStatistic(percentile);
82+
return Optional.of(statistic);
83+
} catch (final NumberFormatException e) {
84+
LOGGER.error()
85+
.setMessage("Invalid percentile statistic")
86+
.addData("name", name)
87+
.log();
88+
}
89+
}
90+
return Optional.empty();
91+
}
92+
8493
private static void checkedPut(final ConcurrentMap<String, Statistic> map, final Statistic statistic) {
8594
checkedPut(map, statistic, statistic.getName());
8695
for (final String alias : statistic.getAliases()) {
@@ -106,14 +115,16 @@ private static void checkedPut(final ConcurrentMap<String, Statistic> map, final
106115
private static final Pattern PERCENTILE_STATISTIC_PATTERN = Pattern.compile("^[t]?p(?<percentile>[0-9]+(?:(\\.|p)[0-9]+)?)$");
107116
private static final ConcurrentMap<String, Statistic> STATISTICS_BY_NAME_AND_ALIAS;
108117
private static final InterfaceDatabase INTERFACE_DATABASE = ReflectionsDatabase.newInstance();
118+
private static final ImmutableList<String> PERCENTILE_STATISTICS_TO_PRELOAD = ImmutableList.of("p75", "p90", "p95", "p99", "p99.9");
109119
private static final Logger LOGGER = LoggerFactory.getLogger(StatisticFactory.class);
110120

111121
static {
112122
// NOTE: Do not put log messages in static blocks since they can lock the logger thread!
113123
final ConcurrentMap<String, Statistic> statisticByNameAndAlias = Maps.newConcurrentMap();
114124
final Set<Class<? extends Statistic>> statisticClasses = INTERFACE_DATABASE.findClassesWithInterface(Statistic.class);
115125
for (final Class<? extends Statistic> statisticClass : statisticClasses) {
116-
if (!statisticClass.isInterface() && !Modifier.isAbstract(statisticClass.getModifiers())) {
126+
if (!statisticClass.isInterface() && !Modifier.isAbstract(statisticClass.getModifiers())
127+
&& !TPStatistic.class.equals(statisticClass)) {
117128
try {
118129
final Constructor<? extends Statistic> constructor = statisticClass.getDeclaredConstructor();
119130
if (!constructor.isAccessible()) {
@@ -126,6 +137,17 @@ private static void checkedPut(final ConcurrentMap<String, Statistic> map, final
126137
}
127138
}
128139
}
140+
for (final String percentileStatisticName : PERCENTILE_STATISTICS_TO_PRELOAD) {
141+
final Optional<Statistic> statistic = getPercentileStatistic(percentileStatisticName);
142+
if (statistic.isPresent()) {
143+
checkedPut(statisticByNameAndAlias, statistic.get());
144+
} else {
145+
LOGGER.warn()
146+
.setMessage("Unable to load statistic")
147+
.addData("name", percentileStatisticName)
148+
.log();
149+
}
150+
}
129151
STATISTICS_BY_NAME_AND_ALIAS = statisticByNameAndAlias;
130152
}
131153
}

0 commit comments

Comments
 (0)