Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic metrics discovery #15650

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions hazelcast-build-utils/src/test/resources/manifest.mf
Expand Up @@ -272,7 +272,7 @@ Export-Package: com.hazelcast.cluster.impl;uses:="com.hazelcast.loggin
nternal.serialization,com.hazelcast.security.permission,com.hazelcast
.spi";version="3.8.0.SNAPSHOT",com.hazelcast.internal.memory;uses:="com.hazelc
ast.internal.util";version="3.8.0.SNAPSHOT",com.hazelcast.internal.metrics;use
s:="com.hazelcast.internal.metrics.renderers";version="3.8.0.SNAPSHOT
s:="com.hazelcast.internal.metrics.collectors";version="3.8.0.SNAPSHOT
",com.hazelcast.internal.util.sort;uses:="com.hazelcast.internal.memo
ry,com.hazelcast.nio";version="3.8.0.SNAPSHOT",com.hazelcast.map.impl
.nearcache;uses:="com.hazelcast.internal.adapter,com.hazelcast.monito
Expand Down Expand Up @@ -1446,7 +1446,7 @@ Export-Package: com.hazelcast.cluster.impl;uses:="com.hazelcast.loggin
internal.metrics,com.hazelcast.internal.util,com.hazelcast.nio,com.hazelcast.m
emory,com.hazelcast.spi.impl.operationservice.impl,com.hazelcast.spi,
com.hazelcast.spi.impl.operationservice,com.hazelcast.core,com.hazelc
ast.internal.cluster,com.hazelcast.internal.metrics.renderers,com.haz
ast.internal.cluster,com.hazelcast.internal.metrics.collectors,com.haz
elcast.spi.impl.operationservice.impl.operations,com.hazelcast.nio.tc
p,com.hazelcast.internal.networking.spinning,com.hazelcast.spi.serial
ization,com.hazelcast.internal.networking,com.hazelcast.internal.netw
Expand Down
Expand Up @@ -18,13 +18,13 @@

import com.hazelcast.internal.metrics.MetricsRegistry;
import com.hazelcast.internal.metrics.Probe;
import com.hazelcast.internal.nio.Connection;
import com.hazelcast.internal.util.counters.MwCounter;
import com.hazelcast.logging.ILogger;
import com.hazelcast.internal.nio.Connection;
import com.hazelcast.spi.impl.eventservice.EventRegistration;
import com.hazelcast.spi.impl.eventservice.EventService;
import com.hazelcast.spi.impl.NodeEngine;
import com.hazelcast.spi.impl.NodeEngineImpl;
import com.hazelcast.spi.impl.eventservice.EventRegistration;
import com.hazelcast.spi.impl.eventservice.EventService;

import javax.security.auth.login.LoginException;
import java.util.Collection;
Expand All @@ -35,9 +35,9 @@

import static com.hazelcast.client.impl.ClientEngineImpl.SERVICE_NAME;
import static com.hazelcast.internal.metrics.ProbeLevel.MANDATORY;
import static com.hazelcast.internal.util.counters.MwCounter.newMwCounter;
import static com.hazelcast.internal.util.Preconditions.checkNotNull;
import static com.hazelcast.internal.util.SetUtil.createHashSet;
import static com.hazelcast.internal.util.counters.MwCounter.newMwCounter;

