Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.hazelcast.internal.metrics.impl.MetricsRegistryImpl Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2016, 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.impl;
import com.hazelcast.internal.metrics.DoubleGauge;
import com.hazelcast.internal.metrics.DoubleProbeFunction;
import com.hazelcast.internal.metrics.LongProbeFunction;
import com.hazelcast.internal.metrics.MetricsProvider;
import com.hazelcast.internal.metrics.MetricsRegistry;
import com.hazelcast.internal.metrics.ProbeFunction;
import com.hazelcast.internal.metrics.ProbeLevel;
import com.hazelcast.internal.metrics.renderers.ProbeRenderer;
import com.hazelcast.logging.ILogger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import static com.hazelcast.util.Preconditions.checkNotNull;
import static java.lang.String.format;
/**
* The {@link MetricsRegistry} implementation.
*/
public class MetricsRegistryImpl implements MetricsRegistry {
private static final Comparator COMPARATOR = new Comparator() {
@Override
public int compare(ProbeInstance o1, ProbeInstance o2) {
return o1.name.compareTo(o2.name);
}
};
final ILogger logger;
final ProbeLevel minimumLevel;
private final ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(2);
private final ConcurrentMap probeInstances = new ConcurrentHashMap();
private final ConcurrentMap, SourceMetadata> metadataMap
= new ConcurrentHashMap, SourceMetadata>();
private final LockStripe lockStripe = new LockStripe();
private final AtomicReference sortedProbeInstancesRef
= new AtomicReference(new SortedProbeInstances(0));
/**
* Creates a MetricsRegistryImpl instance.
*
* @param logger the ILogger used
* @param minimumLevel the minimum ProbeLevel. If a probe is registered with a ProbeLevel lower than the minimum ProbeLevel,
* then the registration is skipped.
* @throws NullPointerException if logger or minimumLevel is null
*/
public MetricsRegistryImpl(ILogger logger, ProbeLevel minimumLevel) {
this.logger = checkNotNull(logger, "logger can't be null");
this.minimumLevel = checkNotNull(minimumLevel, "minimumLevel can't be null");
if (logger.isFinestEnabled()) {
logger.finest("MetricsRegistry minimumLevel:" + minimumLevel);
}
}
long modCount() {
return sortedProbeInstancesRef.get().mod;
}
@Override
public Set getNames() {
Set names = new HashSet(probeInstances.keySet());
return Collections.unmodifiableSet(names);
}
/**
* Loads the {@link SourceMetadata}.
*
* @param clazz the Class to be analyzed.
* @return the loaded SourceMetadata.
*/
private SourceMetadata loadSourceMetadata(Class clazz) {
SourceMetadata metadata = metadataMap.get(clazz);
if (metadata == null) {
metadata = new SourceMetadata(clazz);
SourceMetadata found = metadataMap.putIfAbsent(clazz, metadata);
metadata = found == null ? metadata : found;
}
return metadata;
}
@Override
public void scanAndRegister(S source, String namePrefix) {
checkNotNull(source, "source can't be null");
checkNotNull(namePrefix, "namePrefix can't be null");
SourceMetadata metadata = loadSourceMetadata(source.getClass());
metadata.register(this, source, namePrefix);
}
@Override
public void register(S source, String name, ProbeLevel level, LongProbeFunction function) {
checkNotNull(source, "source can't be null");
checkNotNull(name, "name can't be null");
checkNotNull(function, "function can't be null");
checkNotNull(level, "level can't be null");
registerInternal(source, name, level, function);
}
@Override
public void register(S source, String name, ProbeLevel level, DoubleProbeFunction function) {
checkNotNull(source, "source can't be null");
checkNotNull(name, "name can't be null");
checkNotNull(function, "function can't be null");
checkNotNull(level, "level can't be null");
registerInternal(source, name, level, function);
}
ProbeInstance getProbeInstance(String name) {
checkNotNull(name, "name can't be null");
return probeInstances.get(name);
}
void registerInternal(S source, String name, ProbeLevel probeLevel, ProbeFunction function) {
if (!probeLevel.isEnabled(minimumLevel)) {
return;
}
synchronized (lockStripe.getLock(source)) {
ProbeInstance probeInstance = probeInstances.get(name);
if (probeInstance == null) {
probeInstance = new ProbeInstance(name, source, function);
probeInstances.put(name, probeInstance);
} else {
logOverwrite(probeInstance);
}
if (logger.isFinestEnabled()) {
logger.finest("Registered probeInstance " + name);
}
probeInstance.source = source;
probeInstance.function = function;
}
incrementMod();
}
private void incrementMod() {
for (; ; ) {
SortedProbeInstances current = sortedProbeInstancesRef.get();
SortedProbeInstances update = new SortedProbeInstances(current.mod + 1);
if (sortedProbeInstancesRef.compareAndSet(current, update)) {
break;
}
}
}
private void logOverwrite(ProbeInstance probeInstance) {
if (probeInstance.function != null || probeInstance.source != null) {
logger.warning(format("Overwriting existing probe '%s'", probeInstance.name));
}
}
@Override
public LongGaugeImpl newLongGauge(String name) {
checkNotNull(name, "name can't be null");
return new LongGaugeImpl(this, name);
}
@Override
public DoubleGauge newDoubleGauge(String name) {
checkNotNull(name, "name can't be null");
return new DoubleGaugeImpl(this, name);
}
@Override
public void deregister(S source) {
checkNotNull(source, "source can't be null");
boolean changed = false;
for (Map.Entry entry : probeInstances.entrySet()) {
ProbeInstance probeInstance = entry.getValue();
if (probeInstance.source != source) {
continue;
}
String name = entry.getKey();
boolean destroyed = false;
synchronized (lockStripe.getLock(source)) {
if (probeInstance.source == source) {
changed = true;
probeInstances.remove(name);
probeInstance.source = null;
probeInstance.function = null;
destroyed = true;
}
}
if (destroyed && logger.isFinestEnabled()) {
logger.finest("Destroying probeInstance " + name);
}
}
if (changed) {
incrementMod();
}
}
@Override
public void render(ProbeRenderer renderer) {
checkNotNull(renderer, "renderer can't be null");
for (ProbeInstance probeInstance : getSortedProbeInstances()) {
render(renderer, probeInstance);
}
}
@Override
public void collectMetrics(Object... objects) {
for (Object object : objects) {
if (object instanceof MetricsProvider) {
((MetricsProvider) object).provideMetrics(this);
}
}
}
List getSortedProbeInstances() {
for (; ; ) {
SortedProbeInstances current = sortedProbeInstancesRef.get();
if (current.probeInstances != null) {
return current.probeInstances;
}
List probeInstanceList = new ArrayList(probeInstances.values());
Collections.sort(probeInstanceList, COMPARATOR);
SortedProbeInstances update = new SortedProbeInstances(current.mod, probeInstanceList);
if (sortedProbeInstancesRef.compareAndSet(current, update)) {
return update.probeInstances;
}
}
}
private void render(ProbeRenderer renderer, ProbeInstance probeInstance) {
ProbeFunction function = probeInstance.function;
Object source = probeInstance.source;
String name = probeInstance.name;
if (function == null || source == null) {
renderer.renderNoValue(name);
return;
}
try {
if (function instanceof LongProbeFunction) {
LongProbeFunction longFunction = (LongProbeFunction) function;
renderer.renderLong(name, longFunction.get(source));
} else {
DoubleProbeFunction doubleFunction = (DoubleProbeFunction) function;
renderer.renderDouble(name, doubleFunction.get(source));
}
} catch (Exception e) {
renderer.renderException(name, e);
}
}
@Override
public void scheduleAtFixedRate(final Runnable publisher, long period, TimeUnit timeUnit) {
scheduledExecutorService.scheduleAtFixedRate(publisher, 0, period, timeUnit);
}
public void shutdown() {
scheduledExecutorService.shutdown();
}
private static class SortedProbeInstances {
private final long mod;
private final List probeInstances;
private SortedProbeInstances(long mod) {
this.mod = mod;
this.probeInstances = null;
}
public SortedProbeInstances(long mod, List probeInstances) {
this.mod = mod;
this.probeInstances = probeInstances;
}
}
}