...
It is useful for user to work with own metrics, not only with provided by Ignite. Current public metrics API doesn't expose any method to add or delete additional metrics. We should allow user to register custom metrics.
...
The most important reason to provide custom is probably the convenience of collecting of desired metrics using one platform, the same client, through the same API. This feature can simplify user application.
...
...
GridMetricManager handles custom metrics.
...
In future, we might want to provide an internal API to obtain metrics like this. It could be quite different and we should split them.
package org.apache.ignite;
public interface Ignite {
public IgniteMetricsIgniteCustomMetrics metrics();
}
...
To keep custom metrics detached from the internals, we should either automaticall add a prefix to custom name or throw an exception if provided metric name doesn't start with that prefix.
package org.apache.ignite;
/**
* Custom metric manager. Allows to add owncustom metrics. inCustom metrics registers is always stored with names starting with "custom.". name prefix "custom.".
* If provided registry name is "a.b.regname", it is automatically converted to "custom.a.b.regname".
* If the name is "custom.a.b.regname", it is used as is.
*/
public interface IgniteMetricsIgniteCustomMetrics {
/**
* Registers metric in register 'custom.' +registry {@code registryName}. Adds new metric registerregistry if absent.
*
* @return New {@codePrevious metric} or previous metric if it already exists with the same name. {@code metric} otherwise.
*/
<T extends Metric> T metric(String registryName, String metricName, T metric);
/** Removes metric from register 'custom.' +registry {@code registryName}. */
void removeMetric(String registryName, String metricName);
/** @return Metric registry named '"custom." + {@code registryName}'. */
ReadOnlyMetricRegistry registry(String registryName);
/** Removes registry named '"custom." + {@code registryName}'. */
void removeRegistry(String registryName);
// Simple type metrics. Int, Long and Double should be enough.
/**
* Registers a {@link LongMetric} in register 'custom.' + registry {@code registryName}. Adds new metric registry if absent.
*
* @return New or previously registered long value setter Previous long value setter if it already exists with the same name. A new one otherwise.
*/
LongConsumer longMetric(String registryName, String metricName, @Nullable String description);
/**
* Registers a {@link DoubleMetric} in register 'custom.' + registry {@code registryName}. Adds new metric registry if absent.
*
* @return New or previously registered double value setterPrevious double value setter if it already exists with the same name. A new one otherwise.
*/
DoubleConsumer doubleMetric(String registryName, String metricName, @Nullable String description);
/**
* Registers a {@link BooleanMetricIntMetric} in register 'custom.' +registry {@code registryName}. Adds new metric registry if absent.
*
* @return New or previously registered boolean value setter Previous int value setter if it already exists with the same name. A new one otherwise.
*/
Consumer<Boolean>IntConsumer booleanMetric(String registryName, String metricName, @Nullable String description);
// Might be useful the gauges.
/**
* Registers a {@link ObjectMetricLongMetric} metric in register 'custom.' + registry {@code registryName} with long value supplier {@code registryNamevalueSupplier}.
* Adds new metric registry if absent.
*
* @return New {@code True} if metric was added. {@code False} if another meric already exists under the same name. or previously registered object setter.
*/
<T> Consumer<T> objectMetricboolean longMetric(String registryName, String metricName, Class<T>LongSupplier valueTypevalueSupplier, @Nullable String description);
// Might be useful the gauges:
/**
* Registers a {@link LongMetricDoubleMetric} metric in register 'custom.' + registry {@code registryName} with longdouble value supplier {@code valueSupplier}.
* Adds new metric registry if absent.
*
* @return {@code True} if metric was added. {@code False} if another meric already exists under the same name.
*/
boolean longMetricdoubleMetric(String registryName, String metricName, LongSupplierDoubleSupplier valueSupplier, @Nullable String description);
/**
* Registers a {@link DoubleMetricIntMetric} metric in register 'custom.' + registry {@code registryName} with doubleint value supplier {@code valueSupplier}.
* Adds new metric registry if absent.
*
* @return {@code True} if metric was added. {@code False} if another meric already exists under the same name.
*/
boolean doubleMetricintMetric(String registryName, String metricName, DoubleSupplierBooleanSupplier valueSupplier, @Nullable String description);
// Additionnaly, we might expose an object metrics API.
/**
* Registers a {@link BooleanMetricObjectMetric} metric in register 'custom.' + registry {@code registryName} with booleanobject value supplier {@code valueSupplier}.
* Adds new metric registry if absent.
*
* @return {@code True} if metric was added. {@code False} if another meric already exists under the same name.
*/
<T> boolean booleanMetricobjectMetric(String registryName, String metricName, Class<T> valueType, BooleanSupplierSupplier<T> valueSupplier, @Nullable String description);
/**
* Registers a {@link ObjectMetric} metric in register 'custom.' + registry {@code registryName} with object value supplier {@code valueSupplier}.
* Adds new metric registry if absent.
*
* @return {@codeNew True}or ifpreviously metricregistered wasobject added. {@code False} if another meric already exists under the same name. setter.
*/
<T> booleanConsumer<T> objectMetric(String registryName, String metricName, Class<T> valueType, Supplier<T> valueSupplier, @Nullable String description);
}
We already have implementations of more complex and useful metricsThe custom metric API might be also enriched with more complex metrics like historgams. We could also store custom metrics and their configurations. Thus, the development steps stages might be: