This is an automated email from the ASF dual-hosted git repository.
anovikov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 51df7cc1e2 IGNITE-17443 Implement OpenTelemetry metric exporter.
(#4531)
51df7cc1e2 is described below
commit 51df7cc1e276d8f64c5518b3539c748dc9ca4f27
Author: Andrey Novikov <[email protected]>
AuthorDate: Tue Nov 19 18:11:17 2024 +0700
IGNITE-17443 Implement OpenTelemetry metric exporter. (#4531)
---
gradle/libs.versions.toml | 3 +
modules/metrics-exporter-otlp/build.gradle | 51 +++++
.../configuration/HeadersConfigurationSchema.java} | 21 +-
.../OtlpExporterConfigurationModule.java | 50 +++++
.../OtlpExporterConfigurationSchema.java | 65 ++++++
.../otlp/IgniteDistributionMetricData.java | 150 +++++++++++++
.../exporters/otlp/IgniteDoubleMetricData.java | 71 ++++++
.../metrics/exporters/otlp/IgniteGaugeData.java} | 29 ++-
.../exporters/otlp/IgniteIntMetricData.java | 71 ++++++
.../exporters/otlp/IgniteLongMetricData.java | 71 ++++++
.../metrics/exporters/otlp/IgniteMetricData.java | 68 ++++++
.../metrics/exporters/otlp/IgnitePointData.java} | 29 ++-
.../metrics/exporters/otlp/MetricReporter.java | 244 +++++++++++++++++++++
.../exporters/otlp/OtlpPushMetricExporter.java | 116 ++++++++++
.../exporters/validator/EndpointValidator.java} | 19 +-
.../exporters/validator/EndpointValidatorImpl.java | 52 +++++
.../exporters/otlp/OtlpPushMetricExporterTest.java | 159 ++++++++++++++
.../validator/EndpointValidatorImplTest.java | 103 +++++++++
.../metrics/exporters/ItJvmMetricSourceTest.java | 3 +-
.../exporters/ItMetricExportersLoadingTest.java | 3 +-
.../metrics/exporters/ItOsMetricSourceTest.java | 3 +-
.../metrics/exporters/TestDoubleStartExporter.java | 7 +-
.../metrics/exporters/TestPullMetricExporter.java | 6 +-
.../metrics/exporters/TestPushMetricExporter.java | 7 +-
.../ignite/internal/metrics/MetricManager.java | 6 +-
.../ignite/internal/metrics/MetricManagerImpl.java | 16 +-
.../metrics/exporters/BasicMetricExporter.java | 24 +-
.../internal/metrics/exporters/MetricExporter.java | 14 +-
.../metrics/exporters/PushMetricExporter.java | 7 +-
.../LogPushExporterConfigurationSchema.java | 3 +-
.../metrics/exporters/jmx/JmxExporter.java | 7 +-
.../metrics/exporters/log/LogPushExporter.java | 7 +-
.../internal/metrics/MetricConfigurationTest.java | 3 +-
.../internal/metrics/exporters/TestExporter.java | 6 +-
.../{ => exporters/jmx}/JmxExporterTest.java | 28 ++-
.../ignite/internal/metrics/NoOpMetricManager.java | 4 +-
modules/runner/build.gradle | 1 +
.../org/apache/ignite/internal/app/IgniteImpl.java | 7 +-
settings.gradle | 2 +
39 files changed, 1466 insertions(+), 70 deletions(-)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 53da19f915..aa70f02dbf 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -83,6 +83,7 @@ tree-sitter = "0.24.3"
tree-sitter-json = "0.23.0"
tree-sitter-sql = "gh-pages-a"
tree-sitter-hocon = "master-a"
+otel = "1.42.1"
#Tools
pmdTool = "6.55.0"
@@ -267,3 +268,5 @@ tree-sitter = { module = "io.github.bonede:tree-sitter",
version.ref = "tree-sit
tree-sitter-json = { module = "io.github.bonede:tree-sitter-json", version.ref
= "tree-sitter-json" }
tree-sitter-sql = { module = "io.github.bonede:tree-sitter-sql", version.ref =
"tree-sitter-sql" }
tree-sitter-hocon = { module = "io.github.bonede:tree-sitter-hocon",
version.ref = "tree-sitter-hocon" }
+
+opentelemetry-exporter-otlp = { module =
"io.opentelemetry:opentelemetry-exporter-otlp", version.ref = "otel" }
diff --git a/modules/metrics-exporter-otlp/build.gradle
b/modules/metrics-exporter-otlp/build.gradle
new file mode 100644
index 0000000000..29742e21d0
--- /dev/null
+++ b/modules/metrics-exporter-otlp/build.gradle
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+apply from: "$rootDir/buildscripts/java-core.gradle"
+apply from: "$rootDir/buildscripts/publishing.gradle"
+apply from: "$rootDir/buildscripts/java-junit5.gradle"
+
+dependencies {
+ annotationProcessor project(':ignite-configuration-annotation-processor')
+ annotationProcessor libs.auto.service
+
+ implementation project(':ignite-api')
+ implementation project(':ignite-core')
+ implementation project(':ignite-configuration')
+ implementation project(':ignite-configuration-root')
+ implementation project(':ignite-network')
+ implementation project(':ignite-metrics')
+ implementation libs.jetbrains.annotations
+ implementation libs.auto.service.annotations
+ implementation(libs.opentelemetry.exporter.otlp) {
+ // Exclude transitive dependency for exporting logs and traces.
+ exclude group: 'io.opentelemetry', module: 'opentelemetry-sdk-logs'
+ exclude group: 'io.opentelemetry', module: 'opentelemetry-sdk-trace'
+ }
+
+ testAnnotationProcessor
project(':ignite-configuration-annotation-processor')
+
+ testImplementation project(':ignite-configuration')
+ testImplementation testFixtures(project(':ignite-core'))
+ testImplementation testFixtures(project(':ignite-configuration'))
+ testImplementation libs.hamcrest.core
+ testImplementation libs.mockito.core
+ testImplementation libs.mockito.junit
+ testImplementation libs.awaitility
+}
+
+description = 'ignite-metrics-exporter-otlp'
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/HeadersConfigurationSchema.java
similarity index 68%
copy from
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
copy to
modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/HeadersConfigurationSchema.java
index 6e0b63046a..2d369c5f63 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/HeadersConfigurationSchema.java
@@ -17,15 +17,22 @@
package org.apache.ignite.internal.metrics.exporters.configuration;
-import org.apache.ignite.configuration.annotation.PolymorphicConfigInstance;
+import org.apache.ignite.configuration.annotation.Config;
+import org.apache.ignite.configuration.annotation.InjectedName;
import org.apache.ignite.configuration.annotation.Value;
-import org.apache.ignite.internal.metrics.exporters.log.LogPushExporter;
+import org.apache.ignite.configuration.validation.NotBlank;
/**
- * Configuration for log push exporter.
+ * Connection headers configuration schema.
*/
-@PolymorphicConfigInstance(LogPushExporter.EXPORTER_NAME)
-public class LogPushExporterConfigurationSchema extends
ExporterConfigurationSchema {
- @Value(hasDefault = true)
- public int period = 30_000;
+@Config
+public class HeadersConfigurationSchema {
+ /** Name of the header. */
+ @InjectedName
+ public String name;
+
+ /** Header value. */
+ @NotBlank
+ @Value
+ public String header;
}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/OtlpExporterConfigurationModule.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/OtlpExporterConfigurationModule.java
new file mode 100644
index 0000000000..27eb722084
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/OtlpExporterConfigurationModule.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.configuration;
+
+import com.google.auto.service.AutoService;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import org.apache.ignite.configuration.ConfigurationModule;
+import org.apache.ignite.configuration.annotation.ConfigurationType;
+import org.apache.ignite.configuration.validation.Validator;
+import
org.apache.ignite.internal.metrics.exporters.validator.EndpointValidatorImpl;
+
+/**
+ * {@link ConfigurationModule} for cluster-wide configuration provided by
metrics-exporter-otlp.
+ */
+@AutoService(ConfigurationModule.class)
+public class OtlpExporterConfigurationModule implements ConfigurationModule {
+ @Override
+ public ConfigurationType type() {
+ return ConfigurationType.DISTRIBUTED;
+ }
+
+ @Override
+ public Set<Validator<?, ?>> validators() {
+ return Set.of(EndpointValidatorImpl.INSTANCE);
+ }
+
+ @Override
+ public Collection<Class<?>> polymorphicSchemaExtensions() {
+ return List.of(
+ OtlpExporterConfigurationSchema.class
+ );
+ }
+}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/OtlpExporterConfigurationSchema.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/OtlpExporterConfigurationSchema.java
new file mode 100644
index 0000000000..8b764c7a26
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/OtlpExporterConfigurationSchema.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.configuration;
+
+import static
io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC;
+import static
io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
+
+import org.apache.ignite.configuration.annotation.ConfigValue;
+import org.apache.ignite.configuration.annotation.NamedConfigValue;
+import org.apache.ignite.configuration.annotation.PolymorphicConfigInstance;
+import org.apache.ignite.configuration.annotation.Value;
+import org.apache.ignite.configuration.validation.OneOf;
+import
org.apache.ignite.internal.metrics.exporters.otlp.OtlpPushMetricExporter;
+import
org.apache.ignite.internal.metrics.exporters.validator.EndpointValidator;
+import org.apache.ignite.internal.network.configuration.SslConfigurationSchema;
+import
org.apache.ignite.internal.network.configuration.SslConfigurationValidator;
+
+/**
+ * Configuration for OTLP push exporter.
+ */
+@PolymorphicConfigInstance(OtlpPushMetricExporter.EXPORTER_NAME)
+public class OtlpExporterConfigurationSchema extends
ExporterConfigurationSchema {
+ /** Export period, in milliseconds. */
+ @Value(hasDefault = true)
+ public long period = 30_000;
+
+ /** String in "host:port" format. */
+ @Value
+ @EndpointValidator
+ public String endpoint;
+
+ /** OTLP protocol. */
+ @OneOf({PROTOCOL_GRPC, PROTOCOL_HTTP_PROTOBUF})
+ @Value(hasDefault = true)
+ public String protocol = PROTOCOL_GRPC;
+
+ /** Connection headers configuration schema. */
+ @NamedConfigValue
+ public HeadersConfigurationSchema headers;
+
+ /** SSL configuration schema. */
+ @ConfigValue
+ @SslConfigurationValidator
+ public SslConfigurationSchema ssl;
+
+ /** Method used to compress payloads. */
+ @OneOf({"none", "gzip"})
+ @Value(hasDefault = true)
+ public String compression = "gzip";
+}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteDistributionMetricData.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteDistributionMetricData.java
new file mode 100644
index 0000000000..e23c230742
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteDistributionMetricData.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.otlp;
+
+import static io.opentelemetry.sdk.metrics.data.MetricDataType.HISTOGRAM;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+
+import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
+import io.opentelemetry.sdk.internal.PrimitiveLongList;
+import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
+import io.opentelemetry.sdk.metrics.data.Data;
+import io.opentelemetry.sdk.metrics.data.DoubleExemplarData;
+import io.opentelemetry.sdk.metrics.data.HistogramData;
+import io.opentelemetry.sdk.metrics.data.HistogramPointData;
+import io.opentelemetry.sdk.metrics.data.MetricDataType;
+import io.opentelemetry.sdk.resources.Resource;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+
+/**
+ * Metric data that holds distribution metric.
+ */
+class IgniteDistributionMetricData extends
IgniteMetricData<DistributionMetric> {
+ private final HistogramData data;
+
+ IgniteDistributionMetricData(Resource resource, InstrumentationScopeInfo
scope, DistributionMetric metric) {
+ super(resource, scope, metric);
+
+ data = new IgniteHistogramData(new
IgniteDistributionPointData(metric));
+ }
+
+ @Override
+ public MetricDataType getType() {
+ return HISTOGRAM;
+ }
+
+ @Override
+ public Data<?> getData() {
+ return data;
+ }
+
+ static class IgniteHistogramData implements HistogramData {
+ private final Collection<HistogramPointData> points;
+
+ IgniteHistogramData(HistogramPointData data) {
+ points = singletonList(data);
+ }
+
+ @Override
+ public AggregationTemporality getAggregationTemporality() {
+ return AggregationTemporality.CUMULATIVE;
+ }
+
+ @Override
+ public Collection<HistogramPointData> getPoints() {
+ return points;
+ }
+ }
+
+ static class IgniteDistributionPointData extends IgnitePointData
implements HistogramPointData {
+ private final DistributionMetric metric;
+
+ private final List<Double> boundaries;
+
+ IgniteDistributionPointData(DistributionMetric metric) {
+ this.metric = metric;
+
+ boundaries = asDoubleList(metric.bounds());
+ }
+
+ @Override
+ public double getSum() {
+ return Double.NaN;
+ }
+
+ @Override
+ public long getCount() {
+ long totalCount = 0;
+
+ for (long c : metric.value()) {
+ totalCount += c;
+ }
+
+ return totalCount;
+ }
+
+ @Override
+ public boolean hasMin() {
+ return false;
+ }
+
+ @Override
+ public double getMin() {
+ return Double.NaN;
+ }
+
+ @Override
+ public boolean hasMax() {
+ return false;
+ }
+
+ @Override
+ public double getMax() {
+ return Double.NaN;
+ }
+
+ @Override
+ public List<Double> getBoundaries() {
+ return boundaries;
+ }
+
+ @Override
+ public List<Long> getCounts() {
+ return PrimitiveLongList.wrap(metric.value());
+ }
+
+ @Override
+ public List<DoubleExemplarData> getExemplars() {
+ return emptyList();
+ }
+
+ private static List<Double> asDoubleList(long[] array) {
+ ArrayList<Double> result = new ArrayList<>(array.length);
+
+ for (long el : array) {
+ result.add((double) el);
+ }
+
+ return result;
+ }
+ }
+}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteDoubleMetricData.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteDoubleMetricData.java
new file mode 100644
index 0000000000..b318e661d3
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteDoubleMetricData.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.otlp;
+
+import static io.opentelemetry.sdk.metrics.data.MetricDataType.DOUBLE_GAUGE;
+import static java.util.Collections.emptyList;
+
+import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
+import io.opentelemetry.sdk.metrics.data.Data;
+import io.opentelemetry.sdk.metrics.data.DoubleExemplarData;
+import io.opentelemetry.sdk.metrics.data.DoublePointData;
+import io.opentelemetry.sdk.metrics.data.MetricDataType;
+import io.opentelemetry.sdk.resources.Resource;
+import java.util.List;
+import org.apache.ignite.internal.metrics.DoubleMetric;
+
+/**
+ * Metric data that holds double metric.
+ */
+class IgniteDoubleMetricData extends IgniteMetricData<DoubleMetric> {
+ private final Data<IgniteDoublePointData> data;
+
+ IgniteDoubleMetricData(Resource resource, InstrumentationScopeInfo scope,
DoubleMetric metric) {
+ super(resource, scope, metric);
+
+ data = new IgniteGaugeData<>(new IgniteDoublePointData(metric));
+ }
+
+ @Override
+ public MetricDataType getType() {
+ return DOUBLE_GAUGE;
+ }
+
+ @Override
+ public Data<?> getData() {
+ return data;
+ }
+
+ private static class IgniteDoublePointData extends IgnitePointData
implements DoublePointData {
+ private final DoubleMetric metric;
+
+ IgniteDoublePointData(DoubleMetric metric) {
+ this.metric = metric;
+ }
+
+ @Override
+ public double getValue() {
+ return metric.value();
+ }
+
+ @Override
+ public List<DoubleExemplarData> getExemplars() {
+ return emptyList();
+ }
+ }
+}
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteGaugeData.java
similarity index 57%
copy from
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
copy to
modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteGaugeData.java
index 6e0b63046a..c6847e15ee 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteGaugeData.java
@@ -15,17 +15,28 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.metrics.exporters.configuration;
+package org.apache.ignite.internal.metrics.exporters.otlp;
-import org.apache.ignite.configuration.annotation.PolymorphicConfigInstance;
-import org.apache.ignite.configuration.annotation.Value;
-import org.apache.ignite.internal.metrics.exporters.log.LogPushExporter;
+import static java.util.Collections.singletonList;
+
+import io.opentelemetry.sdk.metrics.data.GaugeData;
+import io.opentelemetry.sdk.metrics.data.PointData;
+import java.util.Collection;
/**
- * Configuration for log push exporter.
+ * Wrapper over data point that returns it as a list.
+ *
+ * @param <T> Data point type.
*/
-@PolymorphicConfigInstance(LogPushExporter.EXPORTER_NAME)
-public class LogPushExporterConfigurationSchema extends
ExporterConfigurationSchema {
- @Value(hasDefault = true)
- public int period = 30_000;
+class IgniteGaugeData<T extends PointData> implements GaugeData<T> {
+ private final Collection<T> points;
+
+ IgniteGaugeData(T data) {
+ points = singletonList(data);
+ }
+
+ @Override
+ public Collection<T> getPoints() {
+ return points;
+ }
}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteIntMetricData.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteIntMetricData.java
new file mode 100644
index 0000000000..ca0ad1a7a6
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteIntMetricData.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.otlp;
+
+import static io.opentelemetry.sdk.metrics.data.MetricDataType.LONG_GAUGE;
+import static java.util.Collections.emptyList;
+
+import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
+import io.opentelemetry.sdk.metrics.data.Data;
+import io.opentelemetry.sdk.metrics.data.LongExemplarData;
+import io.opentelemetry.sdk.metrics.data.LongPointData;
+import io.opentelemetry.sdk.metrics.data.MetricDataType;
+import io.opentelemetry.sdk.resources.Resource;
+import java.util.List;
+import org.apache.ignite.internal.metrics.IntMetric;
+
+/**
+ * Metric data that holds int metric.
+ */
+class IgniteIntMetricData extends IgniteMetricData<IntMetric> {
+ private final Data<IgniteIntPointData> data;
+
+ IgniteIntMetricData(Resource resource, InstrumentationScopeInfo scope,
IntMetric metric) {
+ super(resource, scope, metric);
+
+ this.data = new IgniteGaugeData<>(new IgniteIntPointData(metric));
+ }
+
+ @Override
+ public MetricDataType getType() {
+ return LONG_GAUGE;
+ }
+
+ @Override
+ public Data<?> getData() {
+ return data;
+ }
+
+ private static class IgniteIntPointData extends IgnitePointData implements
LongPointData {
+ private final IntMetric metric;
+
+ IgniteIntPointData(IntMetric metric) {
+ this.metric = metric;
+ }
+
+ @Override
+ public long getValue() {
+ return metric.value();
+ }
+
+ @Override
+ public List<LongExemplarData> getExemplars() {
+ return emptyList();
+ }
+ }
+}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteLongMetricData.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteLongMetricData.java
new file mode 100644
index 0000000000..781d840e53
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteLongMetricData.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.otlp;
+
+import static io.opentelemetry.sdk.metrics.data.MetricDataType.LONG_GAUGE;
+import static java.util.Collections.emptyList;
+
+import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
+import io.opentelemetry.sdk.metrics.data.Data;
+import io.opentelemetry.sdk.metrics.data.LongExemplarData;
+import io.opentelemetry.sdk.metrics.data.LongPointData;
+import io.opentelemetry.sdk.metrics.data.MetricDataType;
+import io.opentelemetry.sdk.resources.Resource;
+import java.util.List;
+import org.apache.ignite.internal.metrics.LongMetric;
+
+/**
+ * Metric data that holds long metric.
+ */
+class IgniteLongMetricData extends IgniteMetricData<LongMetric> {
+ private final Data<IgniteLongPointData> data;
+
+ IgniteLongMetricData(Resource resource, InstrumentationScopeInfo scope,
LongMetric metric) {
+ super(resource, scope, metric);
+
+ this.data = new IgniteGaugeData<>(new IgniteLongPointData(metric));
+ }
+
+ @Override
+ public MetricDataType getType() {
+ return LONG_GAUGE;
+ }
+
+ @Override
+ public Data<?> getData() {
+ return data;
+ }
+
+ private static class IgniteLongPointData extends IgnitePointData
implements LongPointData {
+ private final LongMetric metric;
+
+ IgniteLongPointData(LongMetric metric) {
+ this.metric = metric;
+ }
+
+ @Override
+ public long getValue() {
+ return metric.value();
+ }
+
+ @Override
+ public List<LongExemplarData> getExemplars() {
+ return emptyList();
+ }
+ }
+}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteMetricData.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteMetricData.java
new file mode 100644
index 0000000000..ca7e360869
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgniteMetricData.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.otlp;
+
+import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
+import io.opentelemetry.sdk.metrics.data.MetricData;
+import io.opentelemetry.sdk.resources.Resource;
+import java.util.Objects;
+import org.apache.ignite.internal.metrics.Metric;
+
+/**
+ * Metric data represents the aggregated measurements of an instrument.
+ *
+ * @param <T> A type of the metric.
+ */
+abstract class IgniteMetricData<T extends Metric> implements MetricData {
+ private final Resource resource;
+ private final InstrumentationScopeInfo scope;
+ private final T metric;
+
+ IgniteMetricData(Resource resource, InstrumentationScopeInfo scope, T
metric) {
+ this.resource = resource;
+ this.scope = scope;
+ this.metric = metric;
+ }
+
+ @Override
+ public Resource getResource() {
+ return resource;
+ }
+
+ @Override
+ public InstrumentationScopeInfo getInstrumentationScopeInfo() {
+ return scope;
+ }
+
+ @Override
+ public String getName() {
+ return metric.name();
+ }
+
+ @Override
+ public String getDescription() {
+ // Can't be null.
+ return Objects.requireNonNull(metric.description(), "");
+ }
+
+ @Override
+ public String getUnit() {
+ // Can't be null.
+ return "";
+ }
+}
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgnitePointData.java
similarity index 57%
copy from
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
copy to
modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgnitePointData.java
index 6e0b63046a..67ef395be8 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/IgnitePointData.java
@@ -15,17 +15,28 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.metrics.exporters.configuration;
+package org.apache.ignite.internal.metrics.exporters.otlp;
-import org.apache.ignite.configuration.annotation.PolymorphicConfigInstance;
-import org.apache.ignite.configuration.annotation.Value;
-import org.apache.ignite.internal.metrics.exporters.log.LogPushExporter;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.sdk.common.Clock;
+import io.opentelemetry.sdk.metrics.data.PointData;
/**
- * Configuration for log push exporter.
+ * Base class for a point in the metric data model.
*/
-@PolymorphicConfigInstance(LogPushExporter.EXPORTER_NAME)
-public class LogPushExporterConfigurationSchema extends
ExporterConfigurationSchema {
- @Value(hasDefault = true)
- public int period = 30_000;
+abstract class IgnitePointData implements PointData {
+ @Override
+ public long getStartEpochNanos() {
+ return Clock.getDefault().now();
+ }
+
+ @Override
+ public long getEpochNanos() {
+ return Clock.getDefault().now();
+ }
+
+ @Override
+ public Attributes getAttributes() {
+ return Attributes.empty();
+ }
}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/MetricReporter.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/MetricReporter.java
new file mode 100644
index 0000000000..e20ac3468e
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/MetricReporter.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.otlp;
+
+import static
io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC;
+import static
io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
+import static io.opentelemetry.sdk.common.export.MemoryMode.REUSABLE_DATA;
+import static org.apache.ignite.internal.util.StringUtils.nullOrBlank;
+
+import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
+import
io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder;
+import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
+import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
+import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
+import io.opentelemetry.sdk.metrics.data.MetricData;
+import io.opentelemetry.sdk.metrics.export.MetricExporter;
+import io.opentelemetry.sdk.resources.Resource;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.NoSuchFileException;
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import org.apache.ignite.configuration.NamedListView;
+import org.apache.ignite.internal.logger.IgniteLogger;
+import org.apache.ignite.internal.logger.Loggers;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.metrics.DoubleMetric;
+import org.apache.ignite.internal.metrics.IntMetric;
+import org.apache.ignite.internal.metrics.LongMetric;
+import org.apache.ignite.internal.metrics.Metric;
+import org.apache.ignite.internal.metrics.MetricSet;
+import org.apache.ignite.internal.metrics.exporters.configuration.HeadersView;
+import
org.apache.ignite.internal.metrics.exporters.configuration.OtlpExporterView;
+import org.apache.ignite.internal.network.configuration.SslView;
+import org.apache.ignite.internal.network.ssl.KeystoreLoader;
+import org.apache.ignite.lang.ErrorGroups.Common;
+import org.apache.ignite.lang.IgniteException;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * A reporter which outputs measurements to a {@link MetricExporter}.
+ */
+class MetricReporter implements AutoCloseable {
+ private static final IgniteLogger LOG =
Loggers.forClass(MetricReporter.class);
+
+ private final Collection<MetricData> metrics = new
CopyOnWriteArrayList<>();
+ private final Resource resource;
+
+ private MetricExporter exporter;
+
+ MetricReporter(OtlpExporterView view, String clusterId, String nodeName) {
+ this.exporter = createExporter(view);
+
+ this.resource = Resource.builder()
+ .put("service.name", clusterId)
+ .put("service.instance.id", nodeName)
+ .build();
+ }
+
+ void addMetricSet(MetricSet metricSet) {
+ Collection<MetricData> metrics0 = new ArrayList<>();
+
+ InstrumentationScopeInfo scope =
InstrumentationScopeInfo.builder(metricSet.name())
+ .build();
+
+ for (Metric metric : metricSet) {
+ MetricData metricData = toMetricData(resource, scope, metric);
+
+ if (metricData != null) {
+ metrics0.add(metricData);
+ }
+ }
+
+ metrics.addAll(metrics0);
+ }
+
+ void removeMetricSet(String metricSetName) {
+ metrics.removeIf(metricData ->
metricSetName.equals(metricData.getName()));
+ }
+
+ void report() {
+ exporter.export(metrics);
+ }
+
+ @Override
+ public void close() throws Exception {
+ exporter.close();
+ }
+
+ @TestOnly
+ void exporter(MetricExporter exporter) {
+ this.exporter = exporter;
+ }
+
+
+ private static Supplier<Map<String, String>> headers(NamedListView<?
extends HeadersView> headers) {
+ return () ->
headers.stream().collect(Collectors.toUnmodifiableMap(HeadersView::name,
HeadersView::header));
+ }
+
+ /** Create client SSL context. */
+ private static TrustManagerFactory createTrustManagerFactory(SslView ssl) {
+ try {
+ TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ trustManagerFactory.init(KeystoreLoader.load(ssl.trustStore()));
+
+ return trustManagerFactory;
+ } catch (IOException | GeneralSecurityException e) {
+ throw new IgniteException(Common.SSL_CONFIGURATION_ERR, e);
+ }
+ }
+
+ /** Create client SSL context. */
+ private static SSLContext createClientSslContext(SslView ssl,
TrustManagerFactory trustManagerFactory) {
+ try {
+ KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(KeystoreLoader.load(ssl.keyStore()),
ssl.keyStore().password().toCharArray());
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagerFactory.getKeyManagers(),
trustManagerFactory.getTrustManagers(), new SecureRandom());
+
+ return sslContext;
+ } catch (NoSuchFileException e) {
+ throw new IgniteException(Common.SSL_CONFIGURATION_ERR,
String.format("File %s not found", e.getMessage()), e);
+ } catch (IOException | GeneralSecurityException e) {
+ throw new IgniteException(Common.SSL_CONFIGURATION_ERR, e);
+ }
+ }
+
+ private static String createEndpoint(OtlpExporterView view) {
+ URI uri = URI.create(view.endpoint());
+ StringBuilder sb = new StringBuilder();
+
+ if (view.protocol().equals(PROTOCOL_HTTP_PROTOBUF)) {
+ String basePath = uri.getPath();
+
+ if (!nullOrBlank(basePath)) {
+ sb.append(basePath);
+ }
+
+ if (!basePath.endsWith("v1/metrics")) {
+ if (!basePath.endsWith("/")) {
+ sb.append('/');
+ }
+
+ sb.append("v1/metrics");
+ }
+ } else {
+ sb.append('/');
+ }
+
+ try {
+ return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(),
uri.getPort(), sb.toString(), null, null).toString();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Unexpected exception creating URL.",
e);
+ }
+ }
+
+ private static MetricExporter createExporter(OtlpExporterView view) {
+ if (view.protocol().equals(PROTOCOL_GRPC)) {
+ OtlpGrpcMetricExporterBuilder builder =
OtlpGrpcMetricExporter.builder()
+ .setEndpoint(createEndpoint(view))
+ .setHeaders(headers(view.headers()))
+ .setCompression(view.compression())
+ .setMemoryMode(REUSABLE_DATA);
+
+ SslView sslView = view.ssl();
+
+ if (sslView.enabled()) {
+ TrustManagerFactory trustManagerFactory =
createTrustManagerFactory(sslView);
+ X509TrustManager trustManager = (X509TrustManager)
trustManagerFactory.getTrustManagers()[0];
+
+ builder.setSslContext(createClientSslContext(sslView,
trustManagerFactory), trustManager);
+ }
+
+ return builder.build();
+ }
+
+ OtlpHttpMetricExporterBuilder builder =
OtlpHttpMetricExporter.builder()
+ .setEndpoint(createEndpoint(view))
+ .setHeaders(headers(view.headers()))
+ .setCompression(view.compression())
+ .setMemoryMode(REUSABLE_DATA);
+
+ SslView sslView = view.ssl();
+
+ if (sslView.enabled()) {
+ TrustManagerFactory trustManagerFactory =
createTrustManagerFactory(sslView);
+ X509TrustManager trustManager = (X509TrustManager)
trustManagerFactory.getTrustManagers()[0];
+
+ builder.setSslContext(createClientSslContext(sslView,
trustManagerFactory), trustManager);
+ }
+
+ return builder.build();
+ }
+
+ private static @Nullable MetricData toMetricData(Resource resource,
InstrumentationScopeInfo scope, Metric metric) {
+ if (metric instanceof IntMetric) {
+ return new IgniteIntMetricData(resource, scope, (IntMetric)
metric);
+ }
+
+ if (metric instanceof LongMetric) {
+ return new IgniteLongMetricData(resource, scope, (LongMetric)
metric);
+ }
+
+ if (metric instanceof DoubleMetric) {
+ return new IgniteDoubleMetricData(resource, scope, (DoubleMetric)
metric);
+ }
+
+ if (metric instanceof DistributionMetric) {
+ return new IgniteDistributionMetricData(resource, scope,
(DistributionMetric) metric);
+ }
+
+ LOG.debug("Unknown metric class for export " + metric.getClass());
+
+ return null;
+ }
+}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporter.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporter.java
new file mode 100644
index 0000000000..16927cc600
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporter.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.otlp;
+
+import com.google.auto.service.AutoService;
+import java.util.UUID;
+import java.util.function.Supplier;
+import org.apache.ignite.internal.metrics.MetricProvider;
+import org.apache.ignite.internal.metrics.MetricSet;
+import org.apache.ignite.internal.metrics.exporters.MetricExporter;
+import org.apache.ignite.internal.metrics.exporters.PushMetricExporter;
+import
org.apache.ignite.internal.metrics.exporters.configuration.OtlpExporterView;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Otlp(OpenTelemetry) metrics exporter.
+ */
+@AutoService(MetricExporter.class)
+public class OtlpPushMetricExporter extends
PushMetricExporter<OtlpExporterView> {
+ public static final String EXPORTER_NAME = "otlp";
+
+ private volatile @Nullable MetricReporter reporter;
+
+ @Override
+ public synchronized void start(MetricProvider metricsProvider,
OtlpExporterView view, Supplier<UUID> clusterIdSupplier,
+ String nodeName) {
+ MetricReporter reporter0 = new MetricReporter(view,
clusterIdSupplier.get().toString(), nodeName);
+
+ for (MetricSet metricSet :
metricsProvider.metrics().getKey().values()) {
+ reporter0.addMetricSet(metricSet);
+ }
+
+ reporter = reporter0;
+
+ super.start(metricsProvider, view, clusterIdSupplier, nodeName);
+ }
+
+ @Override
+ public synchronized void stop() {
+ super.stop();
+
+ try {
+ IgniteUtils.closeAll(reporter);
+ } catch (Exception e) {
+ log.error("Failed to stop metric exporter: " + name(), e);
+ }
+
+ reporter = null;
+ }
+
+ @Override
+ public synchronized void reconfigure(OtlpExporterView newVal) {
+ super.reconfigure(newVal);
+
+ reporter = new MetricReporter(newVal, clusterId().toString(),
nodeName());
+ }
+
+ @Override
+ public void addMetricSet(MetricSet metricSet) {
+ MetricReporter reporter0 = reporter;
+
+ assert reporter0 != null;
+
+ reporter0.addMetricSet(metricSet);
+ }
+
+ @Override
+ public void removeMetricSet(String metricSetName) {
+ MetricReporter reporter0 = reporter;
+
+ assert reporter0 != null;
+
+ reporter0.removeMetricSet(metricSetName);
+ }
+
+ @Override
+ protected long period() {
+ return configuration().period();
+ }
+
+ @Override
+ public void report() {
+ MetricReporter reporter0 = reporter;
+
+ assert reporter0 != null;
+
+ reporter0.report();
+ }
+
+ @Override
+ public String name() {
+ return EXPORTER_NAME;
+ }
+
+ @TestOnly
+ @Nullable MetricReporter reporter() {
+ return reporter;
+ }
+}
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidator.java
similarity index 60%
copy from
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
copy to
modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidator.java
index 6e0b63046a..eab1aa7c1b 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidator.java
@@ -15,17 +15,18 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.metrics.exporters.configuration;
+package org.apache.ignite.internal.metrics.exporters.validator;
-import org.apache.ignite.configuration.annotation.PolymorphicConfigInstance;
-import org.apache.ignite.configuration.annotation.Value;
-import org.apache.ignite.internal.metrics.exporters.log.LogPushExporter;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
/**
- * Configuration for log push exporter.
+ * Annotation to validate endpoint.
*/
-@PolymorphicConfigInstance(LogPushExporter.EXPORTER_NAME)
-public class LogPushExporterConfigurationSchema extends
ExporterConfigurationSchema {
- @Value(hasDefault = true)
- public int period = 30_000;
+@Target(FIELD)
+@Retention(RUNTIME)
+public @interface EndpointValidator {
}
diff --git
a/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidatorImpl.java
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidatorImpl.java
new file mode 100644
index 0000000000..dc2b1f567a
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/main/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidatorImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.validator;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.apache.ignite.configuration.validation.ValidationContext;
+import org.apache.ignite.configuration.validation.ValidationIssue;
+import org.apache.ignite.configuration.validation.Validator;
+
+/** Implementation of the {@link EndpointValidator}. */
+public class EndpointValidatorImpl implements Validator<EndpointValidator,
String> {
+ public static final EndpointValidatorImpl INSTANCE = new
EndpointValidatorImpl();
+
+ @Override
+ public void validate(EndpointValidator annotation,
ValidationContext<String> ctx) {
+ String endpoint = ctx.getNewValue();
+
+ try {
+ URL endpointUrl = new URL(endpoint);
+
+ if (!"http".equalsIgnoreCase(endpointUrl.getProtocol()) &&
!"https".equalsIgnoreCase(endpointUrl.getProtocol())) {
+ ctx.addIssue(new ValidationIssue(ctx.currentKey(), "Endpoint
scheme must be http or https: " + endpointUrl.getProtocol()));
+ }
+
+ if (endpointUrl.getQuery() != null) {
+ ctx.addIssue(new ValidationIssue(ctx.currentKey(), "Endpoint
must not have a query string: " + endpointUrl.getQuery()));
+ }
+
+ if (endpointUrl.getRef() != null) {
+ ctx.addIssue(new ValidationIssue(ctx.currentKey(), "Endpoint
must not have a fragment: " + endpointUrl.getRef()));
+ }
+ } catch (MalformedURLException e) {
+ ctx.addIssue(new ValidationIssue(ctx.currentKey(), "Endpoint must
be a valid URL: " + endpoint));
+ }
+ }
+}
diff --git
a/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
b/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
new file mode 100644
index 0000000000..3d6db8672d
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.otlp;
+
+import static io.opentelemetry.api.common.AttributeType.STRING;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import io.opentelemetry.api.internal.InternalAttributeKeyImpl;
+import io.opentelemetry.sdk.common.CompletableResultCode;
+import io.opentelemetry.sdk.metrics.data.HistogramPointData;
+import io.opentelemetry.sdk.metrics.data.MetricData;
+import io.opentelemetry.sdk.metrics.export.MetricExporter;
+import io.opentelemetry.sdk.resources.Resource;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
+import
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
+import org.apache.ignite.internal.lang.IgniteBiTuple;
+import org.apache.ignite.internal.metrics.AtomicDoubleMetric;
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.AtomicLongMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.metrics.DoubleAdderMetric;
+import org.apache.ignite.internal.metrics.DoubleGauge;
+import org.apache.ignite.internal.metrics.DoubleMetric;
+import org.apache.ignite.internal.metrics.HitRateMetric;
+import org.apache.ignite.internal.metrics.IntGauge;
+import org.apache.ignite.internal.metrics.IntMetric;
+import org.apache.ignite.internal.metrics.LongAdderMetric;
+import org.apache.ignite.internal.metrics.LongGauge;
+import org.apache.ignite.internal.metrics.LongMetric;
+import org.apache.ignite.internal.metrics.Metric;
+import org.apache.ignite.internal.metrics.MetricProvider;
+import org.apache.ignite.internal.metrics.MetricSet;
+import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
+import
org.apache.ignite.internal.metrics.exporters.configuration.OtlpExporterView;
+import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.apache.ignite.internal.util.CollectionUtils;
+import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(ConfigurationExtension.class)
+@ExtendWith(MockitoExtension.class)
+class OtlpPushMetricExporterTest extends BaseIgniteAbstractTest {
+ @InjectConfiguration("mock.exporters = {otlp = {exporterName = otlp,
period = 10000000, endpoint = \"http://localhost:4317\"}}")
+ private MetricConfiguration metricConfiguration;
+
+ private static final UUID CLUSTER_ID = UUID.randomUUID();
+
+ private static final String SRC_NAME = "testSource";
+
+ /** Metric set with all available metric types. */
+ private static final MetricSet metricSet =
+ new MetricSet(
+ SRC_NAME,
+ Map.of(
+ "intGauge", new IntGauge("intGauge", "", () -> 1),
+ "longGauge", new LongGauge("longGauge", "", () ->
1L),
+ "doubleGauge", new DoubleGauge("doubleGauge", "",
() -> 1d),
+ "atomicInt", new AtomicIntMetric("atomicInt", ""),
+ "atomicLong", new AtomicLongMetric("atomicLong",
""),
+ "atomicDouble", new
AtomicDoubleMetric("atomicDouble", ""),
+ "longAdder", new LongAdderMetric("longAdder", ""),
+ "doubleAdder", new
DoubleAdderMetric("doubleAdder", ""),
+ "distributionMetric", new
DistributionMetric("distributionMetric", "", new long[] {0, 1}),
+ "hitRate", new HitRateMetric("hitRate", "",
Long.MAX_VALUE)
+ )
+ );
+
+ private MetricProvider metricsProvider;
+
+ private MetricExporter metricsExporter;
+
+ private OtlpPushMetricExporter exporter;
+
+ @Captor
+ private ArgumentCaptor<Collection<MetricData>> metricsCaptor;
+
+ @BeforeEach
+ void setUp() {
+ OtlpExporterView exporterConf = (OtlpExporterView)
metricConfiguration.exporters().get("otlp").value();
+ metricsProvider = mock(MetricProvider.class);
+ Map<String, MetricSet> metrics = Map.of(metricSet.name(), metricSet);
+ when(metricsProvider.metrics()).thenReturn(new
IgniteBiTuple<>(metrics, 1L));
+
+ exporter = new OtlpPushMetricExporter();
+ exporter.start(metricsProvider, exporterConf, () -> CLUSTER_ID,
"nodeName");
+
+ metricsExporter = mock(MetricExporter.class);
+ exporter.reporter().exporter(metricsExporter);
+ }
+
+ @Test
+ public void testExport() {
+
when(metricsExporter.export(metricsCaptor.capture())).thenReturn(CompletableResultCode.ofSuccess());
+ exporter.report();
+
+
assertThatExportedMetricsAndMetricValuesAreTheSame(metricsCaptor.getValue());
+ }
+
+ /**
+ * Check, that all exported has the same values as original metric values.
+ */
+ private static void
assertThatExportedMetricsAndMetricValuesAreTheSame(Collection<MetricData>
metrics) {
+ for (Metric metric : metricSet) {
+ MetricData otlpMetric = metrics.stream().filter(m ->
m.getName().equals(metric.name())).findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("Failed to
find metric with name " + metric.name()));
+
+ Resource res = otlpMetric.getResource();
+
+ assertEquals(CLUSTER_ID.toString(),
res.getAttribute(InternalAttributeKeyImpl.create("service.name", STRING)));
+ assertEquals("nodeName",
res.getAttribute(InternalAttributeKeyImpl.create("service.instance.id",
STRING)));
+
+ if (metric instanceof IntMetric) {
+ assertEquals(((IntMetric) metric).value(),
CollectionUtils.first(otlpMetric.getLongGaugeData().getPoints()).getValue());
+ } else if (metric instanceof LongMetric) {
+ assertEquals(((LongMetric) metric).value(),
CollectionUtils.first(otlpMetric.getLongGaugeData().getPoints()).getValue());
+ } else if (metric instanceof DoubleMetric) {
+ assertEquals(((DoubleMetric) metric).value(),
+
CollectionUtils.first(otlpMetric.getDoubleGaugeData().getPoints()).getValue());
+ } else if (metric instanceof DistributionMetric) {
+ @Nullable HistogramPointData point =
CollectionUtils.first(otlpMetric.getHistogramData().getPoints());
+
+ assertArrayEquals(
+ ((DistributionMetric) metric).bounds(),
+
point.getBoundaries().stream().mapToLong(Double::longValue).toArray()
+ );
+ assertArrayEquals(
+ ((DistributionMetric) metric).value(),
+
point.getCounts().stream().mapToLong(Long::longValue).toArray()
+ );
+ }
+ }
+ }
+}
diff --git
a/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidatorImplTest.java
b/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidatorImplTest.java
new file mode 100644
index 0000000000..b949f8ef3a
--- /dev/null
+++
b/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/validator/EndpointValidatorImplTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics.exporters.validator;
+
+import static
org.apache.ignite.internal.configuration.validation.TestValidationUtil.mockValidationContext;
+import static org.mockito.Mockito.mock;
+
+import org.apache.ignite.configuration.validation.ValidationContext;
+import
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
+import org.apache.ignite.internal.configuration.validation.TestValidationUtil;
+import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+/** Tests for {@link EndpointValidatorImpl}. */
+@ExtendWith(ConfigurationExtension.class)
+class EndpointValidatorImplTest extends BaseIgniteAbstractTest {
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "http://127.0.0.1:8080",
+ "http://127.0.0.1",
+ "http://host",
+ "http://host:8080",
+ "http://www.host.com",
+ "http://www.host.com:8080"
+ })
+ void validEndpointSuccess(String endpoint) {
+ validate(endpoint);
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "127.0.0.1:8080",
+ "127.0.0.1",
+ "host/v1/metrics",
+ "www.host.com",
+ })
+ void invalidEndpointFails(String endpoint) {
+ validate(endpoint, "Endpoint must be a valid URL");
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "ftp://127.0.0.1:8080",
+ "file://www.host.com"
+ })
+ void endpointWithUnexpectedSchemaFails(String endpoint) {
+ validate(endpoint, "Endpoint scheme must be http or https");
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "http://www.host.com/?s=1",
+ "https://www.host.com/?s=1"
+ })
+ void endpointWithQueryStringFails(String endpoint) {
+ validate(endpoint, "Endpoint must not have a query string");
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "http://www.host.com/v1/metrics#print",
+ "https://127.0.0.1:8080/#test"
+ })
+ void endpointWithFragmentFails(String endpoint) {
+ validate(endpoint, "Endpoint must not have a fragment");
+ }
+
+ private static void validate(String newValue) {
+ validate(newValue, (String[]) null);
+ }
+
+ private static void validate(String newValue, String @Nullable ...
errorMessagePrefixes) {
+ ValidationContext<String> ctx = mockValidationContext(
+ null,
+ newValue
+ );
+
+ TestValidationUtil.validate(
+ EndpointValidatorImpl.INSTANCE,
+ mock(EndpointValidator.class),
+ ctx,
+ errorMessagePrefixes
+ );
+ }
+}
diff --git
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
index 30f2d3ae50..9e55bde12d 100644
---
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
+++
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
import
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
import org.apache.ignite.internal.manager.ComponentContext;
@@ -54,7 +55,7 @@ public class ItJvmMetricSourceTest extends
BaseIgniteAbstractTest {
public void testMemoryUsageMetric() {
MetricManager metricManager = new MetricManagerImpl();
- metricManager.configure(simpleConfiguration);
+ metricManager.configure(simpleConfiguration, UUID::randomUUID,
"test-node");
Map<String, MetricExporter> exporters = new HashMap<>();
diff --git
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItMetricExportersLoadingTest.java
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItMetricExportersLoadingTest.java
index c6986efcca..c3578a072d 100644
---
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItMetricExportersLoadingTest.java
+++
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItMetricExportersLoadingTest.java
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
+import java.util.UUID;
import java.util.concurrent.locks.LockSupport;
import
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
import
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
@@ -56,7 +57,7 @@ public class ItMetricExportersLoadingTest extends
BaseIgniteAbstractTest {
public void test() throws Exception {
MetricManager metricManager = new MetricManagerImpl();
- metricManager.configure(metricConfiguration);
+ metricManager.configure(metricConfiguration, UUID::randomUUID,
"test-node");
TestMetricsSource src = new TestMetricsSource("TestMetricsSource");
diff --git
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItOsMetricSourceTest.java
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItOsMetricSourceTest.java
index 3543a4697f..f2b6918e47 100644
---
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItOsMetricSourceTest.java
+++
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItOsMetricSourceTest.java
@@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.greaterThan;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
import
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
import org.apache.ignite.internal.manager.ComponentContext;
@@ -49,7 +50,7 @@ class ItOsMetricSourceTest extends BaseIgniteAbstractTest {
@Test
void testOsMetrics() {
MetricManager metricManager = new MetricManagerImpl();
- metricManager.configure(simpleConfiguration);
+ metricManager.configure(simpleConfiguration, UUID::randomUUID,
"test-node");
Map<String, MetricExporter> exporters = new HashMap<>();
TestSimpleExporter simpleExporter = new TestSimpleExporter();
diff --git
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestDoubleStartExporter.java
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestDoubleStartExporter.java
index a1c327c4d4..79edc4f4c6 100644
---
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestDoubleStartExporter.java
+++
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestDoubleStartExporter.java
@@ -21,7 +21,9 @@ import static java.util.Collections.emptyMap;
import com.google.auto.service.AutoService;
import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
import org.apache.ignite.internal.metrics.MetricProvider;
import org.apache.ignite.internal.metrics.MetricSet;
@@ -47,8 +49,9 @@ public class TestDoubleStartExporter extends
BasicMetricExporter<TestDoubleStart
}
@Override
- public void start(MetricProvider metricsProvider,
TestDoubleStartExporterView configuration) {
- super.start(metricsProvider, configuration);
+ public void start(MetricProvider metricsProvider,
TestDoubleStartExporterView configuration, Supplier<UUID> clusterIdSupplier,
+ String nodeName) {
+ super.start(metricsProvider, configuration, clusterIdSupplier,
nodeName);
START_COUNTER.incrementAndGet();
}
diff --git
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestPullMetricExporter.java
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestPullMetricExporter.java
index 316cf1008f..7fde93997d 100644
---
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestPullMetricExporter.java
+++
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestPullMetricExporter.java
@@ -21,8 +21,10 @@ import com.google.auto.service.AutoService;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
+import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.function.Supplier;
import org.apache.ignite.internal.metrics.Metric;
import org.apache.ignite.internal.metrics.MetricProvider;
import org.apache.ignite.internal.metrics.MetricSet;
@@ -55,8 +57,8 @@ public class TestPullMetricExporter extends
BasicMetricExporter<TestPullMetricsE
}
@Override
- public void start(MetricProvider metricProvider,
TestPullMetricsExporterView conf) {
- super.start(metricProvider, conf);
+ public void start(MetricProvider metricProvider,
TestPullMetricsExporterView conf, Supplier<UUID> clusterIdSupplier, String
nodeName) {
+ super.start(metricProvider, conf, clusterIdSupplier, nodeName);
executorService.execute(() -> {
while (true) {
diff --git
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestPushMetricExporter.java
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestPushMetricExporter.java
index 9309544d75..dd81a4ced7 100644
---
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestPushMetricExporter.java
+++
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestPushMetricExporter.java
@@ -21,6 +21,8 @@ import com.google.auto.service.AutoService;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
+import java.util.UUID;
+import java.util.function.Supplier;
import org.apache.ignite.internal.metrics.Metric;
import org.apache.ignite.internal.metrics.MetricProvider;
import org.apache.ignite.internal.metrics.MetricSet;
@@ -37,10 +39,11 @@ public class TestPushMetricExporter extends
PushMetricExporter<TestPushMetricsEx
private long period;
@Override
- public void start(MetricProvider metricsProvider,
TestPushMetricsExporterView configuration) {
+ public void start(MetricProvider metricsProvider,
TestPushMetricsExporterView configuration, Supplier<UUID> clusterIdSupplier,
+ String nodeName) {
period = configuration.period();
- super.start(metricsProvider, configuration);
+ super.start(metricsProvider, configuration, clusterIdSupplier,
nodeName);
}
public static void setOutputStream(OutputStream outputStream) {
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
index 07baf98ed7..337114a1ac 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
+++
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
@@ -19,6 +19,8 @@ package org.apache.ignite.internal.metrics;
import java.util.Collection;
import java.util.Map;
+import java.util.UUID;
+import java.util.function.Supplier;
import org.apache.ignite.internal.lang.IgniteBiTuple;
import org.apache.ignite.internal.manager.IgniteComponent;
import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
@@ -33,10 +35,12 @@ public interface MetricManager extends IgniteComponent {
* Method to configure {@link MetricManager} with distributed
configuration.
*
* @param metricConfiguration Distributed metric configuration.
+ * @param clusterIdSupplier Cluster ID supplier.
+ * @param nodeName Node name.
*/
// TODO: IGNITE-17718 when we design the system to configure metrics itself
// TODO: this method should be revisited, but now it is supposed to use
only to set distributed configuration for exporters.
- void configure(MetricConfiguration metricConfiguration);
+ void configure(MetricConfiguration metricConfiguration, Supplier<UUID>
clusterIdSupplier, String nodeName);
/**
* Start component.
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
index 9609010663..282462ec0c 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
+++
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
@@ -24,9 +24,11 @@ import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
+import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
import
org.apache.ignite.configuration.notifications.ConfigurationNamedListListener;
import
org.apache.ignite.configuration.notifications.ConfigurationNotificationEvent;
@@ -60,6 +62,10 @@ public class MetricManagerImpl implements MetricManager {
private MetricConfiguration metricConfiguration;
+ private Supplier<UUID> clusterIdSupplier;
+
+ private String nodeName;
+
/**
* Constructor.
*/
@@ -79,10 +85,14 @@ public class MetricManagerImpl implements MetricManager {
}
@Override
- public void configure(MetricConfiguration metricConfiguration) {
+ public void configure(MetricConfiguration metricConfiguration,
Supplier<UUID> clusterIdSupplier, String nodeName) {
assert this.metricConfiguration == null : "Metric manager must be
configured only once, on the start of the node";
+ assert this.clusterIdSupplier == null : "Metric manager must be
configured only once, on the start of the node";
+ assert this.nodeName == null : "Metric manager must be configured only
once, on the start of the node";
this.metricConfiguration = metricConfiguration;
+ this.clusterIdSupplier = clusterIdSupplier;
+ this.nodeName = nodeName;
}
@Override
@@ -111,7 +121,7 @@ public class MetricManagerImpl implements MetricManager {
this.availableExporters = new HashMap<>();
for (MetricExporter<?> exporter : exporters) {
- exporter.start(metricsProvider, null);
+ exporter.start(metricsProvider, null, clusterIdSupplier, nodeName);
availableExporters.put(exporter.name(), exporter);
enabledMetricExporters.put(exporter.name(), exporter);
@@ -197,7 +207,7 @@ public class MetricManagerImpl implements MetricManager {
if (exporter != null) {
enabledMetricExporters.computeIfAbsent(exporter.name(), name -> {
try {
- exporter.start(metricsProvider, exporterConfiguration);
+ exporter.start(metricsProvider, exporterConfiguration,
clusterIdSupplier, nodeName);
return exporter;
} catch (Exception e) {
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/BasicMetricExporter.java
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/BasicMetricExporter.java
index 0464484f15..a5cdb40fd8 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/BasicMetricExporter.java
+++
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/BasicMetricExporter.java
@@ -18,6 +18,8 @@
package org.apache.ignite.internal.metrics.exporters;
import java.util.Map;
+import java.util.UUID;
+import java.util.function.Supplier;
import org.apache.ignite.internal.lang.IgniteBiTuple;
import org.apache.ignite.internal.metrics.MetricProvider;
import org.apache.ignite.internal.metrics.MetricSet;
@@ -31,14 +33,20 @@ public abstract class BasicMetricExporter<CfgT extends
ExporterView> implements
/** Metrics provider. */
private MetricProvider metricsProvider;
+ private Supplier<UUID> clusterIdSupplier;
+
+ private String nodeName;
+
/** Exporter's configuration view. */
private CfgT configuration;
/** {@inheritDoc} */
@Override
- public void start(MetricProvider metricsProvider, CfgT configuration) {
+ public void start(MetricProvider metricsProvider, CfgT configuration,
Supplier<UUID> clusterIdSupplier, String nodeName) {
this.metricsProvider = metricsProvider;
this.configuration = configuration;
+ this.clusterIdSupplier = clusterIdSupplier;
+ this.nodeName = nodeName;
}
/** {@inheritDoc} */
@@ -64,4 +72,18 @@ public abstract class BasicMetricExporter<CfgT extends
ExporterView> implements
protected final IgniteBiTuple<Map<String, MetricSet>, Long> metrics() {
return metricsProvider.metrics();
}
+
+ /**
+ * Returns current cluster ID.
+ */
+ protected final UUID clusterId() {
+ return clusterIdSupplier.get();
+ }
+
+ /**
+ * Returns the network alias of the node.
+ */
+ protected final String nodeName() {
+ return nodeName;
+ }
}
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/MetricExporter.java
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/MetricExporter.java
index d93db1fd85..76c73a547d 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/MetricExporter.java
+++
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/MetricExporter.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.metrics.exporters;
+import java.util.UUID;
+import java.util.function.Supplier;
import org.apache.ignite.internal.metrics.MetricManagerImpl;
import org.apache.ignite.internal.metrics.MetricProvider;
import org.apache.ignite.internal.metrics.MetricSet;
@@ -39,8 +41,10 @@ public interface MetricExporter<CfgT extends ExporterView> {
*
* @param metricProvider Provider of metric sources.
* @param configuration Exporter configuration view.
+ * @param clusterIdSupplier Cluster ID supplier.
+ * @param nodeName Node name.
*/
- void start(MetricProvider metricProvider, CfgT configuration);
+ void start(MetricProvider metricProvider, CfgT configuration,
Supplier<UUID> clusterIdSupplier, String nodeName);
/**
* Stop and cleanup work for current exporter must be implemented here.
@@ -70,7 +74,9 @@ public interface MetricExporter<CfgT extends ExporterView> {
*
* @param metricSet Named metric set.
*/
- void addMetricSet(MetricSet metricSet);
+ default void addMetricSet(MetricSet metricSet) {
+ // No-op.
+ }
/**
* {@link MetricManagerImpl} invokes this method,
@@ -78,5 +84,7 @@ public interface MetricExporter<CfgT extends ExporterView> {
*
* @param metricSetName Name of metric set to remove.
*/
- void removeMetricSet(String metricSetName);
+ default void removeMetricSet(String metricSetName) {
+ // No-op.
+ }
}
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/PushMetricExporter.java
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/PushMetricExporter.java
index 71704e05be..6948f4b049 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/PushMetricExporter.java
+++
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/PushMetricExporter.java
@@ -17,10 +17,12 @@
package org.apache.ignite.internal.metrics.exporters;
+import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.logger.Loggers;
import org.apache.ignite.internal.metrics.MetricProvider;
@@ -45,8 +47,8 @@ public abstract class PushMetricExporter<CfgT extends
ExporterView> extends Basi
/** {@inheritDoc} */
@Override
- public synchronized void start(MetricProvider metricProvider, CfgT conf) {
- super.start(metricProvider, conf);
+ public synchronized void start(MetricProvider metricProvider, CfgT conf,
Supplier<UUID> clusterIdSupplier, String nodeName) {
+ super.start(metricProvider, conf, clusterIdSupplier, nodeName);
scheduler =
Executors.newSingleThreadScheduledExecutor(new
NamedThreadFactory("metrics-exporter-" + name(), log));
@@ -61,7 +63,6 @@ public abstract class PushMetricExporter<CfgT extends
ExporterView> extends Basi
throw th;
}
}, period(), period(), TimeUnit.MILLISECONDS);
-
}
/** {@inheritDoc} */
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
index 6e0b63046a..0a19701e97 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
+++
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
@@ -26,6 +26,7 @@ import
org.apache.ignite.internal.metrics.exporters.log.LogPushExporter;
*/
@PolymorphicConfigInstance(LogPushExporter.EXPORTER_NAME)
public class LogPushExporterConfigurationSchema extends
ExporterConfigurationSchema {
+ /** Export period, in milliseconds. */
@Value(hasDefault = true)
- public int period = 30_000;
+ public long period = 30_000;
}
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporter.java
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporter.java
index 526afde60a..646bc32b7d 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporter.java
+++
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporter.java
@@ -23,6 +23,8 @@ import com.google.auto.service.AutoService;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
+import java.util.function.Supplier;
import javax.management.JMException;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
@@ -71,8 +73,9 @@ public class JmxExporter extends
BasicMetricExporter<JmxExporterView> {
* {@inheritDoc}
*/
@Override
- public synchronized void start(MetricProvider metricsProvider,
JmxExporterView configuration) {
- super.start(metricsProvider, configuration);
+ public synchronized void start(MetricProvider metricsProvider,
JmxExporterView configuration, Supplier<UUID> clusterIdSupplier,
+ String nodeName) {
+ super.start(metricsProvider, configuration, clusterIdSupplier,
nodeName);
for (MetricSet metricSet : metricsProvider.metrics().get1().values()) {
register(metricSet);
diff --git
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporter.java
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporter.java
index cd00a45d7f..13749deeed 100644
---
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporter.java
+++
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporter.java
@@ -19,6 +19,8 @@ package org.apache.ignite.internal.metrics.exporters.log;
import com.google.auto.service.AutoService;
import java.util.Comparator;
+import java.util.UUID;
+import java.util.function.Supplier;
import java.util.stream.StreamSupport;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.logger.Loggers;
@@ -42,11 +44,12 @@ public class LogPushExporter extends
PushMetricExporter<LogPushExporterView> {
private long period;
@Override
- public void start(MetricProvider metricsProvider, LogPushExporterView
configuration) {
+ public synchronized void start(MetricProvider metricsProvider,
LogPushExporterView configuration, Supplier<UUID> clusterIdSupplier,
+ String nodeName) {
period = configuration.period();
log = Loggers.forClass(LogPushExporter.class);
- super.start(metricsProvider, configuration);
+ super.start(metricsProvider, configuration, clusterIdSupplier,
nodeName);
}
@Override
diff --git
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricConfigurationTest.java
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricConfigurationTest.java
index f14034627b..d71aab526c 100644
---
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricConfigurationTest.java
+++
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricConfigurationTest.java
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
import
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
@@ -61,7 +62,7 @@ public class MetricConfigurationTest extends
BaseIgniteAbstractTest {
availableExporters.put("test", exporter);
- metricManager.configure(metricConfiguration);
+ metricManager.configure(metricConfiguration, UUID::randomUUID,
"test-node");
metricManager.start(availableExporters);
}
diff --git
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/TestExporter.java
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/TestExporter.java
index b95795cf22..43c246a4a1 100644
---
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/TestExporter.java
+++
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/TestExporter.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.metrics.exporters;
+import java.util.UUID;
+import java.util.function.Supplier;
import org.apache.ignite.internal.metrics.MetricProvider;
import org.apache.ignite.internal.metrics.MetricSet;
import org.jetbrains.annotations.Nullable;
@@ -31,8 +33,8 @@ public class TestExporter extends
BasicMetricExporter<TestExporterView> {
private volatile int port;
@Override
- public void start(MetricProvider metricsProvider, TestExporterView
configuration) {
- super.start(metricsProvider, configuration);
+ public void start(MetricProvider metricsProvider, TestExporterView
configuration, Supplier<UUID> clusterIdSupplier, String nodeName) {
+ super.start(metricsProvider, configuration, clusterIdSupplier,
nodeName);
port = configuration.port();
diff --git
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/JmxExporterTest.java
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporterTest.java
similarity index 86%
rename from
modules/metrics/src/test/java/org/apache/ignite/internal/metrics/JmxExporterTest.java
rename to
modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporterTest.java
index 913f279102..59066a7ff4 100644
---
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/JmxExporterTest.java
+++
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporterTest.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.metrics;
+package org.apache.ignite.internal.metrics.exporters.jmx;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -27,6 +27,7 @@ import java.lang.management.ManagementFactory;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.UUID;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InstanceNotFoundException;
@@ -43,9 +44,24 @@ import
org.apache.ignite.internal.configuration.testframework.ConfigurationExten
import
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
import org.apache.ignite.internal.lang.IgniteBiTuple;
import org.apache.ignite.internal.logger.Loggers;
+import org.apache.ignite.internal.metrics.AtomicDoubleMetric;
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.AtomicLongMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.metrics.DoubleAdderMetric;
+import org.apache.ignite.internal.metrics.DoubleGauge;
+import org.apache.ignite.internal.metrics.DoubleMetric;
+import org.apache.ignite.internal.metrics.HitRateMetric;
+import org.apache.ignite.internal.metrics.IntGauge;
+import org.apache.ignite.internal.metrics.IntMetric;
+import org.apache.ignite.internal.metrics.LongAdderMetric;
+import org.apache.ignite.internal.metrics.LongGauge;
+import org.apache.ignite.internal.metrics.LongMetric;
+import org.apache.ignite.internal.metrics.Metric;
+import org.apache.ignite.internal.metrics.MetricProvider;
+import org.apache.ignite.internal.metrics.MetricSet;
import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
import
org.apache.ignite.internal.metrics.exporters.configuration.JmxExporterView;
-import org.apache.ignite.internal.metrics.exporters.jmx.JmxExporter;
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
import org.apache.ignite.internal.util.IgniteUtils;
import org.junit.jupiter.api.AfterEach;
@@ -122,7 +138,7 @@ public class JmxExporterTest extends BaseIgniteAbstractTest
{
when(metricsProvider.metrics()).thenReturn(new
IgniteBiTuple<>(metrics, 1L));
- jmxExporter.start(metricsProvider, jmxExporterConf);
+ jmxExporter.start(metricsProvider, jmxExporterConf, UUID::randomUUID,
"nodeName");
assertThatMbeanAttributeAndMetricValuesAreTheSame();
}
@@ -132,7 +148,7 @@ public class JmxExporterTest extends BaseIgniteAbstractTest
{
throws ReflectionException, AttributeNotFoundException,
MBeanException {
when(metricsProvider.metrics()).thenReturn(new IgniteBiTuple<>(new
HashMap<>(), 1L));
- jmxExporter.start(metricsProvider, jmxExporterConf);
+ jmxExporter.start(metricsProvider, jmxExporterConf, UUID::randomUUID,
"nodeName");
assertThrows(
InstanceNotFoundException.class,
@@ -151,7 +167,7 @@ public class JmxExporterTest extends BaseIgniteAbstractTest
{
when(metricsProvider.metrics()).thenReturn(new
IgniteBiTuple<>(metrics, 1L));
- jmxExporter.start(metricsProvider, jmxExporterConf);
+ jmxExporter.start(metricsProvider, jmxExporterConf, UUID::randomUUID,
"nodeName");
assertThatMbeanAttributeAndMetricValuesAreTheSame();
@@ -169,7 +185,7 @@ public class JmxExporterTest extends BaseIgniteAbstractTest
{
when(metricsProvider.metrics()).thenReturn(new
IgniteBiTuple<>(Map.of(metricSet.name(), metricSet), 1L));
- jmxExporter.start(metricsProvider, jmxExporterConf);
+ jmxExporter.start(metricsProvider, jmxExporterConf, UUID::randomUUID,
"nodeName");
assertEquals(0, mbean().getAttribute(MTRC_NAME));
diff --git
a/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
b/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
index c19905ef0c..5164c15b96 100644
---
a/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
+++
b/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
@@ -22,7 +22,9 @@ import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFu
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
import org.apache.ignite.internal.lang.IgniteBiTuple;
import org.apache.ignite.internal.manager.ComponentContext;
import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
@@ -34,7 +36,7 @@ import
org.apache.ignite.internal.metrics.exporters.MetricExporter;
*/
public class NoOpMetricManager implements MetricManager {
@Override
- public void configure(MetricConfiguration metricConfiguration) {
+ public void configure(MetricConfiguration metricConfiguration,
Supplier<UUID> clusterIdSupplier, String nodeName) {
}
@Override
diff --git a/modules/runner/build.gradle b/modules/runner/build.gradle
index 570e1fa60d..42c06099a1 100644
--- a/modules/runner/build.gradle
+++ b/modules/runner/build.gradle
@@ -75,6 +75,7 @@ dependencies {
implementation project(':ignite-cluster-management')
implementation project(':ignite-metrics')
implementation project(':ignite-cluster-metrics')
+ implementation project(':ignite-metrics-exporter-otlp')
implementation project(':ignite-replicator')
implementation project(':ignite-distribution-zones')
implementation project(':ignite-placement-driver')
diff --git
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
index 9b2d97770b..0a5b14c206 100644
---
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
+++
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
@@ -262,6 +262,7 @@ import
org.apache.ignite.internal.tx.impl.TransactionIdGenerator;
import org.apache.ignite.internal.tx.impl.TransactionInflights;
import org.apache.ignite.internal.tx.impl.TxManagerImpl;
import org.apache.ignite.internal.tx.message.TxMessageGroup;
+import org.apache.ignite.internal.util.CollectionUtils;
import org.apache.ignite.internal.vault.VaultManager;
import org.apache.ignite.internal.vault.persistence.PersistentVaultService;
import org.apache.ignite.internal.worker.CriticalWorkerWatchdog;
@@ -819,7 +820,11 @@ public class IgniteImpl implements Ignite {
threadPoolsManager.tableIoExecutor()
);
-
metricManager.configure(clusterConfigRegistry.getConfiguration(MetricExtensionConfiguration.KEY).metrics());
+ metricManager.configure(
+
clusterConfigRegistry.getConfiguration(MetricExtensionConfiguration.KEY).metrics(),
+ () ->
CollectionUtils.last(clusterInfo(clusterStateStorageMgr).idHistory()),
+ name
+ );
DataStorageModules dataStorageModules = new DataStorageModules(
ServiceLoader.load(DataStorageModule.class,
serviceProviderClassLoader)
diff --git a/settings.gradle b/settings.gradle
index 7b4271fa3e..8df3ddf551 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -61,6 +61,7 @@ include(':ignite-configuration-annotation-processor')
include(':ignite-compute')
include(':ignite-metrics')
include(':ignite-cluster-metrics')
+include(':ignite-metrics-exporter-otlp')
include(':ignite-binary-tuple')
include(':platforms')
include(':packaging-cli')
@@ -139,6 +140,7 @@
project(":ignite-configuration-annotation-processor").projectDir = file('modules
project(":ignite-compute").projectDir = file('modules/compute')
project(":ignite-metrics").projectDir = file('modules/metrics')
project(":ignite-cluster-metrics").projectDir = file('modules/cluster-metrics')
+project(":ignite-metrics-exporter-otlp").projectDir =
file('modules/metrics-exporter-otlp')
project(":ignite-binary-tuple").projectDir = file('modules/binary-tuple')
project(":platforms").projectDir = file('modules/platforms')
project(":ignite-replicator").projectDir = file('modules/replicator')