2 * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowjava.statistics;
11 import java.util.Timer;
12 import java.util.TimerTask;
13 import java.util.concurrent.ConcurrentHashMap;
14 import org.opendaylight.openflowjava.protocol.spi.statistics.StatisticsHandler;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
19 * Singleton class to hold and process counters
23 public final class StatisticsCounters implements StatisticsHandler {
26 * Default delay between two writings into log (milliseconds)
28 public static final int DEFAULT_LOG_REPORT_PERIOD = 10000;
30 * Minimal delay between two writings into log (milliseconds)
32 public static final int MINIMAL_LOG_REPORT_PERIOD = 500;
33 private static StatisticsCounters instanceHolder;
34 private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsCounters.class);
36 private Timer logReporter;
37 private int logReportPeriod;
38 private boolean runLogReport;
39 private Map<CounterEventTypes, Counter> countersMap;
40 private boolean runCounting;
41 // array to hold enabled counter types
42 private CounterEventTypes[] enabledCounters = {
43 CounterEventTypes.DS_ENCODE_FAIL,
44 CounterEventTypes.DS_ENCODE_SUCCESS,
45 CounterEventTypes.DS_ENTERED_OFJAVA,
46 CounterEventTypes.DS_FLOW_MODS_ENTERED,
47 CounterEventTypes.DS_FLOW_MODS_SENT,
48 CounterEventTypes.US_DROPPED_PACKET_IN,
49 CounterEventTypes.US_DECODE_FAIL,
50 CounterEventTypes.US_DECODE_SUCCESS,
51 CounterEventTypes.US_MESSAGE_PASS,
52 CounterEventTypes.US_RECEIVED_IN_OFJAVA};
55 * Get instance of statistics counters, first created object does not start counting and log reporting
58 public static synchronized StatisticsCounters getInstance() {
59 if (instanceHolder == null) {
60 instanceHolder = new StatisticsCounters();
62 return instanceHolder;
65 private StatisticsCounters() {
66 countersMap = new ConcurrentHashMap<>();
67 for(CounterEventTypes cet : enabledCounters){
68 countersMap.put(cet, new Counter());
71 this.logReportPeriod = 0;
72 this.runLogReport = false;
73 LOGGER.debug("StaticsCounters has been created");
77 * Start counting (counters are set to 0 before counting starts)
78 * @param reportToLogs - true = statistic counters will periodically log
79 * @param logReportDelay - delay between two logs (in milliseconds)
81 public void startCounting(boolean reportToLogs, int logReportDelay){
86 LOGGER.debug("Counting started...");
88 startLogReport(logReportDelay);
94 * Stop counting, values in counters are untouched, log reporter is stopped
96 public void stopCounting(){
98 LOGGER.debug("Stop counting...");
103 * Give an information if counting is running
104 * @return true, if counting is running, otherwise false
106 public boolean isRunCounting(){
111 * Prints statistics with given delay between logs
112 * @param logReportDelay - delay between two logs (in milliseconds)
113 * @exception IllegalArgumentException if logReportDelay is less than 0
115 public void startLogReport(int logReportDelay){
119 if(logReportDelay <= 0){
120 throw new IllegalArgumentException("logReportDelay has to be greater than 0");
122 if(logReportDelay < MINIMAL_LOG_REPORT_PERIOD){
123 this.logReportPeriod = MINIMAL_LOG_REPORT_PERIOD;
125 this.logReportPeriod = logReportDelay;
127 logReporter = new Timer("SC_Timer");
128 logReporter.schedule(new LogReporterTask(this), this.logReportPeriod, this.logReportPeriod);
130 LOGGER.debug("Statistics log reporter has been scheduled with period {} ms", this.logReportPeriod);
134 * Stops logging, counting continues
136 public void stopLogReport(){
138 if(logReporter != null){
139 logReporter.cancel();
140 LOGGER.debug("Statistics log reporter has been canceled");
142 runLogReport = false;
147 * Give an information if log reporter is running (statistics are write into logs).
148 * @return true if log reporter writes statistics into log, otherwise false
150 public boolean isRunLogReport(){
155 * @return the current delay between two writings into logs
157 public int getLogReportPeriod() {
158 return logReportPeriod;
162 * @return the enabled counters
164 protected CounterEventTypes[] getEnabledCounters() {
165 return enabledCounters;
168 * @return the countersMap
170 protected Map<CounterEventTypes, Counter> getCountersMap() {
175 * Give an information if is given counter is enabled
176 * @param counterEventKey
177 * @return true if counter has been Enabled, otherwise false
179 public boolean isCounterEnabled(CounterEventTypes counterEventKey){
180 if (counterEventKey == null) {
183 return countersMap.containsKey(counterEventKey);
187 * Get counter by CounterEventType
188 * @param counterEventKey key to identify counter (can not be null)
189 * @return Counter object or null if counter has not been enabled
190 * @throws IllegalArgumentException if counterEventKey is null
192 public Counter getCounter(CounterEventTypes counterEventKey) {
193 if (counterEventKey == null) {
194 throw new IllegalArgumentException("counterEventKey can not be null");
196 return countersMap.get(counterEventKey);
200 * Increment value of given counter
201 * @param counterEventKey key to identify counter
203 public void incrementCounter(CounterEventTypes counterEventKey) {
205 if (isCounterEnabled(counterEventKey)){
206 countersMap.get(counterEventKey).incrementCounter();
212 public void resetCounters() {
213 for(CounterEventTypes cet : enabledCounters){
214 countersMap.get(cet).reset();
216 LOGGER.debug("StaticsCounters has been reset");
220 public String printStatistics() {
221 StringBuilder strBuilder = new StringBuilder();
222 for(CounterEventTypes cet : getEnabledCounters()){
223 strBuilder.append(cet.name() + ": " + getCountersMap().get(cet).getStat() + "\n");
225 return strBuilder.toString();
229 * internal class to process logReporter
233 private static class LogReporterTask extends TimerTask {
234 private static final Logger LOG = LoggerFactory.getLogger(LogReporterTask.class);
236 private StatisticsCounters sc;
237 public LogReporterTask(StatisticsCounters sc) {
243 for(CounterEventTypes cet : sc.getEnabledCounters()){
244 LOG.debug(cet.name() + ": " + sc.getCountersMap().get(cet).getStat());