All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tacitknowledge.slowlight.proxyserver.metrics.ThroughputHandler Maven / Gradle / Ivy

The newest version!
package com.tacitknowledge.slowlight.proxyserver.metrics;

import com.netflix.servo.annotations.DataSourceType;
import com.netflix.servo.annotations.Monitor;
import com.netflix.servo.monitor.Monitors;
import com.tacitknowledge.slowlight.proxyserver.config.HandlerConfig;
import com.tacitknowledge.slowlight.proxyserver.handler.AbstractChannelHandler;
import io.netty.buffer.ByteBuf;

import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * A {@link io.netty.channel.ChannelHandler} implementation that computes
 * throughput as bytes per second. The metric is determined at two levels :
 *
 *  Frame  - inside a specified time frame
 *  Channel - throughput determined per test session
 *
 *  See also :
 *
 *      {@link com.tacitknowledge.slowlight.proxyserver.metrics.InThroughputHandler}
 *
 *      and
 *
 *      {@link com.tacitknowledge.slowlight.proxyserver.metrics.OutThroughputHandler}
 *
 * @author Pavel Sorocun ([email protected])
 */
public class ThroughputHandler extends AbstractChannelHandler
{
    public static final TimeUnit SECONDS = TimeUnit.SECONDS;
    public static final TimeUnit MILLISECONDS = TimeUnit.MILLISECONDS;

    private Date startDate = new Date();
    private AtomicLong frameReadBytes = new AtomicLong(0);
    private AtomicLong channelBytes = new AtomicLong(0);

    public ThroughputHandler(final HandlerConfig handlerConfig)
    {
        super(handlerConfig);

        Monitors.registerObject(handlerConfig.getName(), this);
    }

    protected void updateThroughputMetric(final Object msg)
    {
        final long readableBytes = ((ByteBuf) msg).readableBytes();

        if(readableBytes > Long.MAX_VALUE - channelBytes.longValue())
        {
            channelBytes.getAndSet(0);
        }

        frameReadBytes.getAndAdd(readableBytes);
        channelBytes.getAndAdd(readableBytes);
    }

    @Monitor(name = "FrameThroughput(bytes_per_second)", type = DataSourceType.GAUGE)
    public long getFrameThroughput()
    {
        return getFrameReadBytes() / SECONDS.convert(getFrameTimeElapsed(), MILLISECONDS);
    }

    @Monitor(name = "ChannelThroughput(bytes_per_second)", type = DataSourceType.GAUGE)
    public long getChannelThroughput()
    {
        return getChannelBytes() / SECONDS.convert(getSessionTimeElapsed(), MILLISECONDS);
    }

    protected void timerCallback()
    {
        frameReadBytes.getAndSet(0);
    }

    public long getSessionTimeElapsed()
    {
        return System.currentTimeMillis() - startDate.getTime();
    }

    public long getFrameTimeElapsed()
    {
        return getSessionTimeElapsed() % (MILLISECONDS.convert(getTimeFrame(), SECONDS));
    }

    public long getFrameReadBytes()
    {
        return frameReadBytes.longValue();
    }

    public long getChannelBytes()
    {
        return channelBytes.longValue();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy