agura commented on code in PR #957:
URL: https://github.com/apache/ignite-3/pull/957#discussion_r937519740
##########
modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java:
##########
@@ -787,4 +802,88 @@ public static void
awaitForWorkersStop(Collection<IgniteWorker> workers, boolean
}
}
}
+
+ /**
+ * Checks if given argument's condition is equal to {@code true}, otherwise
+ * throws {@link IllegalArgumentException} exception.
+ *
+ * @param cond Argument's value condition to check.
+ * @param desc Description of the condition to be used in error message.
+ */
+ public static void ensure(boolean cond, String desc) {
Review Comment:
There is no any usage of this approach in AI 3. Please remove and use
standard approach for AI3.
##########
modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java:
##########
@@ -787,4 +802,88 @@ public static void
awaitForWorkersStop(Collection<IgniteWorker> workers, boolean
}
}
}
+
+ /**
+ * Checks if given argument's condition is equal to {@code true}, otherwise
+ * throws {@link IllegalArgumentException} exception.
+ *
+ * @param cond Argument's value condition to check.
+ * @param desc Description of the condition to be used in error message.
+ */
+ public static void ensure(boolean cond, String desc) {
+ if (!cond) {
+ throw new IllegalArgumentException(INVALID_ARG_MSG_PREFIX + desc);
+ }
+ }
+
+ /**
+ * System time approximated by 10 ms.
+ *
+ * @return System time approximated by 10 ms.
+ */
+ public static long currentTimeMillis() {
Review Comment:
There is already `FastTimestamps.coarseCurrentTimeMillis()`. Please remove.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricSet.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.ignite.internal.metrics.composite.CompositeMetric;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * The Metric set that consists of set of metrics identified by a metric name.
+ * The metrics set is immutable.
+ */
+public class MetricSet implements Iterable<Metric> {
+ /** Metrics set name. */
+ private final String name;
+
+ /** Registered metrics. */
+ private final Map<String, Metric> metrics;
+
+ /**
+ * Creates an instance of a metrics set with given name and metrics.
+ *
+ * @param name Metrics set name.
+ * @param metrics Metrics.
+ */
+ public MetricSet(String name, Map<String, Metric> metrics) {
+ this.name = name;
+ this.metrics = Collections.unmodifiableMap(metrics);
+ }
+
+ /**
+ * Get metric by name.
+ *
+ * @param name Metric name.
+ * @return Metric.
+ */
+ @Nullable
+ @TestOnly
+ public <M extends Metric> M get(String name) {
+ return (M) metrics.get(name);
+ }
+
+ /** {@inheritDoc} */
+ public Iterator<Metric> iterator() {
+ return metrics.values().iterator();
+ }
+
+ /**
+ * The iterator that considers composite metrics as a group of scalar
ones, see {@link CompositeMetric#asScalarMetrics()},
+ * and enumerates composite metrics in order to enumerate every scalar
metric.
+ *
+ * @return Iterator.
+ */
+ public Iterator<Metric> scalarMetricsIterator() {
Review Comment:
IMO, this method is not needed. `iterator` should return all metrics in the
set (always in the same order). You can create a composite iterator which will
return all metrics as a "flat" set.
Otherwise, exporter will be responsible for invocation of both methods and
it could lead to side effects like different order of invocation.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unregister metric source. It must be unregistered in case of
corrsponding component is destroyed or stopped.
Review Comment:
typo in `corrsponding`
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unregister metric source. It must be unregistered in case of
corrsponding component is destroyed or stopped.
+ *
+ * @param src Metric source.
+ */
+ public void unregisterSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ disable(src.name());
+
+ sources.remove(src.name());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Enable metric set for the given metric source.
+ *
+ * @param srcName Metric source name.
+ * @return Metric set, or {@code null} if the metric set is already
enabled.
+ */
+ public MetricSet enable(final String srcName) {
+ lock.lock();
+
+ try {
+ MetricSource src = sources.get(srcName);
+
+ if (src == null) {
+ throw new IllegalStateException("Metrics source with given
name doesn't exists: " + srcName);
+ }
+
+ MetricSet metricSet = src.enable();
+
+ if (metricSet != null) {
+ sets.put(srcName, metricSet);
+
+ version++;
+ }
+
+ return metricSet;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Disable metric set for the given metric source.
+ *
+ * @param srcName Metric source name.
+ */
+ public void disable(final String srcName) {
Review Comment:
May be in some cases it will be useful to disable by `MetricsSource`
instance.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
Review Comment:
Where is a part described in the
https://issues.apache.org/jira/browse/IGNITE-17354? I talk about a metrics
export infrastructure like copy-on-write semantic, etc.
> Data structure (likely map) that is responsible for keeping enabled
metrics set should be modified using copy-on-write semantics in order to avoid
data races between main functionality (metrics enabling\disabling) and
exporters.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
Review Comment:
How any exporter should get access to metircs? Current implementation
doesn't allow such functionality.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricSetBuilder.java:
##########
@@ -0,0 +1,229 @@
+/*
+ * 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;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.DoubleSupplier;
+import java.util.function.IntSupplier;
+import java.util.function.LongSupplier;
+import org.apache.ignite.internal.metrics.composite.DistributionMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicDoubleMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicLongMetric;
+import org.apache.ignite.internal.metrics.scalar.DoubleAdderMetric;
+import org.apache.ignite.internal.metrics.scalar.DoubleGauge;
+import org.apache.ignite.internal.metrics.scalar.HitRateMetric;
+import org.apache.ignite.internal.metrics.scalar.IntGauge;
+import org.apache.ignite.internal.metrics.scalar.LongAdderMetric;
+import org.apache.ignite.internal.metrics.scalar.LongGauge;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Metric set builder.
+ */
+public class MetricSetBuilder {
Review Comment:
Metric**s**
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/AbstractMetricSource.java:
##########
@@ -0,0 +1,137 @@
+/*
+ * 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;
+
+import static
java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater;
+
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+/**
+ * Base class for all metric sources.
+ *
+ * @param <T> Holder type.
+ */
+public abstract class AbstractMetricSource<T extends
AbstractMetricSource.Holder<T>> implements MetricSource {
Review Comment:
Metric**s**
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricSetBuilder.java:
##########
@@ -0,0 +1,229 @@
+/*
+ * 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;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.DoubleSupplier;
+import java.util.function.IntSupplier;
+import java.util.function.LongSupplier;
+import org.apache.ignite.internal.metrics.composite.DistributionMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicDoubleMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicLongMetric;
+import org.apache.ignite.internal.metrics.scalar.DoubleAdderMetric;
+import org.apache.ignite.internal.metrics.scalar.DoubleGauge;
+import org.apache.ignite.internal.metrics.scalar.HitRateMetric;
+import org.apache.ignite.internal.metrics.scalar.IntGauge;
+import org.apache.ignite.internal.metrics.scalar.LongAdderMetric;
+import org.apache.ignite.internal.metrics.scalar.LongGauge;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Metric set builder.
+ */
+public class MetricSetBuilder {
+ /** Metrics set name. */
+ private final String name;
+
+ /** Registered metrics. */
+ private Map<String, Metric> metrics = new LinkedHashMap<>();
+
+ /**
+ * Creates a new instance of metrics set builder with given name.
+ *
+ * @param name Name of metrics set. Can't be null.
+ */
+ public MetricSetBuilder(String name) {
+ Objects.requireNonNull(name, "Metrics set name can't be null");
+ this.name = name;
+ }
+
+ /**
+ * Build a metric set.
+ *
+ * @return Metric set.
+ */
+ public MetricSet build() {
+ if (metrics == null) {
+ throw new IllegalStateException("Builder can't be used twice.");
+ }
+
+ MetricSet reg = new MetricSet(name, metrics);
+
+ metrics = null;
+
+ return reg;
+ }
+
+ /**
+ * Returns metrics set name.
+ *
+ * @return Metrics set name.
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Adds existing metric with the specified name.
+ *
+ * @param metric Metric.
+ * @throws IllegalStateException If metric with given name is already
added.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Metric> T register(T metric) {
+ T old = (T) metrics.putIfAbsent(metric.name(), metric);
+
+ if (old != null) {
+ throw new IllegalStateException("Metric with given name is already
registered [name=" + name
+ + ", metric=" + metric + ']');
+ }
+
+ return metric;
+ }
+
+ /**
+ * Add an atomic integer metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic integer metric.
+ */
+ public AtomicIntMetric atomicInt(String name, @Nullable String
description) {
+ return register(new AtomicIntMetric(name, description));
+ }
+
+ /**
+ * Add an integer gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Integer gauge.
+ */
+ public IntGauge intGauge(String name, @Nullable String description,
IntSupplier supplier) {
+ return register(new IntGauge(name, description, supplier));
+ }
+
+ /**
+ * Add an atomic long metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic long metric.
+ */
+ public AtomicLongMetric atomicLong(String name, @Nullable String
description) {
+ return register(new AtomicLongMetric(name, description));
+ }
+
+ /**
+ * Add a long adder metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Long adder metric.
+ */
+ public LongAdderMetric longAdder(String name, @Nullable String
description) {
+ return register(new LongAdderMetric(name, description));
+ }
+
+ /**
+ * Add a long gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Long gauge.
+ */
+ public LongGauge longGauge(String name, @Nullable String description,
LongSupplier supplier) {
+ return register(new LongGauge(name, description, supplier));
+ }
+
+ /**
+ * Add an atomic double metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic double metric.
+ */
+ public AtomicDoubleMetric atomicDouble(String name, @Nullable String
description) {
+ return register(new AtomicDoubleMetric(name, description));
+ }
+
+ /**
+ * Add a double adder metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Double adder metric.
+ */
+ public DoubleAdderMetric doubleAdder(String name, @Nullable String
description) {
+ return register(new DoubleAdderMetric(name, description));
+ }
+
+ /**
+ * Add a double gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Double gauge.
+ */
+ public DoubleGauge doubleGauge(String name, @Nullable String description,
DoubleSupplier supplier) {
+ return register(new DoubleGauge(name, description, supplier));
+ }
+
+ /**
+ * Add a hit rate metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param rateTimeInterval Rate time interval in milliseconds.
+ * @return Hit rate metric.
+ */
+ public HitRateMetric hitRateMetric(String name, @Nullable String
description, long rateTimeInterval) {
+ return register(new HitRateMetric(name, description,
rateTimeInterval));
+ }
+
+ /**
+ * Add a hit rate metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param rateTimeInterval Rate time interval in milliseconds.
+ * @param size Counters array size.
+ * @return Hit rate metric.
+ */
+ public HitRateMetric hitRateMetric(String name, @Nullable String
description, long rateTimeInterval, int size) {
Review Comment:
Just `hitRate` in order to be consistent with the naming of other factory
methods.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
Review Comment:
Metric**s**
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unregister metric source. It must be unregistered in case of
corrsponding component is destroyed or stopped.
+ *
+ * @param src Metric source.
+ */
+ public void unregisterSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ disable(src.name());
Review Comment:
This behavior should be stated in java doc. And `registerSource` should
notice that registration doesn't lead to enabling.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricSetBuilder.java:
##########
@@ -0,0 +1,229 @@
+/*
+ * 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;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.DoubleSupplier;
+import java.util.function.IntSupplier;
+import java.util.function.LongSupplier;
+import org.apache.ignite.internal.metrics.composite.DistributionMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicDoubleMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicLongMetric;
+import org.apache.ignite.internal.metrics.scalar.DoubleAdderMetric;
+import org.apache.ignite.internal.metrics.scalar.DoubleGauge;
+import org.apache.ignite.internal.metrics.scalar.HitRateMetric;
+import org.apache.ignite.internal.metrics.scalar.IntGauge;
+import org.apache.ignite.internal.metrics.scalar.LongAdderMetric;
+import org.apache.ignite.internal.metrics.scalar.LongGauge;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Metric set builder.
+ */
+public class MetricSetBuilder {
+ /** Metrics set name. */
+ private final String name;
+
+ /** Registered metrics. */
+ private Map<String, Metric> metrics = new LinkedHashMap<>();
+
+ /**
+ * Creates a new instance of metrics set builder with given name.
+ *
+ * @param name Name of metrics set. Can't be null.
+ */
+ public MetricSetBuilder(String name) {
+ Objects.requireNonNull(name, "Metrics set name can't be null");
+ this.name = name;
+ }
+
+ /**
+ * Build a metric set.
+ *
+ * @return Metric set.
+ */
+ public MetricSet build() {
+ if (metrics == null) {
+ throw new IllegalStateException("Builder can't be used twice.");
+ }
+
+ MetricSet reg = new MetricSet(name, metrics);
+
+ metrics = null;
+
+ return reg;
+ }
+
+ /**
+ * Returns metrics set name.
+ *
+ * @return Metrics set name.
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Adds existing metric with the specified name.
+ *
+ * @param metric Metric.
+ * @throws IllegalStateException If metric with given name is already
added.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Metric> T register(T metric) {
+ T old = (T) metrics.putIfAbsent(metric.name(), metric);
+
+ if (old != null) {
+ throw new IllegalStateException("Metric with given name is already
registered [name=" + name
+ + ", metric=" + metric + ']');
+ }
+
+ return metric;
+ }
+
+ /**
+ * Add an atomic integer metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic integer metric.
+ */
+ public AtomicIntMetric atomicInt(String name, @Nullable String
description) {
+ return register(new AtomicIntMetric(name, description));
+ }
+
+ /**
+ * Add an integer gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Integer gauge.
+ */
+ public IntGauge intGauge(String name, @Nullable String description,
IntSupplier supplier) {
+ return register(new IntGauge(name, description, supplier));
+ }
+
+ /**
+ * Add an atomic long metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic long metric.
+ */
+ public AtomicLongMetric atomicLong(String name, @Nullable String
description) {
+ return register(new AtomicLongMetric(name, description));
+ }
+
+ /**
+ * Add a long adder metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Long adder metric.
+ */
+ public LongAdderMetric longAdder(String name, @Nullable String
description) {
+ return register(new LongAdderMetric(name, description));
+ }
+
+ /**
+ * Add a long gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Long gauge.
+ */
+ public LongGauge longGauge(String name, @Nullable String description,
LongSupplier supplier) {
+ return register(new LongGauge(name, description, supplier));
+ }
+
+ /**
+ * Add an atomic double metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic double metric.
+ */
+ public AtomicDoubleMetric atomicDouble(String name, @Nullable String
description) {
+ return register(new AtomicDoubleMetric(name, description));
+ }
+
+ /**
+ * Add a double adder metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Double adder metric.
+ */
+ public DoubleAdderMetric doubleAdder(String name, @Nullable String
description) {
+ return register(new DoubleAdderMetric(name, description));
+ }
+
+ /**
+ * Add a double gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Double gauge.
+ */
+ public DoubleGauge doubleGauge(String name, @Nullable String description,
DoubleSupplier supplier) {
+ return register(new DoubleGauge(name, description, supplier));
+ }
+
+ /**
+ * Add a hit rate metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param rateTimeInterval Rate time interval in milliseconds.
+ * @return Hit rate metric.
+ */
+ public HitRateMetric hitRateMetric(String name, @Nullable String
description, long rateTimeInterval) {
Review Comment:
Just `hitRate` in order to be consistent with the naming of other factory
methods.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
Review Comment:
This exception should be described in java doc.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unregister metric source. It must be unregistered in case of
corrsponding component is destroyed or stopped.
+ *
+ * @param src Metric source.
+ */
+ public void unregisterSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ disable(src.name());
+
+ sources.remove(src.name());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Enable metric set for the given metric source.
+ *
+ * @param srcName Metric source name.
+ * @return Metric set, or {@code null} if the metric set is already
enabled.
+ */
+ public MetricSet enable(final String srcName) {
Review Comment:
May be in some cases it can be useful to enable by `MetricsSource` instance.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unregister metric source. It must be unregistered in case of
corrsponding component is destroyed or stopped.
+ *
+ * @param src Metric source.
+ */
+ public void unregisterSource(MetricSource src) {
Review Comment:
Interesting thing here is that you can have only metrics source name in some
cases. May be unregister by name will be useful.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unregister metric source. It must be unregistered in case of
corrsponding component is destroyed or stopped.
+ *
+ * @param src Metric source.
+ */
+ public void unregisterSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ disable(src.name());
+
+ sources.remove(src.name());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Enable metric set for the given metric source.
+ *
+ * @param srcName Metric source name.
+ * @return Metric set, or {@code null} if the metric set is already
enabled.
+ */
+ public MetricSet enable(final String srcName) {
+ lock.lock();
+
+ try {
+ MetricSource src = sources.get(srcName);
+
+ if (src == null) {
+ throw new IllegalStateException("Metrics source with given
name doesn't exists: " + srcName);
+ }
+
+ MetricSet metricSet = src.enable();
+
+ if (metricSet != null) {
+ sets.put(srcName, metricSet);
Review Comment:
This metrics can be already enabled and metrics set could be already added
to registry. So you will not change the metrics registry state but change the
version. Moreover, additional instance of `MetricsSet` will be created but we
can avoid it.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unregister metric source. It must be unregistered in case of
corrsponding component is destroyed or stopped.
+ *
+ * @param src Metric source.
+ */
+ public void unregisterSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ disable(src.name());
+
+ sources.remove(src.name());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Enable metric set for the given metric source.
+ *
+ * @param srcName Metric source name.
+ * @return Metric set, or {@code null} if the metric set is already
enabled.
+ */
+ public MetricSet enable(final String srcName) {
+ lock.lock();
+
+ try {
+ MetricSource src = sources.get(srcName);
+
+ if (src == null) {
+ throw new IllegalStateException("Metrics source with given
name doesn't exists: " + srcName);
+ }
+
+ MetricSet metricSet = src.enable();
+
+ if (metricSet != null) {
+ sets.put(srcName, metricSet);
+
+ version++;
+ }
+
+ return metricSet;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Disable metric set for the given metric source.
+ *
+ * @param srcName Metric source name.
+ */
+ public void disable(final String srcName) {
+ lock.lock();
+
+ try {
+ MetricSource src = sources.get(srcName);
+
+ if (src == null) {
+ throw new IllegalStateException("Metrics source with given
name doesn't exists: " + srcName);
+ }
+
+ src.disable();
+
+ sets.remove(srcName);
+
+ version++;
Review Comment:
`MetricsSet` instance could be removed already but `version` will be
changed.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricSetBuilder.java:
##########
@@ -0,0 +1,229 @@
+/*
+ * 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;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.DoubleSupplier;
+import java.util.function.IntSupplier;
+import java.util.function.LongSupplier;
+import org.apache.ignite.internal.metrics.composite.DistributionMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicDoubleMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.scalar.AtomicLongMetric;
+import org.apache.ignite.internal.metrics.scalar.DoubleAdderMetric;
+import org.apache.ignite.internal.metrics.scalar.DoubleGauge;
+import org.apache.ignite.internal.metrics.scalar.HitRateMetric;
+import org.apache.ignite.internal.metrics.scalar.IntGauge;
+import org.apache.ignite.internal.metrics.scalar.LongAdderMetric;
+import org.apache.ignite.internal.metrics.scalar.LongGauge;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Metric set builder.
+ */
+public class MetricSetBuilder {
+ /** Metrics set name. */
+ private final String name;
+
+ /** Registered metrics. */
+ private Map<String, Metric> metrics = new LinkedHashMap<>();
+
+ /**
+ * Creates a new instance of metrics set builder with given name.
+ *
+ * @param name Name of metrics set. Can't be null.
+ */
+ public MetricSetBuilder(String name) {
+ Objects.requireNonNull(name, "Metrics set name can't be null");
+ this.name = name;
+ }
+
+ /**
+ * Build a metric set.
+ *
+ * @return Metric set.
+ */
+ public MetricSet build() {
+ if (metrics == null) {
+ throw new IllegalStateException("Builder can't be used twice.");
+ }
+
+ MetricSet reg = new MetricSet(name, metrics);
+
+ metrics = null;
+
+ return reg;
+ }
+
+ /**
+ * Returns metrics set name.
+ *
+ * @return Metrics set name.
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Adds existing metric with the specified name.
+ *
+ * @param metric Metric.
+ * @throws IllegalStateException If metric with given name is already
added.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Metric> T register(T metric) {
+ T old = (T) metrics.putIfAbsent(metric.name(), metric);
+
+ if (old != null) {
+ throw new IllegalStateException("Metric with given name is already
registered [name=" + name
+ + ", metric=" + metric + ']');
+ }
+
+ return metric;
+ }
+
+ /**
+ * Add an atomic integer metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic integer metric.
+ */
+ public AtomicIntMetric atomicInt(String name, @Nullable String
description) {
+ return register(new AtomicIntMetric(name, description));
+ }
+
+ /**
+ * Add an integer gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Integer gauge.
+ */
+ public IntGauge intGauge(String name, @Nullable String description,
IntSupplier supplier) {
+ return register(new IntGauge(name, description, supplier));
+ }
+
+ /**
+ * Add an atomic long metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic long metric.
+ */
+ public AtomicLongMetric atomicLong(String name, @Nullable String
description) {
+ return register(new AtomicLongMetric(name, description));
+ }
+
+ /**
+ * Add a long adder metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Long adder metric.
+ */
+ public LongAdderMetric longAdder(String name, @Nullable String
description) {
+ return register(new LongAdderMetric(name, description));
+ }
+
+ /**
+ * Add a long gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Long gauge.
+ */
+ public LongGauge longGauge(String name, @Nullable String description,
LongSupplier supplier) {
+ return register(new LongGauge(name, description, supplier));
+ }
+
+ /**
+ * Add an atomic double metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Atomic double metric.
+ */
+ public AtomicDoubleMetric atomicDouble(String name, @Nullable String
description) {
+ return register(new AtomicDoubleMetric(name, description));
+ }
+
+ /**
+ * Add a double adder metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @return Double adder metric.
+ */
+ public DoubleAdderMetric doubleAdder(String name, @Nullable String
description) {
+ return register(new DoubleAdderMetric(name, description));
+ }
+
+ /**
+ * Add a double gauge.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param supplier Supplier of the value.
+ * @return Double gauge.
+ */
+ public DoubleGauge doubleGauge(String name, @Nullable String description,
DoubleSupplier supplier) {
+ return register(new DoubleGauge(name, description, supplier));
+ }
+
+ /**
+ * Add a hit rate metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param rateTimeInterval Rate time interval in milliseconds.
+ * @return Hit rate metric.
+ */
+ public HitRateMetric hitRateMetric(String name, @Nullable String
description, long rateTimeInterval) {
+ return register(new HitRateMetric(name, description,
rateTimeInterval));
+ }
+
+ /**
+ * Add a hit rate metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param rateTimeInterval Rate time interval in milliseconds.
+ * @param size Counters array size.
+ * @return Hit rate metric.
+ */
+ public HitRateMetric hitRateMetric(String name, @Nullable String
description, long rateTimeInterval, int size) {
+ return register(new HitRateMetric(name, description, rateTimeInterval,
size));
+ }
+
+ /**
+ * Add a distribution metric.
+ *
+ * @param name Name.
+ * @param description Description.
+ * @param bounds Bounds of the buckets
+ * @return Distribution metrics.
+ */
+ public DistributionMetric distributionMetric(String name, @Nullable String
description, long[] bounds) {
Review Comment:
Just `distribution` in order to be consistent with the naming of other
factory methods.
##########
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricRegistry.java:
##########
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * Metric registry. Metrics source (see {@link MetricSource} must be
registered in this metrics registry after initialization
+ * of corresponding component and must be unregistered in case of component is
destroyed or stopped. Metrics registry also
+ * provides access to all enabled metrics through corresponding metrics sets.
Metrics registry lifetime is equal to the node lifetime.
+ */
+public class MetricRegistry {
+ private final Lock lock = new ReentrantLock();
+
+ /** Registered metric sources. */
+ private final Map<String, MetricSource> sources = new HashMap<>();
+
+ /** Enabled metric sets. */
+ private final Map<String, MetricSet> sets = new TreeMap<>();
+
+ /** Version always should be changed on metrics enabled/disabled action. */
+ private volatile long version;
+
+ /**
+ * Register metric source. It must be registered in this metrics registry
after initialization of corresponding component
+ * and must be unregistered in case of component is destroyed or stopped,
see {@link #unregisterSource(MetricSource)}.
+ *
+ * @param src Metric source.
+ */
+ public void registerSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ MetricSource old = sources.putIfAbsent(src.name(), src);
+
+ if (old != null) {
+ throw new IllegalStateException("Metrics source with given
name is already exists: " + src.name());
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unregister metric source. It must be unregistered in case of
corrsponding component is destroyed or stopped.
+ *
+ * @param src Metric source.
+ */
+ public void unregisterSource(MetricSource src) {
+ lock.lock();
+
+ try {
+ disable(src.name());
+
+ sources.remove(src.name());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Enable metric set for the given metric source.
+ *
+ * @param srcName Metric source name.
+ * @return Metric set, or {@code null} if the metric set is already
enabled.
+ */
+ public MetricSet enable(final String srcName) {
+ lock.lock();
+
+ try {
+ MetricSource src = sources.get(srcName);
+
+ if (src == null) {
+ throw new IllegalStateException("Metrics source with given
name doesn't exists: " + srcName);
+ }
+
+ MetricSet metricSet = src.enable();
+
+ if (metricSet != null) {
+ sets.put(srcName, metricSet);
+
+ version++;
+ }
+
+ return metricSet;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Disable metric set for the given metric source.
+ *
+ * @param srcName Metric source name.
+ */
+ public void disable(final String srcName) {
+ lock.lock();
+
+ try {
+ MetricSource src = sources.get(srcName);
+
+ if (src == null) {
+ throw new IllegalStateException("Metrics source with given
name doesn't exists: " + srcName);
+ }
+
+ src.disable();
+
+ sets.remove(srcName);
+
+ version++;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns registry schema version.
+ *
+ * @return Version.
+ */
+ @TestOnly
+ public long version() {
Review Comment:
This method is not for tests only. Versioning is a way for using compact
metrics format for exporting because you can pass the schema only one for one
particular version.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]