blob: 639623b3d52e0cb4d6b5a4657f1758fca02ed639 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
2 * Performance monitoring package
3 */
4package net.floodlightcontroller.perfmon;
5
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.HashMap;
9import java.util.List;
10import java.util.Map;
11
12import net.floodlightcontroller.core.FloodlightContext;
13import net.floodlightcontroller.core.IOFMessageListener;
14import net.floodlightcontroller.core.IOFSwitch;
15import net.floodlightcontroller.core.annotations.LogMessageCategory;
16import net.floodlightcontroller.core.annotations.LogMessageDoc;
17import net.floodlightcontroller.core.module.FloodlightModuleContext;
18import net.floodlightcontroller.core.module.FloodlightModuleException;
19import net.floodlightcontroller.core.module.IFloodlightModule;
20import net.floodlightcontroller.core.module.IFloodlightService;
21import net.floodlightcontroller.restserver.IRestApiService;
22
23import org.openflow.protocol.OFMessage;
24import org.slf4j.Logger;
25import org.slf4j.LoggerFactory;
26
27/**
28 * This class contains a set of buckets (called time buckets as the
29 * primarily contain 'times' that are used in a circular way to
30 * store information on packet in processing time.
31 * Each bucket is meant to store the various processing time
32 * related data for a fixed duration.
33 * Buckets are reused to reduce garbage generation! Once the
34 * last bucket is used up the LRU bucket is reused.
35 *
36 * Naming convention for variable or constants
37 * variable_s : value in seconds
38 * variable_ms: value in milliseconds
39 * variable_us: value in microseconds
40 * variable_ns: value in nanoseconds
41 *
42 * Key Constants:
43 * ONE_BUCKET_DURATION_SECONDS_INT: time duration of each bucket
44 * BUCKET_SET_SIZE: Number of buckets
45 * TOT_PROC_TIME_WARN_THRESHOLD_US: if processing time for a packet
46 * exceeds this threshold then a warning LOG message is generated
47 * TOT_PROC_TIME_ALERT_THRESHOLD_US: same as above but an alert level
48 * syslog is generated instead
49 *
50 */
51@LogMessageCategory("Performance Monitoring")
52public class PktInProcessingTime
53 implements IFloodlightModule, IPktInProcessingTimeService {
54
55
56 // Our dependencies
57 private IRestApiService restApi;
58
59 protected long ptWarningThresholdInNano;
60
61 // DB storage tables
62 protected static final String ControllerTableName = "controller_controller";
63 public static final String COLUMN_ID = "id";
64 public static final String COLUMN_PERF_MON = "performance_monitor_feature";
65
66 protected static Logger logger =
67 LoggerFactory.getLogger(PktInProcessingTime.class);
68
69 protected boolean isEnabled = false;
70 protected boolean isInited = false;
71 // Maintains the time when the last packet was processed
72 protected long lastPktTime_ns;
73 private CumulativeTimeBucket ctb = null;
74
75
76 /***
77 * BUCKET_SET_SIZE buckets each holding 10s of processing time data, a total
78 * of 30*10s = 5mins of processing time data is maintained
79 */
80 protected static final int ONE_BUCKET_DURATION_SECONDS = 10;// seconds
81 protected static final long ONE_BUCKET_DURATION_NANOSECONDS =
82 ONE_BUCKET_DURATION_SECONDS * 1000000000;
83
84 @Override
85 public void bootstrap(List<IOFMessageListener> listeners) {
86 if (!isInited) {
87 ctb = new CumulativeTimeBucket(listeners);
88 isInited = true;
89 }
90 }
91
92 @Override
93 public boolean isEnabled() {
94 return isEnabled && isInited;
95 }
96
97 @Override
98 public void setEnabled(boolean enabled) {
99 this.isEnabled = enabled;
100 logger.debug("Setting module to " + isEnabled);
101 }
102
103 @Override
104 public CumulativeTimeBucket getCtb() {
105 return ctb;
106 }
107
108 private long startTimePktNs;
109 private long startTimeCompNs;
110 @Override
111 public void recordStartTimeComp(IOFMessageListener listener) {
112 if (isEnabled()) {
113 startTimeCompNs = System.nanoTime();
114 }
115 }
116
117 @Override
118 public void recordEndTimeComp(IOFMessageListener listener) {
119 if (isEnabled()) {
120 long procTime = System.nanoTime() - startTimeCompNs;
121 ctb.updateOneComponent(listener, procTime);
122 }
123 }
124
125 @Override
126 public void recordStartTimePktIn() {
127 if (isEnabled()) {
128 startTimePktNs = System.nanoTime();
129 }
130 }
131
132 @Override
133 @LogMessageDoc(level="WARN",
134 message="Time to process packet-in exceeded threshold: {}",
135 explanation="Time to process packet-in exceeded the configured " +
136 "performance threshold",
137 recommendation=LogMessageDoc.CHECK_CONTROLLER)
138 public void recordEndTimePktIn(IOFSwitch sw, OFMessage m, FloodlightContext cntx) {
139 if (isEnabled()) {
140 long procTimeNs = System.nanoTime() - startTimePktNs;
141 ctb.updatePerPacketCounters(procTimeNs);
142
143 if (ptWarningThresholdInNano > 0 &&
144 procTimeNs > ptWarningThresholdInNano) {
145 logger.warn("Time to process packet-in exceeded threshold: {}",
146 procTimeNs/1000);
147 }
148 }
149 }
150
151 // IFloodlightModule methods
152
153 @Override
154 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
155 Collection<Class<? extends IFloodlightService>> l =
156 new ArrayList<Class<? extends IFloodlightService>>();
157 l.add(IPktInProcessingTimeService.class);
158 return l;
159 }
160
161 @Override
162 public Map<Class<? extends IFloodlightService>, IFloodlightService>
163 getServiceImpls() {
164 Map<Class<? extends IFloodlightService>,
165 IFloodlightService> m =
166 new HashMap<Class<? extends IFloodlightService>,
167 IFloodlightService>();
168 // We are the class that implements the service
169 m.put(IPktInProcessingTimeService.class, this);
170 return m;
171 }
172
173 @Override
174 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
175 Collection<Class<? extends IFloodlightService>> l =
176 new ArrayList<Class<? extends IFloodlightService>>();
177 l.add(IRestApiService.class);
178 return l;
179 }
180
181 @Override
182 public void init(FloodlightModuleContext context)
183 throws FloodlightModuleException {
184 restApi = context.getServiceImpl(IRestApiService.class);
185 }
186
187 @Override
188 @LogMessageDoc(level="INFO",
189 message="Packet processing time threshold for warning" +
190 " set to {time} ms.",
191 explanation="Performance monitoring will log a warning if " +
192 "packet processing time exceeds the configured threshold")
193 public void startUp(FloodlightModuleContext context) {
194 // Add our REST API
195 restApi.addRestletRoutable(new PerfWebRoutable());
196
197 // TODO - Alex - change this to a config option
198 ptWarningThresholdInNano = Long.parseLong(System.getProperty(
199 "net.floodlightcontroller.core.PTWarningThresholdInMilli", "0")) * 1000000;
200 if (ptWarningThresholdInNano > 0) {
201 logger.info("Packet processing time threshold for warning" +
202 " set to {} ms.", ptWarningThresholdInNano/1000000);
203 }
204 }
205}