blob: c5ee2f83ec6d413a137c47db7bd69be21eeac9a1 [file] [log] [blame]
sangho538108b2015-04-08 14:29:20 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
sangho538108b2015-04-08 14:29:20 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connor7cbbbb72016-04-09 02:13:23 -070016package org.onosproject.cli.net;
sangho538108b2015-04-08 14:29:20 -070017
Dusan Pajin11ff4a82015-08-20 18:03:05 +020018import static org.onosproject.net.DeviceId.deviceId;
19
Charles Chan33a79ce2015-12-12 11:14:07 -080020import java.util.List;
Dusan Pajin11ff4a82015-08-20 18:03:05 +020021import java.util.concurrent.TimeUnit;
22
Charles Chan33a79ce2015-12-12 11:14:07 -080023import com.google.common.collect.Lists;
Dusan Pajin11ff4a82015-08-20 18:03:05 +020024import org.apache.karaf.shell.commands.Argument;
sangho538108b2015-04-08 14:29:20 -070025import org.apache.karaf.shell.commands.Command;
Dusan Pajin11ff4a82015-08-20 18:03:05 +020026import org.apache.karaf.shell.commands.Option;
27import org.onosproject.net.Device;
sangho538108b2015-04-08 14:29:20 -070028import org.onosproject.net.DeviceId;
29import org.onosproject.net.device.DeviceService;
30import org.onosproject.net.device.PortStatistics;
31
32/**
33 * Lists port statistic of all ports in the system.
34 */
35@Command(scope = "onos", name = "portstats",
36 description = "Lists statistics of all ports in the system")
Dusan Pajin11ff4a82015-08-20 18:03:05 +020037public class DevicePortStatsCommand extends DevicesListCommand {
38
39 @Option(name = "-d", aliases = "--delta", description = "Show Delta Port Statistics,"
40 + "only for the last polling interval",
41 required = false, multiValued = false)
42 private boolean delta = false;
43
44 @Option(name = "-t", aliases = "--table", description = "Show human readable table format for statistics",
45 required = false, multiValued = false)
46 private boolean table = false;
47
48 @Argument(index = 0, name = "uri", description = "Device ID",
49 required = false, multiValued = false)
50 String uri = null;
sangho538108b2015-04-08 14:29:20 -070051
Saurav Dasa2d37502016-03-25 17:50:40 -070052 @Argument(index = 1, name = "portNumber", description = "Port Number",
53 required = false, multiValued = false)
54 Integer portNumber = null;
55
sangho538108b2015-04-08 14:29:20 -070056 private static final String FORMAT =
57 " port=%s, pktRx=%s, pktTx=%s, bytesRx=%s, bytesTx=%s, pktRxDrp=%s, pktTxDrp=%s, Dur=%s";
58
59 @Override
60 protected void execute() {
61 DeviceService deviceService = get(DeviceService.class);
62
Dusan Pajin11ff4a82015-08-20 18:03:05 +020063 if (uri == null) {
64 for (Device d : getSortedDevices(deviceService)) {
65 if (delta) {
66 if (table) {
67 printPortStatsDeltaTable(d.id(), deviceService.getPortDeltaStatistics(d.id()));
68 } else {
69 printPortStatsDelta(d.id(), deviceService.getPortDeltaStatistics(d.id()));
70 }
71 } else {
72 printPortStats(d.id(), deviceService.getPortStatistics(d.id()));
73 }
74 }
75 } else {
76 Device d = deviceService.getDevice(deviceId(uri));
77 if (d == null) {
78 error("No such device %s", uri);
79 } else if (delta) {
80 if (table) {
81 printPortStatsDeltaTable(d.id(), deviceService.getPortDeltaStatistics(d.id()));
82 } else {
83 printPortStatsDelta(d.id(), deviceService.getPortDeltaStatistics(d.id()));
84 }
85 } else {
86 printPortStats(d.id(), deviceService.getPortStatistics(d.id()));
87 }
88 }
sangho538108b2015-04-08 14:29:20 -070089 }
90
Dusan Pajin11ff4a82015-08-20 18:03:05 +020091 /**
92 * Prints Port Statistics.
93 *
94 * @param deviceId
95 * @param portStats
96 */
sangho538108b2015-04-08 14:29:20 -070097 private void printPortStats(DeviceId deviceId, Iterable<PortStatistics> portStats) {
98 print("deviceId=%s", deviceId);
Charles Chan33a79ce2015-12-12 11:14:07 -080099 for (PortStatistics stat : sortByPort(portStats)) {
Saurav Dasa2d37502016-03-25 17:50:40 -0700100 if (portNumber != null && stat.port() != portNumber) {
101 continue;
102 }
sangho538108b2015-04-08 14:29:20 -0700103 print(FORMAT, stat.port(), stat.packetsReceived(), stat.packetsSent(), stat.bytesReceived(),
104 stat.bytesSent(), stat.packetsRxDropped(), stat.packetsTxDropped(), stat.durationSec());
105 }
106 }
Dusan Pajin11ff4a82015-08-20 18:03:05 +0200107 /**
108 * Prints Port delta statistics.
109 *
110 * @param deviceId
111 * @param portStats
112 */
113 private void printPortStatsDelta(DeviceId deviceId, Iterable<PortStatistics> portStats) {
114 final String formatDelta = " port=%s, pktRx=%s, pktTx=%s, bytesRx=%s, bytesTx=%s,"
115 + " rateRx=%s, rateTx=%s, pktRxDrp=%s, pktTxDrp=%s, interval=%s";
116 print("deviceId=%s", deviceId);
Charles Chan33a79ce2015-12-12 11:14:07 -0800117 for (PortStatistics stat : sortByPort(portStats)) {
Saurav Dasa2d37502016-03-25 17:50:40 -0700118 if (portNumber != null && stat.port() != portNumber) {
119 continue;
120 }
Dusan Pajin11ff4a82015-08-20 18:03:05 +0200121 float duration = ((float) stat.durationSec()) +
122 (((float) stat.durationNano()) / TimeUnit.SECONDS.toNanos(1));
123 float rateRx = stat.bytesReceived() * 8 / duration;
124 float rateTx = stat.bytesSent() * 8 / duration;
125 print(formatDelta, stat.port(),
126 stat.packetsReceived(),
127 stat.packetsSent(),
128 stat.bytesReceived(),
129 stat.bytesSent(),
130 String.format("%.1f", rateRx),
131 String.format("%.1f", rateTx),
132 stat.packetsRxDropped(),
133 stat.packetsTxDropped(),
134 String.format("%.3f", duration));
135 }
136 }
137
138 /**
139 * Prints human readable table with delta Port Statistics for specific device.
140 *
141 * @param deviceId
142 * @param portStats
143 */
144 private void printPortStatsDeltaTable(DeviceId deviceId, Iterable<PortStatistics> portStats) {
145 final String formatDeltaTable = "|%5s | %7s | %7s | %7s | %7s | %7s | %7s | %7s | %7s |%9s |";
146 print("+---------------------------------------------------------------------------------------------------+");
147 print("| DeviceId = %s |", deviceId);
148 print("|---------------------------------------------------------------------------------------------------|");
149 print("| | Receive | Transmit | Time [s] |");
150 print("| Port | Packets | Bytes | Rate bps | Drop | Packets | Bytes | Rate bps | Drop | Interval |");
151 print("|---------------------------------------------------------------------------------------------------|");
152
Charles Chan33a79ce2015-12-12 11:14:07 -0800153 for (PortStatistics stat : sortByPort(portStats)) {
Saurav Dasa2d37502016-03-25 17:50:40 -0700154 if (portNumber != null && stat.port() != portNumber) {
155 continue;
Dusan Pajin11ff4a82015-08-20 18:03:05 +0200156 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700157 float duration = ((float) stat.durationSec()) +
158 (((float) stat.durationNano()) / TimeUnit.SECONDS.toNanos(1));
159 float rateRx = stat.bytesReceived() * 8 / duration;
160 float rateTx = stat.bytesSent() * 8 / duration;
161 print(formatDeltaTable, stat.port(),
162 humanReadable(stat.packetsReceived()),
163 humanReadable(stat.bytesReceived()),
164 humanReadableBps(rateRx),
165 humanReadable(stat.packetsRxDropped()),
166 humanReadable(stat.packetsSent()),
167 humanReadable(stat.bytesSent()),
168 humanReadableBps(rateTx),
169 humanReadable(stat.packetsTxDropped()),
170 String.format("%.3f", duration));
171 }
Dusan Pajin11ff4a82015-08-20 18:03:05 +0200172 print("+---------------------------------------------------------------------------------------------------+");
173 }
174
175 /**
176 * Converts bytes to human readable string with Kilo, Mega, Giga, etc.
177 *
Madan Jampanif97edc12015-08-31 14:41:01 -0700178 * @param bytes input byte array
179 * @return human readble string
Dusan Pajin11ff4a82015-08-20 18:03:05 +0200180 */
181 public static String humanReadable(long bytes) {
182 int unit = 1000;
183 if (bytes < unit) {
184 return String.format("%s ", bytes);
185 }
186 int exp = (int) (Math.log(bytes) / Math.log(unit));
187 Character pre = ("KMGTPE").charAt(exp - 1);
188 return String.format("%.2f%s", bytes / Math.pow(unit, exp), pre);
189 }
190 /**
191 * Converts bps to human readable format.
192 *
Madan Jampanif97edc12015-08-31 14:41:01 -0700193 * @param bps input rate
194 * @return human readble string
Dusan Pajin11ff4a82015-08-20 18:03:05 +0200195 */
196 public static String humanReadableBps(float bps) {
197 int unit = 1000;
198 if (bps < unit) {
199 return String.format("%.0f ", (float) bps);
200 }
201 int exp = (int) (Math.log(bps) / Math.log(unit));
202 Character pre = ("KMGTPE").charAt(exp - 1);
203 return String.format("%.2f%s", bps / Math.pow(unit, exp), pre);
204 }
Charles Chan33a79ce2015-12-12 11:14:07 -0800205
206 private static List<PortStatistics> sortByPort(Iterable<PortStatistics> portStats) {
207 List<PortStatistics> portStatsList = Lists.newArrayList(portStats);
208 portStatsList.sort((PortStatistics o1, PortStatistics o2) ->
209 o1.port() - o2.port());
210 return portStatsList;
211 }
sangho538108b2015-04-08 14:29:20 -0700212}