/**
* Manages and stores {@link com.hazelcast.client.impl.ClientEndpointImpl}s.
Expand All @@ -58,7 +58,7 @@ public ClientEndpointManagerImpl(NodeEngine nodeEngine) {
this.logger = nodeEngine.getLogger(ClientEndpointManager.class);
this.eventService = nodeEngine.getEventService();
MetricsRegistry metricsRegistry = ((NodeEngineImpl) nodeEngine).getMetricsRegistry();
metricsRegistry.scanAndRegister(this, "client.endpoint");
metricsRegistry.registerStaticMetrics(this, "client.endpoint");
}

@Override
Expand Down
Expand Up @@ -329,9 +329,9 @@ private void startMetrics() {
ThreadMetricSet.register(metricsRegistry);
ClassLoadingMetricSet.register(metricsRegistry);
FileMetricSet.register(metricsRegistry);
metricsRegistry.scanAndRegister(clientExtension.getMemoryStats(), "memory");
metricsRegistry.collectMetrics(clientExtension);
metricsRegistry.collectMetrics(executionService);
metricsRegistry.registerStaticMetrics(clientExtension.getMemoryStats(), "memory");
metricsRegistry.provideMetrics(clientExtension);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't say I'm terribly excited about the name 'provide metrics'.

The caller will not provide metrics; it will collect the metrics that were provided.

Copy link
Contributor

@pveentjer pveentjer Oct 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... this is the registration of metrics; not the collection of metrics.

Perhaps we should just call it something with register? I got confused.. so probably an indication of me either being stupid or the API not being that clear (or a combination of these 2).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's named provideMetrics since we call methods on StaticMetricsProvider instances that will register their metrics. There is an indirection. Also since this change metrics collection is the term used for iterating through the known and discovered metrics and collect (publish, render etc) them. I wanted to avoid the name clash with that too.

metricsRegistry.provideMetrics(executionService);
}

private LoadBalancer initLoadBalancer(ClientConfig config) {
Expand Down Expand Up @@ -428,7 +428,7 @@ public void start() {
new EventQueuePlugin(loggingService.getLogger(EventQueuePlugin.class), listenerService.getEventExecutor(),
properties));

metricsRegistry.collectMetrics(listenerService);
metricsRegistry.provideMetrics(listenerService);

proxyManager.init(config, clientContext);
listenerService.start();
Expand Down
Expand Up @@ -16,20 +16,20 @@

package com.hazelcast.client.impl.connection.nio;

import com.hazelcast.client.impl.connection.ClientConnectionManager;
import com.hazelcast.client.impl.clientside.HazelcastClientInstanceImpl;
import com.hazelcast.client.impl.connection.ClientConnectionManager;
import com.hazelcast.client.impl.protocol.ClientMessage;
import com.hazelcast.client.impl.spi.impl.listener.AbstractClientListenerService;
import com.hazelcast.core.LifecycleService;
import com.hazelcast.internal.metrics.Probe;
import com.hazelcast.internal.metrics.ProbeLevel;
import com.hazelcast.internal.networking.Channel;
import com.hazelcast.internal.networking.OutboundFrame;
import com.hazelcast.logging.ILogger;
import com.hazelcast.nio.Address;
import com.hazelcast.internal.nio.Connection;
import com.hazelcast.internal.nio.ConnectionType;
import com.hazelcast.internal.nio.EndpointManager;
import com.hazelcast.logging.ILogger;
import com.hazelcast.nio.Address;

import java.io.EOFException;
import java.io.IOException;
Expand Down Expand Up @@ -189,8 +189,6 @@ public void close(String reason, Throwable cause) {
}

connectionManager.onClose(this);

client.getMetricsRegistry().discardMetrics(this);
}

private void logClose() {
Expand Down
Expand Up @@ -87,7 +87,7 @@ public AbstractClientInvocationService(HazelcastClientInstanceImpl client) {

this.operationBackupTimeoutMillis = properties.getInteger(OPERATION_BACKUP_TIMEOUT_MILLIS);
this.shouldFailOnIndeterminateOperationState = properties.getBoolean(FAIL_ON_INDETERMINATE_OPERATION_STATE);
client.getMetricsRegistry().scanAndRegister(this, "invocations");
client.getMetricsRegistry().registerStaticMetrics(this, "invocations");
}

private long initInvocationRetryPauseMillis() {
Expand Down
Expand Up @@ -17,16 +17,16 @@
package com.hazelcast.client.impl.spi.impl;

import com.hazelcast.client.impl.spi.ClientExecutionService;
import com.hazelcast.internal.metrics.MetricsProvider;
import com.hazelcast.internal.metrics.MetricsRegistry;
import com.hazelcast.internal.metrics.Probe;
import com.hazelcast.internal.metrics.StaticMetricsProvider;
import com.hazelcast.internal.util.RuntimeAvailableProcessors;
import com.hazelcast.internal.util.executor.LoggingScheduledExecutor;
import com.hazelcast.internal.util.executor.PoolExecutorThreadFactory;
import com.hazelcast.logging.ILogger;
import com.hazelcast.logging.LoggingService;
import com.hazelcast.spi.properties.HazelcastProperties;
import com.hazelcast.spi.properties.HazelcastProperty;
import com.hazelcast.internal.util.executor.LoggingScheduledExecutor;
import com.hazelcast.internal.util.executor.PoolExecutorThreadFactory;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
Expand All @@ -41,7 +41,7 @@
import static com.hazelcast.internal.metrics.ProbeLevel.MANDATORY;
import static java.lang.Thread.currentThread;

public final class ClientExecutionServiceImpl implements ClientExecutionService, MetricsProvider {
public final class ClientExecutionServiceImpl implements ClientExecutionService, StaticMetricsProvider {

public static final HazelcastProperty INTERNAL_EXECUTOR_POOL_SIZE
= new HazelcastProperty("hazelcast.client.internal.executor.pool.size", 3);
Expand Down Expand Up @@ -128,7 +128,7 @@ public static void shutdownExecutor(String name, ExecutorService executor, ILogg
}

@Override
public void provideMetrics(MetricsRegistry registry) {
registry.scanAndRegister(this, "executionService");
public void provideStaticMetrics(MetricsRegistry registry) {
registry.registerStaticMetrics(this, "executionService");
}
}
Expand Up @@ -29,7 +29,7 @@
import com.hazelcast.client.impl.spi.ClientListenerService;
import com.hazelcast.client.properties.ClientProperty;
import com.hazelcast.core.HazelcastException;
import com.hazelcast.internal.metrics.MetricsProvider;
import com.hazelcast.internal.metrics.StaticMetricsProvider;
import com.hazelcast.internal.metrics.MetricsRegistry;
import com.hazelcast.internal.metrics.Probe;
import com.hazelcast.logging.ILogger;
Expand Down Expand Up @@ -64,7 +64,7 @@
import static com.hazelcast.internal.metrics.ProbeLevel.MANDATORY;
import static com.hazelcast.internal.util.Preconditions.checkNotNull;

public abstract class AbstractClientListenerService implements ClientListenerService, MetricsProvider, ConnectionListener {
public abstract class AbstractClientListenerService implements ClientListenerService, StaticMetricsProvider, ConnectionListener {

protected final HazelcastClientInstanceImpl client;
protected final SerializationService serializationService;
Expand Down Expand Up @@ -162,8 +162,8 @@ public boolean deregisterListener(@Nullable UUID userRegistrationId) {
}

@Override
public void provideMetrics(MetricsRegistry registry) {
registry.scanAndRegister(this, "listeners");
public void provideStaticMetrics(MetricsRegistry registry) {
registry.registerStaticMetrics(this, "listeners");
}

@Probe(level = MANDATORY)
Expand Down
Expand Up @@ -16,23 +16,24 @@

package com.hazelcast.instance.impl;

import com.hazelcast.internal.cluster.Joiner;
import com.hazelcast.config.Config;
import com.hazelcast.config.InvalidConfigurationException;
import com.hazelcast.config.MemberAddressProviderConfig;
import com.hazelcast.instance.AddressPicker;
import com.hazelcast.internal.cluster.Joiner;
import com.hazelcast.internal.metrics.MetricsRegistry;
import com.hazelcast.internal.networking.ChannelErrorHandler;
import com.hazelcast.internal.networking.Networking;
import com.hazelcast.internal.networking.ServerSocketRegistry;
import com.hazelcast.internal.networking.nio.NioNetworking;
import com.hazelcast.internal.util.InstantiationUtils;
import com.hazelcast.logging.ILogger;
import com.hazelcast.logging.impl.LoggingServiceImpl;
import com.hazelcast.internal.nio.ClassLoaderUtil;
import com.hazelcast.internal.nio.NetworkingService;
import com.hazelcast.internal.nio.NodeIOService;
import com.hazelcast.internal.nio.tcp.TcpIpConnectionChannelErrorHandler;
import com.hazelcast.internal.nio.tcp.TcpIpNetworkingService;
import com.hazelcast.internal.util.InstantiationUtils;
import com.hazelcast.logging.ILogger;
import com.hazelcast.logging.impl.LoggingServiceImpl;
import com.hazelcast.spi.MemberAddressProvider;
import com.hazelcast.spi.properties.HazelcastProperties;

Expand Down Expand Up @@ -146,14 +147,16 @@ public NetworkingService createNetworkingService(Node node, ServerSocketRegistry
Networking networking = createNetworking(node);
Config config = node.getConfig();

return new TcpIpNetworkingService(config,
MetricsRegistry metricsRegistry = node.nodeEngine.getMetricsRegistry();
TcpIpNetworkingService tcpIpNetworkingService = new TcpIpNetworkingService(config,
ioService,
registry,
node.loggingService,
node.nodeEngine.getMetricsRegistry(),
metricsRegistry,
networking,
node.getNodeExtension().createChannelInitializerProvider(ioService),
node.getProperties());
return tcpIpNetworkingService;
}

private Networking createNetworking(Node node) {
Expand Down
Expand Up @@ -250,7 +250,7 @@ public Node(HazelcastInstanceImpl hazelcastInstance, Config staticConfig, NodeCo
config.setConfigurationService(nodeEngine.getConfigurationService());
config.onSecurityServiceUpdated(getSecurityService());
MetricsRegistry metricsRegistry = nodeEngine.getMetricsRegistry();
metricsRegistry.collectMetrics(nodeExtension);
metricsRegistry.provideMetrics(nodeExtension);

networkingService = nodeContext.createNetworkingService(this, serverSocketRegistry);
healthMonitor = new HealthMonitor(this);
Expand Down
Expand Up @@ -149,9 +149,9 @@ public ClusterServiceImpl(Node node, MemberImpl localMember) {

private void registerMetrics() {
MetricsRegistry metricsRegistry = node.nodeEngine.getMetricsRegistry();
metricsRegistry.scanAndRegister(clusterClock, "cluster.clock");
metricsRegistry.scanAndRegister(clusterHeartbeatManager, "cluster.heartbeat");
metricsRegistry.scanAndRegister(this, "cluster");
metricsRegistry.registerStaticMetrics(clusterClock, "cluster.clock");
metricsRegistry.registerStaticMetrics(clusterHeartbeatManager, "cluster.heartbeat");
metricsRegistry.registerStaticMetrics(this, "cluster");
}

@Override
Expand Down
Expand Up @@ -18,7 +18,7 @@

import com.hazelcast.internal.metrics.MetricsRegistry;
import com.hazelcast.internal.metrics.ProbeLevel;
import com.hazelcast.internal.metrics.renderers.ProbeRenderer;
import com.hazelcast.internal.metrics.collectors.MetricsCollector;
import com.hazelcast.logging.ILogger;
import com.hazelcast.spi.impl.NodeEngineImpl;
import com.hazelcast.spi.properties.HazelcastProperties;
Expand Down Expand Up @@ -49,7 +49,7 @@ public class MetricsPlugin extends DiagnosticsPlugin {

private final MetricsRegistry metricsRegistry;
private final long periodMillis;
private final ProbeRendererImpl probeRenderer = new ProbeRendererImpl();
private final MetricsCollectorImpl probeRenderer = new MetricsCollectorImpl();

public MetricsPlugin(NodeEngineImpl nodeEngine) {
this(nodeEngine.getLogger(MetricsPlugin.class), nodeEngine.getMetricsRegistry(), nodeEngine.getProperties());
Expand Down Expand Up @@ -77,33 +77,33 @@ public void run(DiagnosticsLogWriter writer) {
// we set the time explicitly so that for this particular rendering of the probes, all metrics have exactly
// the same timestamp
probeRenderer.timeMillis = System.currentTimeMillis();
metricsRegistry.render(probeRenderer);
metricsRegistry.collect(probeRenderer);
probeRenderer.writer = null;
}

private static class ProbeRendererImpl implements ProbeRenderer {
private static class MetricsCollectorImpl implements MetricsCollector {
private static final String SECTION_NAME = "Metric";

private DiagnosticsLogWriter writer;
private long timeMillis;

@Override
public void renderLong(String name, long value) {
public void collectLong(String name, long value) {
writer.writeSectionKeyValue(SECTION_NAME, timeMillis, name, value);
}

@Override
public void renderDouble(String name, double value) {
public void collectDouble(String name, double value) {
writer.writeSectionKeyValue(SECTION_NAME, timeMillis, name, value);
}

@Override
public void renderException(String name, Exception e) {
public void collectException(String name, Exception e) {
writer.writeSectionKeyValue(SECTION_NAME, timeMillis, name, e.getClass().getName() + ':' + e.getMessage());
}

@Override
public void renderNoValue(String name) {
public void collectNoValue(String name) {
writer.writeSectionKeyValue(SECTION_NAME, timeMillis, name, "NA");
}
}
Expand Down
Expand Up @@ -18,7 +18,7 @@

/**
* A {@link ProbeFunction} that provides a double value and can be used to
* create a probe using {@link MetricsRegistry#register(Object, String, ProbeLevel, LongProbeFunction)}
* create a probe using {@link MetricsRegistry#registerStaticProbe(Object, String, ProbeLevel, LongProbeFunction)}
*
* @param <S> the type of the source object.
* @see LongProbeFunction
Expand Down
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2008-2019, Hazelcast, Inc. All Rights Reserved.
*
* Licensed 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 com.hazelcast.internal.metrics;

/**
* Interface to be implemented by the classes that expose metrics in a
* dynamic fashion. The {@link #provideDynamicMetrics(MetricTaggerSupplier, MetricsExtractor)}
* method is called in every metric collection cycle. For more on dynamic
* metrics, please see the documentation of {@link MetricsRegistry}.
* <p/>
* Registering instances of this interface should be done by calling
* {@link MetricsRegistry#registerDynamicMetricsProvider(DynamicMetricsProvider)}
*/
public interface DynamicMetricsProvider {

/**
* Metrics collection callback that is called in every metric collection
* cycle. The collected metrics should be passed to the
* {@link MetricsExtractor} passed in argument.
*
* @param extractor The consumer of the collected metrics
*/
void provideDynamicMetrics(MetricTaggerSupplier taggerSupplier, MetricsExtractor extractor);
}
Expand Up @@ -18,7 +18,7 @@

/**
* A {@link ProbeFunction} that provides a long value and can be used to create
* a probe using {@link MetricsRegistry#register(Object, String, ProbeLevel, LongProbeFunction)}
* a probe using {@link MetricsRegistry#registerStaticProbe(Object, String, ProbeLevel, LongProbeFunction)}
*
* @param <S> the type of the source object.
* @see DoubleProbeFunction
Expand Down