You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 29 Next »

IDIEP-114
Author
Sponsor
Created
Status
DRAFT


Motivation

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.

Description

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.

Examples of custom metric usages

  • Some metrics may not be provided yet and user registers own.
  • Metrics for load balancing.
  • Various metrics of business processes or related to user application.
  • Security-related metrics.

Examples of databases with custom metrics

Oracle DBPostgresOracle CoherenceMS SQL ServerIBM DB2

Implementation proposal

General approach

  • Custom Metrics are based on the New Metric System.
  • Custom metric name always begins with the prefix "custom.".
  • GridMetricManager handles custom metrics.

  • Allow registration of simple metrics like LongMetric, DoubleMetric, ObjectMetric which can be exported by the existing metric exporters like JMX exporter.
  • Custom metrics management might require a permission.
  • We should document examples of effecient metrics implementations like LongAdder.

API

   1. New metrics facade to Ignite:

package org.apache.ignite;

public interface Ignite {
   public IgniteMetrics metrics();

}

   2. New interface IgniteMetrics

package org.apache.ignite;

/**
* Custom metric manager. Allows to add own metrics in registers with names starting with "custom.".
*/
public interface IgniteMetrics {
/**
* Registers metric in register 'custom.' + {@code registryName}. Adds new register if absent.
*
* @return New {@code metric} or previous metric if it already exists with the same name.
*/
<T extends Metric> T metric(String registryName, String metricName, T metric);

/** Removes metric from register 'custom.' + {@code registryName}. */
void removeMetric(String registryName, String metricName);

/** @return Metric registry named '"custom." + {@code registryName}'. */
ReadOnlyMetricRegistry registry(String registryName);

/** @return Removes registry named '"custom." + {@code registryName}'. */
ReadOnlyMetricRegistry removeRegistry(String registryName);


// Simple type metrics.

/**
* Registers a {@link LongMetric} in register 'custom.' + {@code registryName}. Adds registry if absent.
*
* @return New or previously registered long value setter.
*/
LongConsumer longMetric(String registryName, String metricName, @Nullable String description);

/**
* Registers a {@link DoubleMetric} in register 'custom.' + {@code registryName}. Adds registry if absent.
*
* @return New or previously registered double value setter.
*/
DoubleConsumer doubleMetric(String registryName, String metricName, @Nullable String description);

/**
* Registers a {@link BooleanMetric} in register 'custom.' + {@code registryName}. Adds registry if absent.
*
* @return New or previously registered boolean value setter.
*/
Consumer<Boolean> booleanMetric(String registryName, String metricName, @Nullable String description);

/**
* Registers a {@link ObjectMetric} in register 'custom.' + {@code registryName}. Adds registry if absent.
*
* @return New or previously registered object setter.
*/
<T> Consumer<T> objectMetric(String registryName, String metricName, Class<T> valueType, @Nullable String description);


// Might be useful the gauges:

/**
* Registers a {@link LongMetric} metric in register 'custom.' + {@code registryName} with long value supplier {@code valueSupplier}.
* Adds registry if absent.
*
* @return {@code True} if metric was added. {@code False} if another meric already exists under the same name.
*/
boolean longMetric(String registryName, String metricName, LongSupplier valueSupplier, @Nullable String description);

/**
* Registers a {@link DoubleMetric} metric in register 'custom.' + {@code registryName} with double value supplier {@code valueSupplier}.
* Adds registry if absent.
*
* @return {@code True} if metric was added. {@code False} if another meric already exists under the same name.
*/
boolean doubleMetric(String registryName, String metricName, DoubleSupplier valueSupplier, @Nullable String description);

/**
* Registers a {@link BooleanMetric} metric in register 'custom.' + {@code registryName} with boolean value supplier {@code valueSupplier}.
* Adds registry if absent.
*
* @return {@code True} if metric was added. {@code False} if another meric already exists under the same name.
*/
boolean booleanMetric(String registryName, String metricName, BooleanSupplier valueSupplier, @Nullable String description);

/**
* Registers a {@link ObjectMetric} metric in register 'custom.' + {@code registryName} with object value supplier {@code valueSupplier}.
* Adds registry if absent.
*
* @return {@code True} if metric was added. {@code False} if another meric already exists under the same name.
*/
<T> boolean objectMetric(String registryName, String metricName, Class<T> valueType, Supplier<T> valueSupplier, @Nullable String description);
}

Risks and Assumptions

  • Custom metrics can affect the performance.
  • We do not provide varuous useful metric implementatons.
  • Custom metrics aren't stored and require re-registration after node restart. At least at the first phase.

Phases

The 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 might be:

  1. Implementation of the described API.
  2. Extending the API with metrics like Histogram, HitRate. Allowing to configure metrics.
  3. Storing registered custom metrics with their configurations.

Discussion Links

Tickets


  • No labels