Skip to content

Commit

Permalink
Metrics Integration
Browse files Browse the repository at this point in the history
  • Loading branch information
pveentjer committed Jul 16, 2015
1 parent 4716e1f commit 30c4ae0
Show file tree
Hide file tree
Showing 92 changed files with 3,405 additions and 1,310 deletions.
3 changes: 3 additions & 0 deletions checkstyle/suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -582,5 +582,8 @@
<!-- Taken from JBOSS project, suppress checkstyles -->
<suppress checks="" files="com/hazelcast/buildutils/ElementParser"/>


<suppress checks="ReturnCount" files="com.hazelcast.internal.metrics.impl.FieldProbe"/>
<suppress checks="ReturnCount" files="com.hazelcast.internal.metrics.impl.MethodProbe"/>
</suppressions>

Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@

import com.hazelcast.client.ClientEndpoint;
import com.hazelcast.client.ClientEndpointManager;

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

import javax.security.auth.login.LoginException;
import java.util.Collection;
Expand All @@ -32,6 +37,7 @@
import java.util.concurrent.TimeUnit;

import static com.hazelcast.util.Preconditions.checkNotNull;
import static com.hazelcast.util.counters.MwCounter.newMwCounter;

/**
* Manages and stores {@link com.hazelcast.client.impl.ClientEndpointImpl}s.
Expand All @@ -43,13 +49,21 @@ public class ClientEndpointManagerImpl implements ClientEndpointManager {
private final ILogger logger;
private final ClientEngineImpl clientEngine;
private final NodeEngine nodeEngine;

@Probe(name = "count")
private final ConcurrentMap<Connection, ClientEndpoint> endpoints =
new ConcurrentHashMap<Connection, ClientEndpoint>();

@Probe(name = "totalRegistrations")
private MwCounter totalRegistrations = newMwCounter();

public ClientEndpointManagerImpl(ClientEngineImpl clientEngine, NodeEngine nodeEngine) {
this.clientEngine = clientEngine;
this.nodeEngine = nodeEngine;
this.logger = nodeEngine.getLogger(ClientEndpointManager.class);

MetricsRegistry metricsRegistry = ((NodeEngineImpl) nodeEngine).getMetricsRegistry();
metricsRegistry.scanAndRegister(this, "client.endpoint");
}

@Override
Expand Down Expand Up @@ -79,6 +93,8 @@ public void registerEndpoint(ClientEndpoint endpoint) {
final Connection conn = endpoint.getConnection();
if (endpoints.putIfAbsent(conn, endpoint) != null) {
logger.severe("An endpoint already exists for connection:" + conn);
} else {
totalRegistrations.inc();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@
package com.hazelcast.cluster.impl;

import com.hazelcast.cluster.ClusterClock;
import com.hazelcast.internal.metrics.Probe;
import com.hazelcast.logging.ILogger;
import com.hazelcast.util.Clock;


public class ClusterClockImpl implements ClusterClock {

private final ILogger logger;

private volatile long clusterTimeDiff = Long.MAX_VALUE;
private volatile long clusterStartTime = Long.MIN_VALUE;

public ClusterClockImpl(ILogger logger) {
this.logger = logger;
}

@Probe(name = "clusterTime")
@Override
public long getClusterTime() {
return Clock.currentTimeMillis() + ((clusterTimeDiff == Long.MAX_VALUE) ? 0 : clusterTimeDiff);
Expand All @@ -44,11 +47,13 @@ public void setMasterTime(long masterTime) {
this.clusterTimeDiff = diff;
}

@Probe(name = "clusterTimeDiff")
@Override
public long getClusterTimeDiff() {
return (clusterTimeDiff == Long.MAX_VALUE) ? 0 : clusterTimeDiff;
}

@Probe(name = "clusterUpTime")
@Override
public long getClusterUpTime() {
return Clock.currentTimeMillis() - clusterStartTime;
Expand All @@ -60,8 +65,14 @@ public void setClusterStartTime(long startTime) {
}
}

@Probe(name = "localClockTime")
private long getLocalClockTime() {
return Clock.currentTimeMillis();
}

@Probe(name = "clusterStartTime")
public long getClusterStartTime() {
return clusterStartTime;
return clusterStartTime;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
import com.hazelcast.instance.LifecycleServiceImpl;
import com.hazelcast.instance.MemberImpl;
import com.hazelcast.instance.Node;
import com.hazelcast.internal.metrics.MetricsRegistry;
import com.hazelcast.internal.metrics.Probe;
import com.hazelcast.logging.ILogger;
import com.hazelcast.nio.Address;
import com.hazelcast.nio.Connection;
Expand Down Expand Up @@ -163,6 +165,7 @@ public final class ClusterServiceImpl implements ClusterService, ConnectionListe

private volatile boolean joinInProgress = false;

@Probe(name = "lastHeartBeat")
private volatile long lastHeartBeat = 0L;

private long timeToStartJoin = 0;
Expand Down Expand Up @@ -198,6 +201,14 @@ public ClusterServiceImpl(final Node node) {
icmpTtl = node.groupProperties.ICMP_TTL.getInteger();
icmpTimeout = node.groupProperties.ICMP_TIMEOUT.getInteger();
node.connectionManager.addConnectionListener(this);

registerMetrics();
}

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

@Override
Expand Down Expand Up @@ -1379,6 +1390,7 @@ public Member getLocalMember() {
return node.getLocalMember();
}

@Probe(name = "size")
@Override
public int getSize() {
final Collection<MemberImpl> members = getMemberList();
Expand Down
74 changes: 64 additions & 10 deletions hazelcast/src/main/java/com/hazelcast/instance/GroupProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,48 @@ public class GroupProperties {
* the future, all kinds of new metrics will be added.
* <p/>
* The performance monitor logs all metrics into the log file.
*
* The default is false.
*/
public static final String PROP_PERFORMANCE_MONITOR_ENABLED = "hazelcast.performance.monitoring.enabled";

