org.opendaylight.ocpjava.statistics.OcpStatisticsCounters Maven / Gradle / Ivy
/*
* Copyright (c) 2015 Foxconn Corporation and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.ocpjava.statistics;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import org.opendaylight.ocpjava.protocol.spi.statistics.OcpStatisticsHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Singleton class to hold and process counters
* @author Marko Lai
*
*/
public final class OcpStatisticsCounters implements OcpStatisticsHandler {
/**
* Default delay between two writings into log (milliseconds)
*/
public static final int DEFAULT_LOG_REPORT_PERIOD = 10000;
/**
* Minimal delay between two writings into log (milliseconds)
*/
public static final int MINIMAL_LOG_REPORT_PERIOD = 500;
private static OcpStatisticsCounters instanceHolder;
private static final Logger LOGGER = LoggerFactory.getLogger(OcpStatisticsCounters.class);
private Timer logReporter;
private int logReportPeriod;
private boolean runLogReport;
private Map countersMap;
private boolean runCounting;
// array to hold enabled counter types
private CounterEventTypes[] enabledCounters = {
CounterEventTypes.DS_ENCODE_FAIL,
CounterEventTypes.DS_ENCODE_SUCCESS,
CounterEventTypes.DS_ENTERED_OCPJAVA,
CounterEventTypes.DS_FLOW_MODS_ENTERED,
CounterEventTypes.DS_FLOW_MODS_SENT,
CounterEventTypes.US_DROPPED_PACKET_IN,
CounterEventTypes.US_DECODE_FAIL,
CounterEventTypes.US_DECODE_SUCCESS,
CounterEventTypes.US_MESSAGE_PASS,
CounterEventTypes.US_RECEIVED_IN_OCPJAVA};
/**
* Get instance of statistics counters, first created object does not start counting and log reporting
* @return an instance
*/
public static synchronized OcpStatisticsCounters getInstance() {
if (instanceHolder == null) {
instanceHolder = new OcpStatisticsCounters();
}
return instanceHolder;
}
private OcpStatisticsCounters() {
countersMap = new ConcurrentHashMap<>();
for(CounterEventTypes cet : enabledCounters){
countersMap.put(cet, new Counter());
}
runCounting = false;
this.logReportPeriod = 0;
this.runLogReport = false;
LOGGER.debug("StaticsCounters has been created");
}
/**
* Start counting (counters are set to 0 before counting starts)
* @param reportToLogs - true = statistic counters will periodically log
* @param logReportDelay - delay between two logs (in milliseconds)
*/
public void startCounting(boolean reportToLogs, int logReportDelay){
if (runCounting) {
return;
}
resetCounters();
LOGGER.debug("Counting started...");
if(reportToLogs){
startLogReport(logReportDelay);
}
runCounting = true;
}
/**
* Stop counting, values in counters are untouched, log reporter is stopped
*/
public void stopCounting(){
runCounting = false;
LOGGER.debug("Stop counting...");
stopLogReport();
}
/**
* Give an information if counting is running
* @return true, if counting is running, otherwise false
*/
public boolean isRunCounting(){
return runCounting;
}
/**
* Prints statistics with given delay between logs
* @param logReportDelay - delay between two logs (in milliseconds)
* @exception IllegalArgumentException if logReportDelay is less than 0
*/
public void startLogReport(int logReportDelay){
if(runLogReport){
return;
}
if(logReportDelay <= 0){
throw new IllegalArgumentException("logReportDelay has to be greater than 0");
}
if(logReportDelay < MINIMAL_LOG_REPORT_PERIOD){
this.logReportPeriod = MINIMAL_LOG_REPORT_PERIOD;
} else {
this.logReportPeriod = logReportDelay;
}
logReporter = new Timer("SC_Timer");
logReporter.schedule(new LogReporterTask(this), this.logReportPeriod, this.logReportPeriod);
runLogReport = true;
LOGGER.debug("OcpStatistics log reporter has been scheduled with period {} ms", this.logReportPeriod);
}
/**
* Stops logging, counting continues
*/
public void stopLogReport(){
if(runLogReport){
if(logReporter != null){
logReporter.cancel();
LOGGER.debug("OcpStatistics log reporter has been canceled");
}
runLogReport = false;
}
}
/**
* Give an information if log reporter is running (statistics are write into logs).
* @return true if log reporter writes statistics into log, otherwise false
*/
public boolean isRunLogReport(){
return runLogReport;
}
/**
* @return the current delay between two writings into logs
*/
public int getLogReportPeriod() {
return logReportPeriod;
}
/**
* @return the enabled counters
*/
protected CounterEventTypes[] getEnabledCounters() {
return enabledCounters;
}
/**
* @return the countersMap
*/
protected Map getCountersMap() {
return countersMap;
}
/**
* Give an information if is given counter is enabled
* @param counterEventKey
* @return true if counter has been Enabled, otherwise false
*/
public boolean isCounterEnabled(CounterEventTypes counterEventKey){
if (counterEventKey == null) {
return false;
}
return countersMap.containsKey(counterEventKey);
}
/**
* Get counter by CounterEventType
* @param counterEventKey key to identify counter (can not be null)
* @return Counter object or null if counter has not been enabled
* @throws IllegalArgumentException if counterEventKey is null
*/
public Counter getCounter(CounterEventTypes counterEventKey) {
if (counterEventKey == null) {
throw new IllegalArgumentException("counterEventKey can not be null");
}
return countersMap.get(counterEventKey);
}
/**
* Increment value of given counter
* @param counterEventKey key to identify counter
*/
public void incrementCounter(CounterEventTypes counterEventKey) {
if((runCounting) && isCounterEnabled(counterEventKey)){
countersMap.get(counterEventKey).incrementCounter();
}
}
@Override
public void resetCounters() {
for(CounterEventTypes cet : enabledCounters){
countersMap.get(cet).reset();
}
LOGGER.debug("StaticsCounters has been reset");
}
@Override
public String printOcpStatistics() {
StringBuilder strBuilder = new StringBuilder();
for(CounterEventTypes cet : getEnabledCounters()){
strBuilder.append(cet.name() + ": " + getCountersMap().get(cet).getStat() + "\n");
}
return strBuilder.toString();
}
/**
* internal class to process logReporter
* @author madamjak
*
*/
private static class LogReporterTask extends TimerTask {
private static final Logger LOG = LoggerFactory.getLogger(LogReporterTask.class);
private OcpStatisticsCounters sc;
public LogReporterTask(OcpStatisticsCounters sc) {
this.sc = sc;
}
@Override
public void run() {
for(CounterEventTypes cet : sc.getEnabledCounters()){
LOG.debug(cet.name() + ": " + sc.getCountersMap().get(cet).getStat());
}
}
}
}