Package com.linkedin.databus2.core.container.monitoring.mbean

Source Code of com.linkedin.databus2.core.container.monitoring.mbean.ContainerTrafficTotalStats

package com.linkedin.databus2.core.container.monitoring.mbean;
/*
*
* Copyright 2013 LinkedIn Corp. 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.
*
*/


import java.io.IOException;
import java.io.OutputStream;
import java.net.ConnectException;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.concurrent.locks.Lock;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.apache.avro.io.JsonEncoder;
import org.apache.avro.specific.SpecificDatumWriter;
import org.apache.log4j.Logger;
import org.jboss.netty.handler.timeout.TimeoutException;

import com.linkedin.databus.core.monitoring.mbean.AbstractMonitoringMBean;
import com.linkedin.databus.core.monitoring.mbean.DatabusMonitoringMBean;
import com.linkedin.databus2.core.container.monitoring.events.ContainerTrafficTotalStatsEvent;

public class ContainerTrafficTotalStats
       extends AbstractMonitoringMBean<ContainerTrafficTotalStatsEvent>
       implements ContainerTrafficTotalStatsMBean
{
  public static final String MODULE = ContainerTrafficTotalStats.class.getName();
  public static final Logger LOG = Logger.getLogger(MODULE);

  private final HashSet<Object> _clients;
  private final String _dimension;
  /** Used to keep track of the timestamp for the last open connection for thread-unsafe (per
   * connection) beans*/
  private long _lastConnOpenTimestamp;
  private long _lastConnOpenMergeTimestamp;

  public ContainerTrafficTotalStats(int containerId, String dimension, boolean enabled,
                                    boolean threadSafe, ContainerTrafficTotalStatsEvent initData)
  {
    super(enabled, threadSafe, initData);
    _clients = new HashSet<Object>(1000);
    _dimension = dimension;
    _event.containerId = containerId;
    _event.dimension = dimension;
    reset();
  }

  public ContainerTrafficTotalStats clone(boolean threadSafe)
  {
    return new ContainerTrafficTotalStats(_event.containerId, _dimension, _enabled.get(),
                                          threadSafe, getStatistics(null));
  }

  @Override
  public long getNumBytes()
  {
    Lock readLock = acquireReadLock();
    long result = 0;
    try
    {
      result = _event.numBytes;
    }
    finally
    {
      releaseLock(readLock);
    }

    return result;
  }

  @Override
  public int getNumClients()
  {
    Lock readLock = acquireReadLock();
    int result = 0;
    try
    {
      result = _event.numClients;
    }
    finally
    {
      releaseLock(readLock);
    }

    return result;
  }

  @Override
  public long getNumClosedConns()
  {
    Lock readLock = acquireReadLock();
    long result = 0;
    try
    {
      result = _event.numClosedConns;
    }
    finally
    {
      releaseLock(readLock);
    }

    return result;
  }

  @Override
  public long getNumOpenConns()
  {
    Lock readLock = acquireReadLock();
    long result = 0;
    try
    {
      result = _event.numOpenConns - _event.numClosedConns;
    }
    finally
    {
      releaseLock(readLock);
    }

    return result;
  }

  @Override
  public long getTimeSinceLastResetMs()
  {
    Lock readLock = acquireReadLock();
    try
    {
      return System.currentTimeMillis() - _event.timestampLastResetMs;
    }
    finally
    {
      releaseLock(readLock);
    }
  }

  @Override
  public long getTimestampLastResetMs()
  {
    Lock readLock = acquireReadLock();
    try
    {
      return _event.timestampLastResetMs;
    }
    finally
    {
      releaseLock(readLock);
    }
  }

  @Override
  public long getTimeClosedConnLifeMs()
  {
    Lock readLock = acquireReadLock();
    try
    {
      return _event.timeClosedConnLifeMs;
    }
    finally
    {
      releaseLock(readLock);
    }
  }

  @Override
  public long getTimeOpenConnLifeMs()
  {
    Lock writeLock = acquireWriteLock();
    try
    {
      long now = (0 == _lastConnOpenTimestamp) ? 0 : System.currentTimeMillis();
      long currentOpenTime = (0 == _lastConnOpenTimestamp) ? 0 : now - _lastConnOpenMergeTimestamp;
      _event.timeOpenConnLifeMs += currentOpenTime;
      _lastConnOpenMergeTimestamp = now;
      return _event.timeOpenConnLifeMs - _event.timeClosedConnLifeMs;
    }
    finally
    {
      releaseLock(writeLock);
    }
  }

  @Override
  public long getErrorTotalCount()
  {
    Lock readLock = acquireReadLock();
    try
    {
      return _event.errorTotalCount;
    }
    finally
    {
      releaseLock(readLock);
    }
  }

  @Override
  public long getErrorConnectCount()
  {
    Lock readLock = acquireReadLock();
    try
    {
      return _event.errorConnectCount;
    }
    finally
    {
      releaseLock(readLock);
    }
  }

  @Override
  public long getErrorTimeoutCount()
  {
    Lock readLock = acquireReadLock();
    try
    {
      return _event.errorTimeoutCount;
    }
    finally
    {
      releaseLock(readLock);
    }
  }

  @Override
  public long getOpenConnsRate()
  {
    return getNumOpenConns();
  }

  @Override
  public long getClosedConnsRate()
  {
    return getNumClosedConns();
  }

  @Override
  public int getClientsRate()
  {
    return getNumClients();
  }

  @Override
  public long getLatencyOpenConn()
  {
    long openConns = getOpenConnsRate();
    return 0 == openConns ? 0 : getTimeOpenConnLifeMs() / openConns;
  }

  @Override
  public long getLatencyClosedConn()
  {
    long closedConns = getClosedConnsRate();
    return 0 == closedConns ? 0 : getTimeClosedConnLifeMs() / closedConns;
  }

  public String getDimension()
  {
    return _dimension;
  }

  public void registerConnectionClose()
  {
    if (! _enabled.get()) return;
    Lock writeLock = acquireWriteLock();

    try
    {
      long now = isThreadSafe() ? 0 : System.currentTimeMillis();
      long connLifespanMs = isThreadSafe() ? 0 : now  - _lastConnOpenTimestamp;
      long unmergedConnLifespanMs = isThreadSafe() ? 0 : now - _lastConnOpenMergeTimestamp;
      _event.numClosedConns++;
      _event.timeOpenConnLifeMs += connLifespanMs;
      _event.timeClosedConnLifeMs += unmergedConnLifespanMs;
      _lastConnOpenTimestamp = 0;
      _lastConnOpenMergeTimestamp = 0;
    }
    finally
    {
      releaseLock(writeLock);
    }
  }

  public void registerConnectionOpen(String client)
  {
    if (! _enabled.get()) return;
    Lock writeLock = acquireWriteLock();

    try
    {
      _lastConnOpenTimestamp = isThreadSafe() ? 0 : System.currentTimeMillis();
      _lastConnOpenMergeTimestamp = _lastConnOpenTimestamp;

      _event.numOpenConns++;
      _clients.add(client);
      _event.numClients = _clients.size();
    }
    finally
    {
      releaseLock(writeLock);
    }
  }

  public void registerConnectionError(Throwable error)
  {
    if (! _enabled.get()) return;
    Lock writeLock = acquireWriteLock();

    try
    {
      ++_event.errorTotalCount;
      if (error instanceof TimeoutException) ++_event.errorTimeoutCount;
      else if (error instanceof ConnectException) ++_event.errorConnectCount;
    }
    finally
    {
      releaseLock(writeLock);
    }
  }

  public void addResponseSize(int bytesSent)
  {
    if (! _enabled.get()) return;
    Lock writeLock = acquireWriteLock();

    try
    {
      _event.numBytes += bytesSent;
    }
    finally
    {
      releaseLock(writeLock);
    }
  }

  @Override
  protected void resetData()
  {
    _event.timestampLastResetMs = System.currentTimeMillis();
    _event.timeSinceLastResetMs = 0;
    _event.numBytes = 0;
    _event.numClients = 0;
    _event.numClosedConns = 0;
    _event.numOpenConns = 0;
    _event.timeClosedConnLifeMs = 0;
    _event.timeOpenConnLifeMs = 0;
    _clients.clear();
    _lastConnOpenTimestamp = 0;
    _lastConnOpenMergeTimestamp = 0;
    _event.errorConnectCount = 0;
    _event.errorTimeoutCount = 0;
    _event.errorTotalCount = 0;
  }

  @Override
  public JsonEncoder createJsonEncoder(OutputStream out) throws IOException
  {
    return new JsonEncoder(_event.getSchema(), out);
  }

  @Override
  protected void cloneData(ContainerTrafficTotalStatsEvent event)
  {
    event.containerId = _event.containerId;
    event.dimension = _event.dimension;
    event.timestampLastResetMs = _event.timestampLastResetMs;
    event.timeSinceLastResetMs = System.currentTimeMillis() - _event.timestampLastResetMs;
    event.numBytes = _event.numBytes;
    event.numClients = _event.numClients;
    event.numClosedConns = _event.numClosedConns;
    event.numOpenConns = _event.numOpenConns;
    event.timeClosedConnLifeMs = _event.timeClosedConnLifeMs;
    event.timeOpenConnLifeMs = _event.timeOpenConnLifeMs;
    event.errorConnectCount = _event.errorConnectCount;
    event.errorTimeoutCount = _event.errorTimeoutCount;
    event.errorTotalCount = _event.errorTotalCount;
  }

  @Override
  protected ContainerTrafficTotalStatsEvent newDataEvent()
  {
    return new ContainerTrafficTotalStatsEvent();
  }

  @Override
  protected SpecificDatumWriter<ContainerTrafficTotalStatsEvent> getAvroWriter()
  {
    return new SpecificDatumWriter<ContainerTrafficTotalStatsEvent>(
        ContainerTrafficTotalStatsEvent.class);
  }

  @Override
  public void mergeStats(DatabusMonitoringMBean<ContainerTrafficTotalStatsEvent> other)
  {
    super.mergeStats(other);
    if (other instanceof ContainerTrafficTotalStats)
    {
      ContainerTrafficTotalStats o = (ContainerTrafficTotalStats)other;
      o.getLatencyOpenConn(); //hack to update the open connections latency which is computed
                              //on demand
      mergeClients(o);
    }
  }

  @Override
  protected void doMergeStats(Object eventData)
  {
    if (! (eventData instanceof ContainerTrafficTotalStatsEvent))
    {
      LOG.warn("Attempt to merge unknown event class: " + eventData.getClass().getName());
      return;
    }
    ContainerTrafficTotalStatsEvent e = (ContainerTrafficTotalStatsEvent)eventData;

    /** Allow use negative relay IDs for aggregation across multiple relays */
    if (_event.containerId > 0 && e.containerId != _event.containerId)
    {
      LOG.warn("Attempt to data for a different relay " + e.containerId);
      return;
    }

    _event.numBytes += e.numBytes;
    _event.numClosedConns += e.numClosedConns;
    _event.numOpenConns += e.numOpenConns;
    _event.timeClosedConnLifeMs += e.timeClosedConnLifeMs;
    _event.timeOpenConnLifeMs += e.timeOpenConnLifeMs;
    _event.errorConnectCount += e.errorConnectCount;
    _event.errorTotalCount += e.errorTotalCount;
    _event.errorTimeoutCount += e.errorTimeoutCount;
    // numClients cannot be merged
  }

  /** A bit of a hack to merge state outside the event state */
  private void mergeClients(ContainerTrafficTotalStats other)
  {
    Lock otherReadLock = other.acquireReadLock();
    Lock writeLock = acquireReadLock(otherReadLock);

    try
    {
      _clients.addAll(other._clients);
      _event.numClients = _clients.size();
    }
    finally
    {
      releaseLock(writeLock);
      releaseLock(otherReadLock);
    }
  }

  @Override
  public ObjectName generateObjectName() throws MalformedObjectNameException
  {
    Hashtable<String, String> mbeanProps = generateBaseMBeanProps();
    mbeanProps.put("containerId", Integer.toString(_event.containerId));
    mbeanProps.put("dimension", getDimension());

    return new ObjectName(AbstractMonitoringMBean.JMX_DOMAIN, mbeanProps);
  }
}
TOP

Related Classes of com.linkedin.databus2.core.container.monitoring.mbean.ContainerTrafficTotalStats

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.