package com.linkedin.databus.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.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 com.linkedin.databus.core.monitoring.mbean.AbstractMonitoringMBean;
import com.linkedin.databus.monitoring.events.DbusDbSourceConnectionStatsEvent;
public class DbusDbSourceConnectionStats extends AbstractMonitoringMBean<DbusDbSourceConnectionStatsEvent>
implements DbusDbSourceConnectionStatsMBean
{
public static final String MODULE = DbusDbSourceConnectionStats.class.getName();
public static final Logger LOG = Logger.getLogger(MODULE);
public DbusDbSourceConnectionStats(int relayId, boolean enabled, boolean threadSafe,
DbusDbSourceConnectionStatsEvent initData)
{
super(enabled, threadSafe, initData);
_event.relayId = relayId;
reset();
}
@Override
public long getNumClosedDbConns()
{
Lock readLock = acquireReadLock();
try
{
return _event.numClosedDbConns;
}
finally
{
releaseLock(readLock);
}
}
@Override
public long getNumOpenDbConns()
{
Lock readLock = acquireReadLock();
try
{
return _event.numOpenDbConns;
}
finally
{
releaseLock(readLock);
}
}
@Override
public long getNumRowsUpdated()
{
Lock readLock = acquireReadLock();
try
{
return _event.numRowsUpdated;
}
finally
{
releaseLock(readLock);
}
}
@Override
public long getTimeClosedDbConnLifeMs()
{
Lock readLock = acquireReadLock();
try
{
return _event.timeClosedDbConnLifeMs;
}
finally
{
releaseLock(readLock);
}
}
@Override
public long getTimeOpenDbConnLifeMs()
{
Lock readLock = acquireReadLock();
try
{
return _event.timeOpenDbConnLifeMs;
}
finally
{
releaseLock(readLock);
}
}
@Override
public long getTimestampLastDbConnCloseMs()
{
Lock readLock = acquireReadLock();
try
{
return _event.timestampLastDbConnCloseMs;
}
finally
{
releaseLock(readLock);
}
}
@Override
public long getTimestampLastDbConnOpenMs()
{
Lock readLock = acquireReadLock();
try
{
return _event.timestampLastDbConnOpenMs;
}
finally
{
releaseLock(readLock);
}
}
@Override
public long getTimeSinceLastResetMs()
{
Lock readLock = acquireReadLock();
try
{
return _event.timeSinceLastResetMs;
}
finally
{
releaseLock(readLock);
}
}
@Override
public long getTimestampLastResetMs()
{
Lock readLock = acquireReadLock();
try
{
return _event.timestampLastResetMs;
}
finally
{
releaseLock(readLock);
}
}
@Override
public JsonEncoder createJsonEncoder(OutputStream out) throws IOException
{
return new JsonEncoder(_event.getSchema(), out);
}
@Override
public void registerDbConnClose(long timestamp, long lifespan)
{
Lock writeLock = acquireWriteLock();
try
{
++ _event.numClosedDbConns;
-- _event.numOpenDbConns;
_event.timeClosedDbConnLifeMs += lifespan;
_event.timestampLastDbConnCloseMs = Math.max(_event.timestampLastDbConnCloseMs, timestamp);
}
finally
{
releaseLock(writeLock);
}
}
@Override
public void registerDbConnOpen(long timestamp)
{
Lock writeLock = acquireWriteLock();
try
{
++ _event.numOpenDbConns;
_event.timestampLastDbConnOpenMs = Math.max(_event.timestampLastDbConnOpenMs, timestamp);
}
finally
{
releaseLock(writeLock);
}
}
@Override
public void registerDbRowsRead(int num)
{
Lock writeLock = acquireWriteLock();
try
{
_event.numRowsUpdated += num;
}
finally
{
releaseLock(writeLock);
}
}
@Override
protected void cloneData(DbusDbSourceConnectionStatsEvent event)
{
event.relayId = _event.relayId;
event.timestampLastResetMs = _event.timestampLastResetMs;
event.timeSinceLastResetMs = System.currentTimeMillis() - _event.timestampLastResetMs;
event.numClosedDbConns = _event.numClosedDbConns;
event.numOpenDbConns = _event.numOpenDbConns;
event.numRowsUpdated = _event.numRowsUpdated;
event.timeClosedDbConnLifeMs = _event.timeClosedDbConnLifeMs;
event.timeOpenDbConnLifeMs = _event.timeOpenDbConnLifeMs;
event.timestampLastDbConnCloseMs = _event.timestampLastDbConnCloseMs;
event.timestampLastDbConnOpenMs = _event.timestampLastDbConnOpenMs;
}
@Override
protected void doMergeStats(Object eventData)
{
if (! (eventData instanceof DbusDbSourceConnectionStatsEvent))
{
LOG.warn("Attempt to merge unknown event class" + eventData.getClass().getName());
return;
}
DbusDbSourceConnectionStatsEvent e = (DbusDbSourceConnectionStatsEvent)eventData;
/** Allow use negative relay IDs for aggregation across multiple relays */
if (_event.relayId > 0 && e.relayId != _event.relayId)
{
LOG.warn("Attempt to data for a different relay " + e.relayId);
return;
}
_event.numClosedDbConns += e.numClosedDbConns;
_event.numOpenDbConns += e.numOpenDbConns;
_event.numRowsUpdated += e.numRowsUpdated;
_event.timeClosedDbConnLifeMs += e.timeClosedDbConnLifeMs;
_event.timeOpenDbConnLifeMs += e.timeOpenDbConnLifeMs;
_event.timestampLastDbConnCloseMs = Math.max(_event.timestampLastDbConnCloseMs,
e.timestampLastDbConnCloseMs);
_event.timestampLastDbConnOpenMs = Math.max(_event.timestampLastDbConnOpenMs,
e.timestampLastDbConnOpenMs);
}
@Override
protected SpecificDatumWriter<DbusDbSourceConnectionStatsEvent> getAvroWriter()
{
return new SpecificDatumWriter<DbusDbSourceConnectionStatsEvent>(DbusDbSourceConnectionStatsEvent.class);
}
@Override
protected DbusDbSourceConnectionStatsEvent newDataEvent()
{
return new DbusDbSourceConnectionStatsEvent();
}
@Override
protected void resetData()
{
_event.timestampLastResetMs = System.currentTimeMillis();
_event.timeSinceLastResetMs = 0;
_event.numClosedDbConns = 0;
_event.numOpenDbConns = 0;
_event.numRowsUpdated = 0;
_event.timeClosedDbConnLifeMs = 0;
_event.timeOpenDbConnLifeMs = 0;
_event.timestampLastDbConnCloseMs = 0;
_event.timestampLastDbConnOpenMs = 0;
}
@Override
public ObjectName generateObjectName() throws MalformedObjectNameException
{
Hashtable<String, String> mbeanProps = generateBaseMBeanProps();
mbeanProps.put("relayId", Integer.toString(_event.relayId));
return new ObjectName(AbstractMonitoringMBean.JMX_DOMAIN, mbeanProps);
}
}