/**
* The delay in seconds between monitor of the performance.
*
* The default is 30 seconds.
*/
public static final String PROP_PERFORMANCE_MONITOR_DELAY_SECONDS
= "hazelcast.performance.monitor.delay.seconds";

/**
* The PerformanceMonitor uses a rolling file approach to prevent eating too much disk space.
*
* This property sets the maximum size in MB for a single file.
*
* Every HazelcastInstance will get its own history of log files.
*
* The default is 10.
*/
public static final String PROP_PERFORMANCE_MONITOR_MAX_ROLLED_FILE_SIZE_MB
= "hazelcast.performance.monitor.max.rolled.file.size.mb";

/**
* The PerformanceMonitor uses a rolling file approach to prevent eating too much disk space.
*
* This property sets the maximum number of rolling files to keep on disk.
*
* The default is 10.
*/
public static final String PROP_PERFORMANCE_MONITORING_ENABLED = "hazelcast.performance.monitoring.enabled";
public static final String PROP_PERFORMANCE_MONITOR_MAX_ROLLED_FILE_COUNT
= "hazelcast.performance.monitor.max.rolled.file.count";

/**
* The delay in seconds between monitoring of the performance.
* If a human friendly, but more difficult to parse, output format should be selected for dumping the metrics.
*
* The default is true.
*/
public static final String PROP_PERFORMANCE_MONITORING_DELAY_SECONDS = "hazelcast.performance.monitoring.delay.seconds";
public static final String PROP_PERFORMANCE_MONITOR_HUMAN_FRIENDLY_FORMAT
= "hazelcast.performance.monitor.human.friendly.format";

