|
22 | 22 | */
|
23 | 23 | package org.opengrok.indexer;
|
24 | 24 |
|
| 25 | +import io.micrometer.core.instrument.Clock; |
| 26 | +import io.micrometer.core.instrument.MeterRegistry; |
| 27 | +import io.micrometer.core.instrument.Tag; |
25 | 28 | import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics;
|
26 | 29 | import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
|
27 | 30 | import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
|
28 | 31 | import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
|
29 | 32 | import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
|
30 | 33 | import io.micrometer.prometheus.PrometheusConfig;
|
31 | 34 | import io.micrometer.prometheus.PrometheusMeterRegistry;
|
| 35 | +import io.micrometer.statsd.StatsdConfig; |
| 36 | +import io.micrometer.statsd.StatsdMeterRegistry; |
| 37 | +import io.micrometer.statsd.StatsdFlavor; |
| 38 | +import org.opengrok.indexer.configuration.RuntimeEnvironment; |
| 39 | +import org.opengrok.indexer.index.Indexer; |
| 40 | +import org.opengrok.indexer.logger.LoggerFactory; |
32 | 41 |
|
| 42 | +import java.util.Collections; |
| 43 | +import java.util.List; |
| 44 | +import java.util.logging.Level; |
| 45 | +import java.util.logging.Logger; |
| 46 | +import java.util.stream.Collectors; |
| 47 | + |
| 48 | +/** |
| 49 | + * Encapsulates logic of meter registry setup and handling. |
| 50 | + * Generally, the web application publishes metrics to Prometheus and the Indexer to StatsD. |
| 51 | + */ |
33 | 52 | public final class Metrics {
|
34 | 53 |
|
35 |
| - private static final PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); |
| 54 | + private static final Logger LOGGER = LoggerFactory.getLogger(Metrics.class); |
| 55 | + |
| 56 | + private static final StatsdConfig statsdConfig = new StatsdConfig() { |
| 57 | + @Override |
| 58 | + public String get(String k) { |
| 59 | + return null; |
| 60 | + } |
| 61 | + |
| 62 | + @Override |
| 63 | + public StatsdFlavor flavor() { |
| 64 | + return RuntimeEnvironment.getInstance().getStatsdConfig().getFlavor(); |
| 65 | + } |
| 66 | + |
| 67 | + @Override |
| 68 | + public int port() { |
| 69 | + return RuntimeEnvironment.getInstance().getStatsdConfig().getPort(); |
| 70 | + } |
| 71 | + |
| 72 | + @Override |
| 73 | + public String host() { |
| 74 | + return RuntimeEnvironment.getInstance().getStatsdConfig().getHost(); |
| 75 | + } |
| 76 | + |
| 77 | + @Override |
| 78 | + public boolean buffered() { |
| 79 | + return true; |
| 80 | + } |
| 81 | + }; |
| 82 | + |
| 83 | + private static PrometheusMeterRegistry prometheusRegistry; |
| 84 | + private static StatsdMeterRegistry statsdRegistry; |
36 | 85 |
|
37 | 86 | static {
|
38 |
| - new ClassLoaderMetrics().bindTo(registry); |
39 |
| - new JvmMemoryMetrics().bindTo(registry); |
40 |
| - new JvmGcMetrics().bindTo(registry); |
41 |
| - new ProcessorMetrics().bindTo(registry); |
42 |
| - new JvmThreadMetrics().bindTo(registry); |
| 87 | + MeterRegistry registry = null; |
| 88 | + |
| 89 | + if (RuntimeEnvironment.getInstance().getStatsdConfig().isEnabled()) { |
| 90 | + LOGGER.log(Level.INFO, "configuring StatsdRegistry"); |
| 91 | + statsdRegistry = new StatsdMeterRegistry(statsdConfig, Clock.SYSTEM); |
| 92 | + registry = statsdRegistry; |
| 93 | + } else if (!RuntimeEnvironment.getInstance().isIndexer()) { |
| 94 | + LOGGER.log(Level.INFO, "configuring PrometheusRegistry"); |
| 95 | + prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); |
| 96 | + registry = prometheusRegistry; |
| 97 | + } |
| 98 | + |
| 99 | + if (registry != null) { |
| 100 | + new ClassLoaderMetrics().bindTo(registry); |
| 101 | + new JvmMemoryMetrics().bindTo(registry); |
| 102 | + new JvmGcMetrics().bindTo(registry); |
| 103 | + new ProcessorMetrics().bindTo(registry); |
| 104 | + new JvmThreadMetrics().bindTo(registry); |
| 105 | + } |
43 | 106 | }
|
44 | 107 |
|
45 | 108 | private Metrics() {
|
46 | 109 | }
|
47 | 110 |
|
48 |
| - public static PrometheusMeterRegistry getRegistry() { |
49 |
| - return registry; |
| 111 | + public static void updateSubFiles(List<String> subFiles) { |
| 112 | + // Add tag for per-project reindex. |
| 113 | + if (statsdRegistry != null && !subFiles.isEmpty()) { |
| 114 | + String projects = subFiles.stream(). |
| 115 | + map(s -> s.startsWith(Indexer.PATH_SEPARATOR_STRING) ? s.substring(1) : s). |
| 116 | + collect(Collectors.joining(",")); |
| 117 | + Tag commonTag = Tag.of("projects", projects); |
| 118 | + LOGGER.log(Level.FINE, "updating statsdRegistry with common tag: {}", commonTag); |
| 119 | + statsdRegistry.config().commonTags(Collections.singleton(commonTag)); |
| 120 | + } |
| 121 | + } |
| 122 | + |
| 123 | + public static PrometheusMeterRegistry getPrometheusRegistry() { |
| 124 | + return prometheusRegistry; |
50 | 125 | }
|
51 | 126 |
|
| 127 | + private static StatsdMeterRegistry getStatsdRegistry() { |
| 128 | + return statsdRegistry; |
| 129 | + } |
| 130 | + |
| 131 | + /** |
| 132 | + * Get registry based on running context. |
| 133 | + * @return MeterRegistry instance |
| 134 | + */ |
| 135 | + public static MeterRegistry getRegistry() { |
| 136 | + if (RuntimeEnvironment.getInstance().isIndexer()) { |
| 137 | + return getStatsdRegistry(); |
| 138 | + } else { |
| 139 | + return getPrometheusRegistry(); |
| 140 | + } |
| 141 | + } |
52 | 142 | }
|
0 commit comments