com.netflix.servo.monitor.PeakRateCounter Maven / Gradle / Ivy
/**
* Copyright 2013 Netflix, Inc.
*
* 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.netflix.servo.monitor;
import com.netflix.servo.annotations.DataSourceType;
import com.netflix.servo.util.Clock;
import com.netflix.servo.util.ClockWithOffset;
import java.util.concurrent.atomic.AtomicLong;
/**
* The value is the maximum count per second within the specified interval.
*/
public class PeakRateCounter extends AbstractMonitor
implements Counter {
private final Clock clock;
private final AtomicLong currentSecond = new AtomicLong();
private final AtomicLong currentCount = new AtomicLong();
/**
* Creates a counter implementation that records the maximum count per second
* within a specific interval.
*/
public PeakRateCounter(MonitorConfig config) {
this(config, ClockWithOffset.INSTANCE);
}
private final StepLong peakRate;
PeakRateCounter(MonitorConfig config, Clock clock) {
super(config.withAdditionalTag(DataSourceType.GAUGE));
this.clock = clock;
this.peakRate = new StepLong(0L, clock);
}
/**
* {@inheritDoc}
*/
@Override
public Number getValue(int pollerIdx) {
return peakRate.getCurrent(pollerIdx);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || !(obj instanceof PeakRateCounter)) {
return false;
}
final PeakRateCounter c = (PeakRateCounter) obj;
final double v = getValue().doubleValue();
final double otherV = c.getValue().doubleValue();
return config.equals(c.getConfig())
&& Double.compare(v, otherV) == 0;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
int result = getConfig().hashCode();
final long n = Double.doubleToLongBits(getValue().doubleValue());
result = 31 * result + (int) (n ^ (n >>> 32));
return result;
}
/**
* {@inheritDoc}
*/
public String toString() {
return "PeakRateCounter{config=" + config + ", max rate per second=" + getValue() + '}';
}
/**
* {@inheritDoc}
*/
@Override
public void increment() {
increment(1L);
}
private void updatePeakPoller(int idx, long v) {
AtomicLong current = peakRate.getCurrent(idx);
long m = current.get();
while (v > m) {
if (current.compareAndSet(m, v)) {
break;
}
m = current.get();
}
}
private void updatePeak(long v) {
for (int i = 0; i < Pollers.NUM_POLLERS; ++i) {
updatePeakPoller(i, v);
}
}
/**
* {@inheritDoc}
*/
@Override
public void increment(long amount) {
long now = clock.now() / 1000L;
if (now != currentSecond.get()) {
currentCount.set(0);
currentSecond.set(now);
}
long count = currentCount.addAndGet(amount);
updatePeak(count);
}
}