public static final String PROP_VERSION_CHECK_ENABLED = "hazelcast.version.check.enabled";
public static final String PROP_PREFER_IPv4_STACK = "hazelcast.prefer.ipv4.stack";
Expand Down Expand Up @@ -419,9 +455,15 @@ public class GroupProperties {

public final GroupProperty HEALTH_MONITORING_DELAY_SECONDS;

public final GroupProperty PERFORMANCE_MONITORING_ENABLED;
public final GroupProperty PERFORMANCE_MONITOR_ENABLED;

public final GroupProperty PERFORMANCE_MONITORING_DELAY_SECONDS;
public final GroupProperty PERFORMANCE_MONITOR_DELAY_SECONDS;

public final GroupProperty PERFORMANCE_MONITOR_MAX_ROLLED_FILE_SIZE;

public final GroupProperty PERFORMANCE_MONITOR_MAX_ROLLED_FILE_COUNT;

public final GroupProperty PERFORMANCE_MONITOR_HUMAN_FRIENDLY_FORMAT;

public final GroupProperty IO_THREAD_COUNT;

Expand Down Expand Up @@ -601,11 +643,19 @@ public class GroupProperties {
public GroupProperties(Config config) {
HEALTH_MONITORING_LEVEL
= new GroupProperty(config, PROP_HEALTH_MONITORING_LEVEL, HealthMonitorLevel.SILENT.toString());
HEALTH_MONITORING_DELAY_SECONDS = new GroupProperty(config, PROP_HEALTH_MONITORING_DELAY_SECONDS, "30");

PERFORMANCE_MONITORING_ENABLED
= new GroupProperty(config, PROP_PERFORMANCE_MONITORING_ENABLED, "false");
PERFORMANCE_MONITORING_DELAY_SECONDS = new GroupProperty(config, PROP_PERFORMANCE_MONITORING_DELAY_SECONDS, "30");
HEALTH_MONITORING_DELAY_SECONDS
= new GroupProperty(config, PROP_HEALTH_MONITORING_DELAY_SECONDS, "30");

PERFORMANCE_MONITOR_ENABLED
= new GroupProperty(config, PROP_PERFORMANCE_MONITOR_ENABLED, "false");
PERFORMANCE_MONITOR_DELAY_SECONDS
= new GroupProperty(config, PROP_PERFORMANCE_MONITOR_DELAY_SECONDS, "30");
PERFORMANCE_MONITOR_MAX_ROLLED_FILE_SIZE
= new GroupProperty(config, PROP_PERFORMANCE_MONITOR_MAX_ROLLED_FILE_SIZE_MB, "10");
PERFORMANCE_MONITOR_MAX_ROLLED_FILE_COUNT
= new GroupProperty(config, PROP_PERFORMANCE_MONITOR_MAX_ROLLED_FILE_COUNT, "10");
PERFORMANCE_MONITOR_HUMAN_FRIENDLY_FORMAT
= new GroupProperty(config, PROP_PERFORMANCE_MONITOR_HUMAN_FRIENDLY_FORMAT, "true");

VERSION_CHECK_ENABLED = new GroupProperty(config, PROP_VERSION_CHECK_ENABLED, "true");
PREFER_IPv4_STACK = new GroupProperty(config, PROP_PREFER_IPv4_STACK, "true");
Expand Down Expand Up @@ -779,6 +829,10 @@ public boolean getBoolean() {
return Boolean.valueOf(this.value);
}

public float getFloat() {
return Float.valueOf(this.value);
}

public String getString() {
return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
import com.hazelcast.core.ReplicatedMap;
import com.hazelcast.executor.impl.DistributedExecutorService;
import com.hazelcast.internal.monitors.HealthMonitor;
import com.hazelcast.internal.monitors.HealthMonitorLevel;
import com.hazelcast.internal.monitors.PerformanceMonitor;
import com.hazelcast.jmx.ManagementService;
import com.hazelcast.logging.ILogger;
Expand Down Expand Up @@ -107,9 +106,15 @@ public class HazelcastInstanceImpl implements HazelcastInstance {

final ConcurrentMap<String, Object> userContext = new ConcurrentHashMap<String, Object>();

final PerformanceMonitor performanceMonitor;

final HealthMonitor healthMonitor;

HazelcastInstanceImpl(String name, Config config, NodeContext nodeContext)
throws Exception {
this.name = name;


lifecycleService = new LifecycleServiceImpl(this);
ManagedContext configuredManagedContext = config.getManagedContext();
managedContext = new HazelcastManagedContext(this, configuredManagedContext);
Expand All @@ -131,7 +136,9 @@ public class HazelcastInstanceImpl implements HazelcastInstance {

managementService = new ManagementService(this);
initManagedContext(configuredManagedContext);
initMonitors();

this.performanceMonitor = new PerformanceMonitor(this).start();
this.healthMonitor = new HealthMonitor(node).start();
} catch (Throwable e) {
try {
// Terminate the node by terminating node engine,
Expand All @@ -144,11 +151,6 @@ public class HazelcastInstanceImpl implements HazelcastInstance {
}
}

private void initMonitors() {
initHealthMonitor();
initPerformanceMonitor();
}

private void initManagedContext(ManagedContext configuredManagedContext) {
if (configuredManagedContext != null) {
if (configuredManagedContext instanceof HazelcastInstanceAware) {
Expand All @@ -157,27 +159,6 @@ private void initManagedContext(ManagedContext configuredManagedContext) {
}
}

private void initHealthMonitor() {
String healthMonitorLevelString = node.getGroupProperties().HEALTH_MONITORING_LEVEL.getString();
HealthMonitorLevel healthLevel = HealthMonitorLevel.valueOf(healthMonitorLevelString);
if (healthLevel != HealthMonitorLevel.OFF) {
logger.finest("Starting health monitor");
int delaySeconds = node.getGroupProperties().HEALTH_MONITORING_DELAY_SECONDS.getInteger();
new HealthMonitor(this, healthLevel, delaySeconds).start();
}
}

private void initPerformanceMonitor() {
boolean enabled = node.getGroupProperties().PERFORMANCE_MONITORING_ENABLED.getBoolean();
if (!enabled) {
return;
}

logger.finest("Starting performance monitor");
int delaySeconds = node.getGroupProperties().PERFORMANCE_MONITORING_DELAY_SECONDS.getInteger();
new PerformanceMonitor(this, delaySeconds).start();
}

public ManagementService getManagementService() {
return managementService;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2008-2015, 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;

/**
* A DoubleGauge is {link Metric} where a particular double value is read instantaneous. E.g. the current os load.
*
* {@link LongGauge}
*/
public interface DoubleGauge extends Metric {

/**
* Reads the current available value as a double.
*
* If the underlying probe provides a long value, then the value will be converted to
* a floating point value.
*
* If no probe is available, or there are problems obtaining a value from the probe, 0 is returned.
*
* @return the current value.
*/
double read();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
package com.hazelcast.internal.metrics;

/**
* A function that provides a double value and can be used to create a metric using
* {@link MetricsRegistry#register(Object, String, DoubleProbe)}
* A {@link ProbeFunction} that provides a double value and can be used to create a probe using
* {@link MetricsRegistry#register(Object, String, DoubleProbeFunction)}
*
* @param <S> the type of the source object.
* @see LongProbeFunction
*/
public interface DoubleProbe<S> {
public interface DoubleProbeFunction<S> extends ProbeFunction {

/**
* Gets the current value of the source object.
Expand Down

0 comments on commit 30c4ae0

Please sign in to comment.