A Micrometer metrics registry for sending dimensional metrics to Logz.io.
This registry can be used by any application that uses micrometer for recording metrics.
Note: you will need java 8 or above
<dependency>
<groupId>io.logz.micrometer</groupId>
<artifactId>micrometer-registry-logzio</artifactId>
<version>1.0.2</version>
</dependency>
implementation 'io.logz.micrometer:micrometer-registry-logzio:1.0.2'
implementation("io.logz.micrometer:micrometer-registry-logzio:1.0.2")
import io.micrometer.logzio.LogzioConfig;
import io.micrometer.logzio.LogzioMeterRegistry;
Replace the placeholders in the code (indicated by the double angle brackets << >>
) to match your specifics.
Environment variable | Description | Required/Default |
---|---|---|
listener-url | The full Logz.io Listener URL for for your region, configured to use port 8052 for http traffic, or port 8053 for https traffic (example: https://listener.logz.io:5053). For more details, see the regions page in logz.io docs | Required |
metrics-token | The Logz.io Prometheus Metrics account token. Find it under Settings > Manage accounts. Look up your Metrics account token. | Required |
interval | The interval in seconds, to push metrics to Logz.io Note that your program will need to run for at least one interval for the metrics to be sent | Required |
package your_package;
import io.micrometer.core.instrument.*;
import io.micrometer.core.instrument.Timer;
import io.micrometer.logzio.LogzioConfig;
import io.micrometer.logzio.LogzioMeterRegistry;
class MicrometerLogzio {
public static void main(String[] args) {
// initilize config
LogzioConfig logzioConfig = new LogzioConfig() {
@Override
public String get(String key) {
return null;
}
@Override
public String uri() {
return "<<listener-url>>";
// example:
// return "https://listener.logz.io:8053";
}
@Override
public String token() {
return "<<metrics-token>>";
}
@Override
public Duration step() {
return Duration.ofSeconds(<<interval>>);
// example:
// return Duration.ofSeconds(30);
}
@Override
public Hashtable<String, String> includeLabels() {
return new Hashtable<>();
}
@Override
public Hashtable<String, String> excludeLabels() {
return new Hashtable<>();
};
// Initialize registry
LogzioMeterRegistry registry = new LogzioMeterRegistry(logzioConfig, Clock.SYSTEM);
// Define tags (labels)
ArrayList<Tag> tags = new ArrayList<>();
tags.add(Tag.of("env","dev-micrometer"));
// Create counter
Counter counter = Counter
.builder("counter_example")
.description("a description of what this counter does") // optional
.tags(tags) // optional
.register(registry);
// Increment your counter
counter.increment();
counter.increment(2);
}
}
You can attach common tags to your registry that will be added to all metrics reported, for example:
// Initialize registry
LogzioMeterRegistry registry = new LogzioMeterRegistry(logzioConfig, Clock.SYSTEM);
// Define tags (labels)
registry.config().commonTags("key", "value");
you can the includeLabels
or excludeLabels
functions to filter your metrics by labels.
Take for example this following usage, In your LogzioConfig()
constructor:
@Override
public Hashtable<String, String> includeLabels() {
Hashtable<String, String> includeLabels = new Hashtable<>();
includeLabels.put("__name__", "my_counter_abc_total|my_second_counter_abc_total");
includeLabels.put("k1", "v1");
return includeLabels;
}
The registry will keep only metrics with the label __name__
matching the regex my_counter_abc_total|my_second_counter_abc_total
, and with the label k1
matching the regex v1
.
In your LogzioConfig()
constructor:
@Override
public Hashtable<String, String> excludeLabels() {
Hashtable<String, String> excludeLabels = new Hashtable<>();
excludeLabels.put("__name__", "my_counter_abc_total|my_second_counter_abc_total");
excludeLabels.put("k1", "v1");
return excludeLabels;
}
The registry will drop all metrics with the label __name__
matching the regex my_counter_abc_total|my_second_counter_abc_total
, and with the label k1
matching the regex v1
.
Micrometer provides a set of binders for monitoring JVM metrics out of the box, for example:
// Initialize registry
LogzioMeterRegistry registry = new LogzioMeterRegistry(logzioConfig, Clock.SYSTEM);
// Gauges buffer and memory pool utilization
new JvmMemoryMetrics().bindTo(registry);
// Gauges max and live data size, promotion and allocation rates, and times GC pauses
new JvmGcMetrics().bindTo(registry);
// Gauges current CPU total and load average.
new ProcessorMetrics().bindTo(registry);
// Gauges thread peak, number of daemon threads, and live threads
new JvmThreadMetrics().bindTo(registry);
// Gauges loaded and unloaded classes
new ClassLoaderMetrics().bindTo(registry);
// File descriptor metrics gathered by the JVM
new FileDescriptorMetrics(tags).bindTo(registry);
// Gauges The uptime and start time of the Java virtual machine
new UptimeMetrics(tags).bindTo(registry);
// Counter of logging events
new LogbackMetrics().bindTo(registry);
new Log4j2Metrics().bindTo(registry);
For more information about other binders check out Micrometer-core Github repo.
Refer to the Micrometer documentation for more details.
Name | Behavior |
---|---|
Counter | Metric value can only go up or be reset to 0, calculated per counter.increment(value); call. |
Gauge | Metric value can arbitrarily increment or decrement, values can set automaticaly by tracking Collection size or set manually by gauge.set(value) |
DistributionSummary | Metric values captured by the summary.record(value) function, the output is a distribution of count ,sum and max for the recorded values during the push interval. |
Timer | Mesures timing, metric values can be recorded by timer.record() call. |
Counter counter = Counter
.builder("counter_example")
.description("a description of what this counter does") // optional
.tags(tags) // optional
.register(registry);
// Increment your counter
counter.increment();
counter.increment(2);
// The following metric will be created and sent to Logz.io: counter_example_total{env="dev"} 3
// Create Gauge
List<String> cache = new ArrayList<>(4);
// Track list size
Gauge gauge = Gauge
.builder("cache_size_gauge_example", cache, List::size)
.tags(tags)
.register(registry);
cache.add("1");
// The following metric will be created and sent to Logz.io: cache_size_gauge_example{env="dev"} 1
// Track map size
Map<String, Integer> map_gauge = registry.gaugeMapSize("map_gauge_example", tags, new HashMap<>());
map_gauge.put("key",1);
// The following metric will be created and sent to Logz.io: map_gauge_example{env="dev"} 1
// set value manually
AtomicInteger manual_gauge = registry.gauge("manual_gauge_example", new AtomicInteger(0));
manual_gauge.set(83);
// The following metric will be created and sent to Logz.io:: manual_gauge_example{env="dev"} 83
// Create DistributionSummary
DistributionSummary summary = DistributionSummary
.builder("summary_example")
.description("a description of what this summary does") // optional
.tags(tags) // optional
.register(registry);
// Record values to distributionSummary
summary.record(10);
summary.record(20);
summary.record(30);
// // The following metrics will be created and sent to Logz.io:
// summary_example_count{env="dev"} 3
// summary_example_max{env="dev"} 30
// summary_example_sum{env="dev"} 60
// Create Timer
Timer timer = Timer
.builder("timer_example")
.description("a description of what this timer does") // optional
.tags(tags) // optional
.register(registry);
// You can set a value manually
timer.record(1500,TimeUnit.MILLISECONDS);
// You can record the timing of a function
timer.record(()-> {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// The following metrics will be created and sent to Logz.io:
// timer_example_duration_seconds_count{env="dev"} 2
// timer_example_duration_seconds_max{env="dev"} 1501
// timer_example_duration_seconds_sum{env="dev"} 3000
- 1.0.2:
- Compatible with Java 8 and above
- Enable Include and Exclude filter
- Implement retry mechanism
- GitHub actions (test with multiple java versions and operating systems)
- 1.0.1:
- Compatible with Java 11 and above
- 1.0.0:
- Initial release.