com.pushtechnology.diffusion.client.features.control.Metrics Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2021, 2024 DiffusionData Ltd., All Rights Reserved.
*
* Use is subject to licence terms.
*
* NOTICE: All information contained herein is, and remains the
* property of DiffusionData. The intellectual and technical
* concepts contained herein are proprietary to DiffusionData and
* may be covered by U.S. and Foreign Patents, patents in process, and
* are protected by trade secret or copyright law.
*******************************************************************************/
package com.pushtechnology.diffusion.client.features.control;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.regex.Pattern;
import com.pushtechnology.diffusion.client.Diffusion;
import com.pushtechnology.diffusion.client.features.ClusterRoutingException;
import com.pushtechnology.diffusion.client.features.InvalidFilterException;
import com.pushtechnology.diffusion.client.session.Feature;
import com.pushtechnology.diffusion.client.session.PermissionsException;
import com.pushtechnology.diffusion.client.session.Session;
import com.pushtechnology.diffusion.client.session.SessionClosedException;
import com.pushtechnology.diffusion.client.types.GlobalPermission;
/**
* This feature allows a client to configure metric collectors.
*
* Diffusion servers provide metrics which are made available in several ways:-
*
* - Java Management Extensions (JMX) MBeans.
*
- Through the Diffusion Management Console.
*
- As endpoints for Prometheus.
*
* Metric collectors allow custom aggregation of metrics that are relevant to
* your application. There are no default metric collectors, only the ones that
* you create.
*
* There are two types of metric collector: Session Metric Collectors and Topic
* Metric Collectors.
*
* For full details regarding the configuration and operation of metric
* collectors see the user manual.
*
Session Metric Collectors.
*
* These can be configured to record metric data for a subset of all sessions,
* specified with a session filter.
*
* The set of metrics recorded by each session metric collector is the same as
* those recorded for the whole server. For full details of session metrics, see
* the table in user manual.
*
* If the session filters of two different session metric collectors select the
* same session, both will record metrics for that session. It is only valid to
* add the metrics of different session metric collectors if their session
* filters select distinct sets of sessions.
*
* You can optionally group the sessions within a collector by session
* properties.
*
Topic Metric Collectors
*
* These can be configured to record metric data for a subset of all topics,
* specified with a topic selector.
*
* You can optionally group the topics within a collector by topic type.
*
* The set of metrics recorded by each topic metric collector is the same as
* those recorded for the whole server. For full details of topic metrics, see
* the table in the user manual.
*
* If the topic selectors of two different topic metric collectors select the
* same topic, both will record metrics for that topic. It is only valid to add
* the metrics of different topic metric collectors if their topic selectors
* select distinct sets of topics.
*
Access control
*
* The following access control restrictions are applied:
*
* - To {@link #putSessionMetricCollector put} or
* {@link #removeSessionMetricCollector remove} a session metric collector, a
* session needs the {@link GlobalPermission#CONTROL_SERVER CONTROL_SERVER}
* global permission.
*
- To {@link #putTopicMetricCollector put} or
* {@link #removeTopicMetricCollector remove} a topic metric collector, a
* session needs the {@link GlobalPermission#CONTROL_SERVER CONTROL_SERVER}
* global permission.
*
- To list {@link #listSessionMetricCollectors session metric collectors} or
* {@link #listTopicMetricCollectors topic metric collectors}, a session needs
* the {@link GlobalPermission#VIEW_SERVER VIEW_SERVER} global permission.
*
- To get metrics with {@link MetricsRequest#fetch()}, session needs the
* {@link GlobalPermission#VIEW_SERVER VIEW_SERVER} global permission.
*
*
* Accessing the feature
*
* This feature may be obtained from a {@link Session session} as follows:
*
*
* Metrics metrics = session.feature(Metrics.class);
*
*
* @author DiffusionData Limited
*
* @since 6.7
*/
public interface Metrics extends Feature {
/**
* The common base interface for metric collectors.
*/
interface MetricCollector {
/**
* Returns the name of the metric collector.
*
* @return the name of the metric collector
*/
String getName();
/**
* Indicates whether the metric collector exports to Prometheus.
*
* @return true if exporting to Prometheus
*/
boolean exportsToPrometheus();
/**
* Limit the number of groups maintained by this metric collector.
*
* Session metric collectors can
* {@link SessionMetricCollector#getGroupByProperties() group metrics by
* property}. Topic metric collectors can
* {@link TopicMetricCollector#groupsByTopicType() group metrics by
* topic type}. This property places an upper limit on the number of
* groups that will be maintained for the metric collector.
*
*
For example,
* if a session metric collector groups by {@code $SessionId} and
* maximumGroups is 10, then metrics will only be collected for the
* first 10 sessions.
*
* @return the maximum number of sub-groups maintained by this metric
* collector
* @since 6.8
*/
int maximumGroups();
}
/**
* Common interface for metric collector builders.
*
* @since 6.8
* @param type of concrete Builder
*/
interface Builder> {
/**
* Reset the builder.
*
* @return this Builder
*/
B reset();
/**
* Specifies whether the metric collector should export metrics to
* Prometheus or not.
*
* By default, metrics are not exported to Prometheus.
*
* @param export true to export metrics to Prometheus
*
* @return this builder
*/
B exportToPrometheus(boolean export);
/**
* Set the maximum number of groups maintained by the metric collector.
*
* By default, the number of groups is not limited.
*
* @param limit a positive integer
* @return the maximum number of groups
* @see MetricCollector#maximumGroups()
* @since 6.8
*/
B maximumGroups(int limit);
}
/**
* The definition of a session metric collector.
*
* These can be configured to record metric data for a subset of all
* sessions, specified with a session filter.
*/
interface SessionMetricCollector extends MetricCollector {
/**
* Returns the session filter.
*
* @return the session filter
*/
String getSessionFilter();
/**
* Returns the list of properties to group by.
*
* @return list of properties to group by
*/
List getGroupByProperties();
/**
* Indicates whether metrics with no matches should be removed.
*
* @return true if metrics with no matches should be removed
*/
boolean removesMetricsWithNoMatches();
/**
* A session metric collector builder.
*
* A builder of this type may be created using
* {@link Diffusion#newSessionMetricCollectorBuilder
* newSessionMetricCollectorBuilder} and used to create instances of
* {@link SessionMetricCollector} that can be supplied to
* {@link Metrics#putSessionMetricCollector putSessionMetricCollector}.
*/
interface Builder extends Metrics.Builder {
/**
* Adds the name of a session property to group by to the list known
* to this builder.
*
* By default a builder will initially have no session properties to
* group by set.
*
* @param propertyName the name of the session property. See
* {@link Session} for details of session properties
*
* @return this builder
*/
Builder groupByProperty(String propertyName);
/**
* Specifies a list of session property names to group by, replacing
* any current list known to this builder.
*
* @param propertyNames a list of session property names. See
* {@link Session} for details of session properties
*
* @return this builder
*/
Builder groupByProperties(List propertyNames);
/**
* Specifies whether the metric collector should remove any metrics
* that have no matches.
*
* The default is that the metric collector will not remove metrics
* with no matches.
*
* @param remove true to indicate that metrics with no matches
* should be removed
*
* @return this builder
*/
Builder removeMetricsWithNoMatches(boolean remove);
/**
* Create a new {@link SessionMetricCollector} using the values
* currently known to this builder.
*
* @param name the name of the {@link SessionMetricCollector}
*
* @param sessionFilter the session filter indicating the sessions
* this collector should apply to. The format of a session
* property filter is documented in {@link Session}
*
* @return a new {@link SessionMetricCollector} with all of the
* current settings of this builder
*/
SessionMetricCollector create(String name, String sessionFilter);
}
}
/**
* The definition of a topic metric collector.
*
* These can be configured to record metric data for a subset of all topics,
* specified with a topic selector.
*/
interface TopicMetricCollector extends MetricCollector {
/**
* Returns the topic selector.
*
* @return topic selector
*/
String getTopicSelector();
/**
* Indicates whether the collector groups by topic type.
*
* @return true if grouping by topic type
*/
boolean groupsByTopicType();
/**
* Indicates whether the collector groups by topic view.
*
* @return true if grouping by topic view
* @since 6.9
*/
boolean groupsByTopicView();
/**
* Returns the number of leading parts of the topic path to group by.
*
* @return the number of leading parts of the topic path to group by, or
* 0 if the collector does not group by path prefix
* @since 6.8
*/
int groupByPathPrefixParts();
/**
* A topic metric collector builder.
*
* A builder of this type may be created using
* {@link Diffusion#newTopicMetricCollectorBuilder
* newTopicMetricCollectorBuilder} and used to create instances of
* {@link TopicMetricCollector} that can be supplied to
* {@link Metrics#putTopicMetricCollector putTopicMetricCollector}.
*/
interface Builder extends Metrics.Builder {
/**
* Specifies whether the metric collector should group by topic
* type.
*
* By default a topic metric collector does not group by topic type.
*
* @param groupByTopicType true to indicate that the collector
* should group by topic type
*
* @return this builder
*/
Builder groupByTopicType(boolean groupByTopicType);
/**
* Specifies the number of leading parts of the topic path the
* metric collector should use to group results.
*
*
* By default a topic metric collector does not group by the topic
* path prefix. If a positive number of parts is specified, it
* will enable grouping.
*
* @param parts the number of leading parts of the topic path to
* group by; set to 0 to disable grouping by path
* @return this builder
* @since 6.8
*/
Builder groupByPathPrefixParts(int parts);
/**
* Specifies whether the metric collector should group by topic view.
*
* By default a topic metric collector does not group by topic view.
*
* @param groupByTopicView true to indicate that the collector should group by topic view
* @return this builder
* @since 6.9
*/
Builder groupByTopicView(boolean groupByTopicView);
/**
* Create a new {@link TopicMetricCollector} using the values
* currently known to this builder.
*
* @param name the name of the {@link TopicMetricCollector}
*
* @param topicSelector the selector pattern that specifies the
* topics for which metrics are to be collected
*
* @return a new {@link TopicMetricCollector} with all of the
* current settings of this builder
* @throws IllegalArgumentException if this builder has been
* configured using {@link #groupByPathPrefixParts(int)} and
* a negative number of parts
*/
TopicMetricCollector create(String name, String topicSelector);
}
}
/**
* Enumeration defining the metric types available. These match the types defined in the
*
* OpenMetrics specification.
*
*
* @since 6.10
*/
enum MetricType {
/**
* Counters measure discrete events. Common examples are the number of HTTP requests received, CPU seconds
* spent, or bytes sent. Counters are always monotonic, and are typically used to count events.
*/
COUNTER,
/**
* Gauges are current measurements, such as bytes of memory currently used or the number of items in a queue.
*/
GAUGE,
/**
* Info metrics are used to expose textual information which SHOULD NOT change during process lifetime.
* Common examples are an application's version, revision control commit, and the version of a compiler.
*/
INFO,
/**
* Histograms measure distributions of discrete events. Common examples are the latency of HTTP requests,
* function runtimes, or I/O request sizes.
*/
HISTOGRAM,
/**
* GaugeHistograms measure current distributions. Common examples are how long items have been waiting in a
* queue, or size of the requests in a queue.
*/
GAUGE_HISTOGRAM,
/**
* StateSets represent a series of related boolean values, also called a bitset.
*/
STATE_SET,
/**
* Like Histograms, Summaries measure distributions of discrete events and MAY be used when
* Histograms are too expensive and/or an average event size is sufficient.
*/
SUMMARY,
/**
* An unknown metric type.
*/
UNKNOWN,
}
/**
* Represents a single metric sample.
* @since 6.10
*/
interface MetricSample {
/**
* Returns the name of the metric sample.
* @return the name of the metric sample
*/
String getName();
/**
* Returns the list of label names for the metric sample. The nth label name corresponds to the nth label value.
* @return the list of label names
*/
List getLabelNames();
/**
* Returns the list of label values for the metric sample. The nth label value corresponds to the nth label
* name.
* @return the list of label values
*/
List getLabelValues();
/**
* Returns the timestamp for the metric sample.
* @return an Optional containing the timestamp if present, otherwise an empty Optional
*/
Optional getTimestamp();
/**
* Returns the value of the metric sample.
* @return the value of the metric sample
*/
double getValue();
}
/**
* Represents a collection of metric samples.
* @since 6.10
*/
interface MetricSampleCollection {
/**
* Returns the name of the metric sample collection.
* @return the name of the metric sample collection
*/
String getName();
/**
* Returns the type of the metric samples in the collection.
* @return the MetricType for the samples in the collection
*/
MetricType getType();
/**
* Returns the unit of measurement for the metric samples in the collection.
* @return the unit of measurement for the metric samples
*/
String getUnit();
/**
* Returns the list of metric samples in the collection.
* @return the list of metric samples
*/
List getSamples();
}
/**
* A parameterized query that can be used to fetch metrics from the server.
*
* A new request can be created with {@link Metrics#metricsRequest()}}. Requests are immutable.
* The {@link #server(String)}, {@link #currentServer()} and {@link #filter(Set)} methods can be used to create
* a configured request that either limits the metrics to a specific server or filters the metrics returned.
*
* By default, the request will fetch metrics from all servers and will not filter the metrics.
*
* The metrics are the same as those exposed by the Prometheus endpoint when requesting metrics in the OpenMetrics
* format.
*
*
* @since 6.10
*/
interface MetricsRequest {
/**
* Allows specifying a set of filters to limit the metrics returned.
*
* The filter may not be null. If the filter is empty then all metrics are returned.
*
* The filter is a set of strings. The filter matches a String if the String equals any member of the filter.
*
* Metrics are included only if:
*
* -
* The filter matches a {@link MetricSampleCollection} name, in which case the entire collection
* and its samples are returned.
*
* -
* The filter doesn't match a {@link MetricSampleCollection} name but matches at least one of its
* {@link MetricSample} children. In this case, the {@link MetricSampleCollection} is
* returned with only the matching child {@link MetricSample}s.
*
*
*
* Only the last filter set by either this method or {@link #filter(Pattern)} will be applied.
*
* @param filters the set of filters to use
* @return a new request derived from this fetch request but with the specified filters
*/
MetricsRequest filter(Set filters);
/**
* Allows specifying a regular expression to filter the metrics returned.
*
* The filter may not be null.
*
* Similarly to {@link #filter(Set)}, metrics are included only if:
*
* -
* The regular expression matches a {@link MetricSampleCollection} name, in which case the
* entire collection and its samples are returned.
*
* -
* The regular expression doesn't match a {@link MetricSampleCollection} name but matches at
* least one of its {@link MetricSample} children. In this case, the {@link MetricSampleCollection} is
* returned with only the matching child {@link MetricSample}s.
*
*
*
* Only the last filter set by either this method or {@link #filter(Set)} will be applied.
*
* @param filter a regular expression to use to filter the metrics
* @return a new request derived from this fetch request but with the specified filter
*/
MetricsRequest filter(Pattern filter);
/**
* Specifies the name of the server to fetch metrics from. This is the configured server name.
*
* @param server the name of the server to fetch metrics from
* @return a new request derived from this fetch request but with the specified server
*/
MetricsRequest server(String server);
/**
* Specifies that metrics should be fetched from the server to which the current session is connected.
*
* @return a new request derived from this fetch request but which will collect metrics from the current server
*/
MetricsRequest currentServer();
/**
* Fetches the metrics from the server.
*
* If the fetch operation completes successfully, the CompletableFuture result
* will contain a {@link MetricsResult} that can be used to access the metrics.
*
* Otherwise, the CompletableFuture will complete exceptionally with
* a {@link CompletionException}. Common reasons for failure, listed
* by the exception reported as the
* {@link CompletionException#getCause() cause}, include:
*
*
* - {@link PermissionsException} – if the calling
* session does not have {@link GlobalPermission#VIEW_SERVER}
* permission;
*
- {@link ClusterRoutingException} – if the operation
* failed due to a transient cluster error;
*
- {@link SessionClosedException} – if the session is
* closed.
*
*
* If all metrics for a server are filtered out then the result will still contain an empty entry for that
* server.
*
* If either {@link #server(String)} or {@link #currentServer()} has been called then the result will contain an
* entry for that server only. Otherwise, it will contain an entry for each server in the cluster.
*
* @return a CompletableFuture that will complete with the metrics
*/
CompletableFuture fetch();
}
/**
* The result of a fetch metrics operation, initiated by a {@link MetricsRequest}.
*
* @since 6.10
*/
interface MetricsResult {
/**
* Returns a list of server names for which the result has metrics.
* The names may be used with {@link #getMetrics(String)}.
*
* @return a set of server names
*/
Set getServerNames();
/**
* Returns the metrics for a server.
*
* @param serverName the name of the server
* @return the metrics for the server
*/
List getMetrics(String serverName);
}
/**
* Add a session metric collector, replacing any with the same name.
*
* @param collector the session metric collector
*
* @return a CompletableFuture that completes when a response is received
* from the server.
*
*
* If the task completes successfully, the CompletableFuture result
* will be null. The result type is any rather than Void to provide
* forward compatibility with future iterations of this API that may
* provide a non-null result with a more specific result type.
*
*
* Otherwise, the CompletableFuture will complete exceptionally with
* a {@link CompletionException}. Common reasons for failure, listed
* by the exception reported as the
* {@link CompletionException#getCause() cause}, include:
*
*
* - {@link InvalidFilterException} – if the metric
* collector session filter is invalid;
*
- {@link PermissionsException} – if the calling
* session does not have {@link GlobalPermission#CONTROL_SERVER
* CONTROL_SERVER} permission;
*
- {@link ClusterRoutingException} – if the operation
* failed due to a transient cluster error;
*
- {@link SessionClosedException} – if the session is
* closed.
*
*/
CompletableFuture> putSessionMetricCollector(
SessionMetricCollector collector);
/**
* Retrieves the current session metric collectors.
*
* @return a CompletableFuture that completes when a response is received
* from the server.
*
*
* If the task completes successfully, the CompletableFuture result
* will be a list of current session metric collectors.
*
*
* Otherwise, the CompletableFuture will complete exceptionally with
* a {@link CompletionException}. Common reasons for failure, listed
* by the exception reported as the
* {@link CompletionException#getCause() cause}, include:
*
*
* - {@link PermissionsException} – if the calling
* session does not have {@link GlobalPermission#VIEW_SERVER
* VIEW_SERVER} permission;
*
- {@link SessionClosedException} – if the session is
* closed.
*
*/
CompletableFuture>
listSessionMetricCollectors();
/**
* Removes any session metric collector with the given name, if it exists.
*
* @param name the session metric collector name
*
* @return a CompletableFuture that completes when a response is received
* from the server.
*
*
* If the task completes successfully, the CompletableFuture result
* will be null. The result type is any rather than Void to provide
* forward compatibility with future iterations of this API that may
* provide a non-null result with a more specific result type.
*
*
* Otherwise, the CompletableFuture will complete exceptionally with
* a {@link CompletionException}. Common reasons for failure, listed
* by the exception reported as the
* {@link CompletionException#getCause() cause}, include:
*
*
* - {@link PermissionsException} – if the calling
* session does not have {@link GlobalPermission#CONTROL_SERVER
* CONTROL_SERVER} permission;
*
- {@link ClusterRoutingException} – if the operation
* failed due to a transient cluster error;
*
- {@link SessionClosedException} – if the session is
* closed.
*
*/
CompletableFuture> removeSessionMetricCollector(String name);
/**
* Add a topic metric collector, replacing any with the same name.
*
* A {@link TopicMetricCollector} instance can be created using
* {@link Diffusion#newTopicMetricCollectorBuilder
* newTopicMetricCollectorBuilder}.
*
* @param collector the topic metric collector
*
* @return a CompletableFuture that completes when a response is received
* from the server.
*
*
* If the task completes successfully, the CompletableFuture result
* will be null. The result type is any rather than Void to provide
* forward compatibility with future iterations of this API that may
* provide a non-null result with a more specific result type.
*
*
* Otherwise, the CompletableFuture will complete exceptionally with
* a {@link CompletionException}. Common reasons for failure, listed
* by the exception reported as the
* {@link CompletionException#getCause() cause}, include:
*
*
* - {@link PermissionsException} – if the calling
* session does not have {@link GlobalPermission#CONTROL_SERVER
* CONTROL_SERVER} permission;
*
- {@link ClusterRoutingException} – if the operation
* failed due to a transient cluster error;
*
- {@link SessionClosedException} – if the session is
* closed.
*
*/
CompletableFuture> putTopicMetricCollector(
TopicMetricCollector collector);
/**
* Retrieves the current topic metric collectors.
*
* @return a CompletableFuture that completes when a response is received
* from the server.
*
*
* If the task completes successfully, the CompletableFuture result
* will be a list of current topic metric collectors.
*
*
* Otherwise, the CompletableFuture will complete exceptionally with
* a {@link CompletionException}. Common reasons for failure, listed
* by the exception reported as the
* {@link CompletionException#getCause() cause}, include:
*
*
* - {@link PermissionsException} – if the calling
* session does not have {@link GlobalPermission#VIEW_SERVER
* VIEW_SERVER} permission;
*
- {@link SessionClosedException} – if the session is
* closed.
*
*/
CompletableFuture> listTopicMetricCollectors();
/**
* Removes any topic metric collector with the given name, if it exists.
*
* @param name the topic metric collector name
*
* @return a CompletableFuture that completes when a response is received
* from the server.
*
*
* If the task completes successfully, the CompletableFuture result
* will be null. The result type is any rather than Void to provide
* forward compatibility with future iterations of this API that may
* provide a non-null result with a more specific result type.
*
*
* Otherwise, the CompletableFuture will complete exceptionally with
* a {@link CompletionException}. Common reasons for failure, listed
* by the exception reported as the
* {@link CompletionException#getCause() cause}, include:
*
*
* - {@link PermissionsException} – if the calling
* session does not have {@link GlobalPermission#CONTROL_SERVER
* CONTROL_SERVER} permission;
*
- {@link ClusterRoutingException} – if the operation
* failed due to a transient cluster error;
*
- {@link SessionClosedException} – if the session is
* closed.
*
*/
CompletableFuture> removeTopicMetricCollector(String name);
/**
* Creates an unconfigured {@link MetricsRequest}. The request can be invoked using
* {@link MetricsRequest#fetch()} to retrieve metrics for the server or cluster.
*
* See {@link MetricsRequest} for more information.
*
* @return a new {@link MetricsRequest}
*
* @since 6.10
*/
MetricsRequest metricsRequest();
}