Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/main/java/io/getunleash/impactmetrics/HistogramImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ public CollectedMetric collect() {
countSnapshot = data.count;
sumSnapshot = data.sum;
for (Double le : buckets) {
bucketSamples.add(
new HistogramBucket(le, data.buckets.getOrDefault(le, 0L)));
bucketSamples.add(new HistogramBucket(le, data.buckets.getOrDefault(le, 0L)));
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linting

}
}

Expand Down
16 changes: 16 additions & 0 deletions src/main/java/io/getunleash/metric/ClientMetrics.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import io.getunleash.engine.UnleashEngine;
import io.getunleash.event.UnleashEvent;
import io.getunleash.event.UnleashSubscriber;
import io.getunleash.impactmetrics.CollectedMetric;
import io.getunleash.lang.Nullable;
import io.getunleash.util.UnleashConfig;
import java.util.List;

public class ClientMetrics implements UnleashEvent {

Expand All @@ -18,8 +20,16 @@ public class ClientMetrics implements UnleashEvent {
@Nullable private final String platformName;
@Nullable private final String platformVersion;
@Nullable private final String yggdrasilVersion;
@Nullable private final List<CollectedMetric> impactMetrics;

ClientMetrics(UnleashConfig config, @Nullable MetricsBucket bucket) {
this(config, bucket, null);
}

ClientMetrics(
UnleashConfig config,
@Nullable MetricsBucket bucket,
@Nullable List<CollectedMetric> impactMetrics) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding impact metrics so it can be used in next iterations.

this.environment = config.getEnvironment();
this.appName = config.getAppName();
this.instanceId = config.getInstanceId();
Expand All @@ -29,6 +39,7 @@ public class ClientMetrics implements UnleashEvent {
this.platformName = System.getProperty("java.vm.name");
this.platformVersion = System.getProperty("java.version");
this.yggdrasilVersion = UnleashEngine.getCoreVersion();
this.impactMetrics = impactMetrics;
}

public String getAppName() {
Expand Down Expand Up @@ -71,6 +82,11 @@ public String getYggdrasilVersion() {
return yggdrasilVersion;
}

@Nullable
public List<CollectedMetric> getImpactMetrics() {
return impactMetrics;
}

@Override
public void publishTo(UnleashSubscriber unleashSubscriber) {
unleashSubscriber.clientMetrics(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import com.google.gson.*;
import io.getunleash.UnleashException;
import io.getunleash.event.EventDispatcher;
import io.getunleash.impactmetrics.HistogramBucket;
import io.getunleash.util.AtomicLongSerializer;
import io.getunleash.util.DateTimeSerializer;
import io.getunleash.util.HistogramBucketSerializer;
import io.getunleash.util.InstantSerializer;
import io.getunleash.util.UnleashConfig;
import io.getunleash.util.UnleashURLs;
Expand Down Expand Up @@ -38,6 +40,7 @@ public DefaultHttpMetricsSender(UnleashConfig unleashConfig) {
.registerTypeAdapter(LocalDateTime.class, new DateTimeSerializer())
.registerTypeAdapter(Instant.class, new InstantSerializer())
.registerTypeAdapter(AtomicLong.class, new AtomicLongSerializer())
.registerTypeAdapter(HistogramBucket.class, new HistogramBucketSerializer())
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Register our serializer

.create();
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/io/getunleash/metric/OkHttpMetricsSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import com.google.gson.GsonBuilder;
import io.getunleash.UnleashException;
import io.getunleash.event.EventDispatcher;
import io.getunleash.impactmetrics.HistogramBucket;
import io.getunleash.util.AtomicLongSerializer;
import io.getunleash.util.DateTimeSerializer;
import io.getunleash.util.HistogramBucketSerializer;
import io.getunleash.util.OkHttpClientConfigurer;
import io.getunleash.util.UnleashConfig;
import java.io.IOException;
Expand Down Expand Up @@ -58,6 +60,7 @@ public OkHttpMetricsSender(UnleashConfig config) {
new GsonBuilder()
.registerTypeAdapter(LocalDateTime.class, new DateTimeSerializer())
.registerTypeAdapter(AtomicLong.class, new AtomicLongSerializer())
.registerTypeAdapter(HistogramBucket.class, new HistogramBucketSerializer())
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Register serializer.

.create();
}

Expand Down
24 changes: 24 additions & 0 deletions src/main/java/io/getunleash/util/HistogramBucketSerializer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.getunleash.util;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import io.getunleash.impactmetrics.HistogramBucket;
import java.lang.reflect.Type;

public class HistogramBucketSerializer implements JsonSerializer<HistogramBucket> {

@Override
public JsonElement serialize(
HistogramBucket src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
if (Double.isInfinite(src.getLe()) && src.getLe() > 0) {
jsonObject.addProperty("le", "+Inf");
} else {
jsonObject.addProperty("le", src.getLe());
}
jsonObject.addProperty("count", src.getCount());
return jsonObject;
}
}
Comment on lines +12 to +24
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are adding simple json serializer for Double.POSITIVE_INFINITY.

21 changes: 19 additions & 2 deletions src/main/java/io/getunleash/util/UnleashConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.getunleash.UnleashException;
import io.getunleash.event.NoOpSubscriber;
import io.getunleash.event.UnleashSubscriber;
import io.getunleash.impactmetrics.ImpactMetricsDataSource;
import io.getunleash.lang.Nullable;
import io.getunleash.metric.DefaultHttpMetricsSender;
import io.getunleash.repository.HttpFeatureFetcher;
Expand Down Expand Up @@ -73,6 +74,7 @@ public class UnleashConfig {
@Nullable private final ToggleBootstrapProvider toggleBootstrapProvider;
@Nullable private final Proxy proxy;
@Nullable private final Consumer<UnleashException> startupExceptionHandler;
@Nullable private final ImpactMetricsDataSource impactMetricsRegistry;

private UnleashConfig(
@Nullable URI unleashAPI,
Expand Down Expand Up @@ -106,7 +108,8 @@ private UnleashConfig(
@Nullable ToggleBootstrapProvider unleashBootstrapProvider,
@Nullable Proxy proxy,
@Nullable Authenticator proxyAuthenticator,
@Nullable Consumer<UnleashException> startupExceptionHandler) {
@Nullable Consumer<UnleashException> startupExceptionHandler,
@Nullable ImpactMetricsDataSource impactMetricsRegistry) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Java it is possible to build config by adding custom registry.


if (appName == null) {
throw new IllegalStateException("You are required to specify the unleash appName");
Expand Down Expand Up @@ -172,6 +175,7 @@ private UnleashConfig(
this.clientSpecificationVersion =
UnleashProperties.getProperty("client.specification.version");
this.startupExceptionHandler = startupExceptionHandler;
this.impactMetricsRegistry = impactMetricsRegistry;
}

public static Builder builder() {
Expand Down Expand Up @@ -352,6 +356,11 @@ public Proxy getProxy() {
return proxy;
}

@Nullable
public ImpactMetricsDataSource getImpactMetricsRegistry() {
return impactMetricsRegistry;
}

public MetricSenderFactory getMetricSenderFactory() {
return this.metricSenderFactory;
}
Expand Down Expand Up @@ -462,6 +471,7 @@ public static class Builder {
private @Nullable Authenticator proxyAuthenticator;

private @Nullable Consumer<UnleashException> startupExceptionHandler;
private @Nullable ImpactMetricsDataSource impactMetricsRegistry;

private static String getHostname() {
String hostName = System.getProperty("hostname");
Expand Down Expand Up @@ -715,6 +725,12 @@ public Builder startupExceptionHandler(
return this;
}

public Builder impactMetricsRegistry(
@Nullable ImpactMetricsDataSource impactMetricsRegistry) {
this.impactMetricsRegistry = impactMetricsRegistry;
return this;
}

public UnleashConfig build() {
return new UnleashConfig(
unleashAPI,
Expand Down Expand Up @@ -749,7 +765,8 @@ public UnleashConfig build() {
toggleBootstrapProvider,
proxy,
proxyAuthenticator,
startupExceptionHandler);
startupExceptionHandler,
impactMetricsRegistry);
}

public String getDefaultSdkVersion() {
Expand Down
59 changes: 59 additions & 0 deletions src/test/java/io/getunleash/impactmetrics/MetricTypeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import static org.assertj.core.api.Assertions.assertThat;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.getunleash.util.HistogramBucketSerializer;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -300,4 +303,60 @@ private NumericMetricSample sample(long value) {
private NumericMetricSample sample(Map<String, String> labels, long value) {
return new NumericMetricSample(labels, value);
}

@Test
public void should_serialize_histogram_with_positive_infinity_as_plus_inf_string() {
InMemoryMetricRegistry registry = new InMemoryMetricRegistry();
Histogram histogram =
registry.histogram(
new BucketMetricOptions(
"serialization_test", "test serialization", List.of(1.0, 5.0)));

histogram.observe(10.0, Map.of("env", "prod"));

List<CollectedMetric> metrics = registry.collect();
assertThat(metrics).hasSize(1);

Gson gson =
new GsonBuilder()
.registerTypeAdapter(HistogramBucket.class, new HistogramBucketSerializer())
.create();

String json = gson.toJson(metrics.get(0));

assertThat(json).contains("\"le\":\"+Inf\"");
assertThat(json).contains("\"le\":1.0");
assertThat(json).contains("\"le\":5.0");
}

@Test
public void should_serialize_histogram_buckets_correctly() {
InMemoryMetricRegistry registry = new InMemoryMetricRegistry();
Histogram histogram =
registry.histogram(
new BucketMetricOptions(
"bucket_serialization", "test buckets", List.of(0.5, 2.0)));

histogram.observe(0.3);
histogram.observe(1.5);
histogram.observe(10.0);

List<CollectedMetric> metrics = registry.collect();
assertThat(metrics).hasSize(1);

BucketMetricSample sample = (BucketMetricSample) metrics.get(0).getSamples().get(0);
assertThat(sample.getBuckets()).hasSize(3);

Gson gson =
new GsonBuilder()
.registerTypeAdapter(HistogramBucket.class, new HistogramBucketSerializer())
.create();

String json = gson.toJson(sample);

assertThat(json).contains("\"le\":0.5");
assertThat(json).contains("\"le\":2.0");
assertThat(json).contains("\"le\":\"+Inf\"");
assertThat(json).contains("\"count\":");
}
}
Loading