Fixing port stats rate calculation.
Change-Id: Ic4c803f58a53c293ae05bc0c207d7e23546f7158
Showing
3 changed files
with
61 additions
and
82 deletions
... | @@ -28,12 +28,12 @@ public class DefaultLoad implements Load { | ... | @@ -28,12 +28,12 @@ public class DefaultLoad implements Load { |
28 | private final long current; | 28 | private final long current; |
29 | private final long previous; | 29 | private final long previous; |
30 | private final long time; | 30 | private final long time; |
31 | - private final int interval; | 31 | + private final long interval; |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Indicates the flow statistics poll interval in seconds. | 34 | * Indicates the flow statistics poll interval in seconds. |
35 | */ | 35 | */ |
36 | - private static int pollInterval = 10; | 36 | + private static long pollInterval = 10; |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * Creates an invalid load. | 39 | * Creates an invalid load. |
... | @@ -63,7 +63,7 @@ public class DefaultLoad implements Load { | ... | @@ -63,7 +63,7 @@ public class DefaultLoad implements Load { |
63 | * @param previous the previous value | 63 | * @param previous the previous value |
64 | * @param interval poll interval for this load | 64 | * @param interval poll interval for this load |
65 | */ | 65 | */ |
66 | - public DefaultLoad(long current, long previous, int interval) { | 66 | + public DefaultLoad(long current, long previous, long interval) { |
67 | checkArgument(interval > 0, "Interval must be greater than 0"); | 67 | checkArgument(interval > 0, "Interval must be greater than 0"); |
68 | this.current = current; | 68 | this.current = current; |
69 | this.previous = previous; | 69 | this.previous = previous; |
... | @@ -78,7 +78,7 @@ public class DefaultLoad implements Load { | ... | @@ -78,7 +78,7 @@ public class DefaultLoad implements Load { |
78 | * | 78 | * |
79 | * @param newPollInterval poll interval duration in seconds | 79 | * @param newPollInterval poll interval duration in seconds |
80 | */ | 80 | */ |
81 | - public static void setPollInterval(int newPollInterval) { | 81 | + public static void setPollInterval(long newPollInterval) { |
82 | pollInterval = newPollInterval; | 82 | pollInterval = newPollInterval; |
83 | } | 83 | } |
84 | 84 | ... | ... |
... | @@ -49,8 +49,8 @@ public class PortStatisticsManager implements PortStatisticsService { | ... | @@ -49,8 +49,8 @@ public class PortStatisticsManager implements PortStatisticsService { |
49 | 49 | ||
50 | private final Logger log = getLogger(getClass()); | 50 | private final Logger log = getLogger(getClass()); |
51 | 51 | ||
52 | - private static final int SECOND = 1_000; // milliseconds | 52 | + private static final long POLL_FREQUENCY = 10_000; // milliseconds |
53 | - private static final long STALE_LIMIT = 15_000; // milliseconds | 53 | + private static final long STALE_LIMIT = (long) (1.5 * POLL_FREQUENCY); |
54 | 54 | ||
55 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 55 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
56 | protected DeviceService deviceService; | 56 | protected DeviceService deviceService; |
... | @@ -77,11 +77,15 @@ public class PortStatisticsManager implements PortStatisticsService { | ... | @@ -77,11 +77,15 @@ public class PortStatisticsManager implements PortStatisticsService { |
77 | DataPoint c = current.get(connectPoint); | 77 | DataPoint c = current.get(connectPoint); |
78 | DataPoint p = previous.get(connectPoint); | 78 | DataPoint p = previous.get(connectPoint); |
79 | long now = System.currentTimeMillis(); | 79 | long now = System.currentTimeMillis(); |
80 | - if (c != null && p != null && (now - c.time < STALE_LIMIT) && | 80 | + |
81 | - (c.time > p.time + SECOND) && | 81 | + if (c != null && p != null && (now - c.time < STALE_LIMIT)) { |
82 | - (c.stats.bytesSent() - p.stats.bytesSent() >= 0)) { | 82 | + if (c.stats.durationSec() > p.stats.durationSec() && |
83 | - return new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(), | 83 | + c.stats.bytesSent() >= p.stats.bytesSent() && |
84 | - (int) (c.time - p.time) / SECOND); | 84 | + c.stats.durationSec() >= POLL_FREQUENCY / 1_000) { |
85 | + return new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(), | ||
86 | + c.stats.durationSec() - p.stats.durationSec()); | ||
87 | + } | ||
88 | + return new DefaultLoad(c.stats.bytesSent(), 0, c.stats.durationSec()); | ||
85 | } | 89 | } |
86 | return null; | 90 | return null; |
87 | } | 91 | } |
... | @@ -114,15 +118,15 @@ public class PortStatisticsManager implements PortStatisticsService { | ... | @@ -114,15 +118,15 @@ public class PortStatisticsManager implements PortStatisticsService { |
114 | // Updates the port stats for the specified port | 118 | // Updates the port stats for the specified port |
115 | private void updatePortData(DeviceId deviceId, PortStatistics stats) { | 119 | private void updatePortData(DeviceId deviceId, PortStatistics stats) { |
116 | ConnectPoint cp = new ConnectPoint(deviceId, portNumber(stats.port())); | 120 | ConnectPoint cp = new ConnectPoint(deviceId, portNumber(stats.port())); |
121 | + DataPoint c = current.get(cp); | ||
122 | + | ||
123 | + // Create a new data point and make it the current one | ||
124 | + current.put(cp, new DataPoint(stats)); | ||
117 | 125 | ||
118 | // If we have a current data point, demote it to previous | 126 | // If we have a current data point, demote it to previous |
119 | - DataPoint c = current.get(cp); | ||
120 | if (c != null) { | 127 | if (c != null) { |
121 | previous.put(cp, c); | 128 | previous.put(cp, c); |
122 | } | 129 | } |
123 | - | ||
124 | - // Create a new data point and make it the current one | ||
125 | - current.put(cp, new DataPoint(stats)); | ||
126 | } | 130 | } |
127 | 131 | ||
128 | // Cleans all port loads for the specified device | 132 | // Cleans all port loads for the specified device | ... | ... |
... | @@ -16,7 +16,6 @@ | ... | @@ -16,7 +16,6 @@ |
16 | package org.onosproject.ui.impl; | 16 | package org.onosproject.ui.impl; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
20 | import com.fasterxml.jackson.databind.node.ArrayNode; | 19 | import com.fasterxml.jackson.databind.node.ArrayNode; |
21 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
22 | import com.google.common.collect.ImmutableList; | 21 | import com.google.common.collect.ImmutableList; |
... | @@ -90,6 +89,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; | ... | @@ -90,6 +89,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; |
90 | import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED; | 89 | import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED; |
91 | import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_REMOVED; | 90 | import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_REMOVED; |
92 | import static org.onosproject.cluster.ControllerNode.State.ACTIVE; | 91 | import static org.onosproject.cluster.ControllerNode.State.ACTIVE; |
92 | +import static org.onosproject.net.DefaultEdgeLink.createEdgeLink; | ||
93 | import static org.onosproject.net.DeviceId.deviceId; | 93 | import static org.onosproject.net.DeviceId.deviceId; |
94 | import static org.onosproject.net.HostId.hostId; | 94 | import static org.onosproject.net.HostId.hostId; |
95 | import static org.onosproject.net.LinkKey.linkKey; | 95 | import static org.onosproject.net.LinkKey.linkKey; |
... | @@ -101,7 +101,8 @@ import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; | ... | @@ -101,7 +101,8 @@ import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; |
101 | import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED; | 101 | import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED; |
102 | import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; | 102 | import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; |
103 | import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED; | 103 | import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED; |
104 | -import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.*; | 104 | +import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.FLOW; |
105 | +import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.PORT; | ||
105 | 106 | ||
106 | /** | 107 | /** |
107 | * Facility for creating messages bound for the topology viewer. | 108 | * Facility for creating messages bound for the topology viewer. |
... | @@ -126,7 +127,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -126,7 +127,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
126 | private static final String KB_UNIT = "KB"; | 127 | private static final String KB_UNIT = "KB"; |
127 | private static final String B_UNIT = "B"; | 128 | private static final String B_UNIT = "B"; |
128 | 129 | ||
129 | - private static final long BPS_THRESHOLD = 1024; | 130 | + private static final double BPS_THRESHOLD = 4 * KB; |
130 | 131 | ||
131 | protected ServiceDirectory directory; | 132 | protected ServiceDirectory directory; |
132 | protected ClusterService clusterService; | 133 | protected ClusterService clusterService; |
... | @@ -567,37 +568,49 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -567,37 +568,49 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
567 | pathNodeT.set("labels", labelsT); | 568 | pathNodeT.set("labels", labelsT); |
568 | paths.add(pathNodeT); | 569 | paths.add(pathNodeT); |
569 | 570 | ||
570 | - for (BiLink link : consolidateLinks(linkService.getLinks())) { | 571 | + Map<LinkKey, BiLink> biLinks = consolidateLinks(linkService.getLinks()); |
572 | + addEdgeLinks(biLinks); | ||
573 | + for (BiLink link : biLinks.values()) { | ||
571 | boolean bi = link.two != null; | 574 | boolean bi = link.two != null; |
572 | - if (isInfrastructureEgress(link.one) || | 575 | + if (type == FLOW) { |
573 | - (bi && isInfrastructureEgress(link.two))) { | 576 | + link.addLoad(getLinkLoad(link.one)); |
574 | - if (type == FLOW) { | 577 | + link.addLoad(bi ? getLinkLoad(link.two) : null); |
575 | - link.addLoad(flowStatsService.load(link.one)); | 578 | + } else if (type == PORT) { |
576 | - link.addLoad(bi ? flowStatsService.load(link.two) : null); | 579 | + link.addLoad(portStatsService.load(link.one.src()), BPS_THRESHOLD); |
577 | - } else if (type == PORT) { | 580 | + link.addLoad(portStatsService.load(link.one.dst()), BPS_THRESHOLD); |
578 | - link.addLoad(portStatsService.load(link.one.src()), BPS_THRESHOLD); | 581 | + } |
579 | - link.addLoad(bi ? portStatsService.load(link.two.src()) : null, BPS_THRESHOLD); | 582 | + if (link.hasTraffic) { |
580 | - } | 583 | + linksNodeT.add(compactLinkString(link.one)); |
581 | - if (link.hasTraffic) { | 584 | + labelsT.add(type == PORT ? |
582 | - linksNodeT.add(compactLinkString(link.one)); | 585 | + formatBytes(link.rate) + "ps" : |
583 | - labelsT.add(type == PORT ? | 586 | + formatBytes(link.bytes)); |
584 | - formatBytes(link.rate) + "ps" : | 587 | + } else { |
585 | - formatBytes(link.bytes)); | 588 | + linksNodeN.add(compactLinkString(link.one)); |
586 | - } else { | 589 | + labelsN.add(""); |
587 | - linksNodeN.add(compactLinkString(link.one)); | ||
588 | - labelsN.add(""); | ||
589 | - } | ||
590 | } | 590 | } |
591 | } | 591 | } |
592 | return JsonUtils.envelope("showTraffic", 0, payload); | 592 | return JsonUtils.envelope("showTraffic", 0, payload); |
593 | } | 593 | } |
594 | 594 | ||
595 | - private Collection<BiLink> consolidateLinks(Iterable<Link> links) { | 595 | + private Load getLinkLoad(Link link) { |
596 | + if (link.src().elementId() instanceof DeviceId) { | ||
597 | + return flowStatsService.load(link); | ||
598 | + } | ||
599 | + return null; | ||
600 | + } | ||
601 | + | ||
602 | + private void addEdgeLinks(Map<LinkKey, BiLink> biLinks) { | ||
603 | + hostService.getHosts().forEach(host -> { | ||
604 | + addLink(biLinks, createEdgeLink(host.location(), false)); | ||
605 | + }); | ||
606 | + } | ||
607 | + | ||
608 | + private Map<LinkKey, BiLink> consolidateLinks(Iterable<Link> links) { | ||
596 | Map<LinkKey, BiLink> biLinks = new HashMap<>(); | 609 | Map<LinkKey, BiLink> biLinks = new HashMap<>(); |
597 | for (Link link : links) { | 610 | for (Link link : links) { |
598 | addLink(biLinks, link); | 611 | addLink(biLinks, link); |
599 | } | 612 | } |
600 | - return biLinks.values(); | 613 | + return biLinks; |
601 | } | 614 | } |
602 | 615 | ||
603 | // Produces JSON message to trigger flow overview visualization | 616 | // Produces JSON message to trigger flow overview visualization |
... | @@ -680,7 +693,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -680,7 +693,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
680 | ((LinkCollectionIntent) installable).links()); | 693 | ((LinkCollectionIntent) installable).links()); |
681 | } else if (installable instanceof OpticalPathIntent) { | 694 | } else if (installable instanceof OpticalPathIntent) { |
682 | classifyLinks(type, biLinks, trafficClass.showTraffic, | 695 | classifyLinks(type, biLinks, trafficClass.showTraffic, |
683 | - ((OpticalPathIntent) installable).path().links()); | 696 | + ((OpticalPathIntent) installable).path().links()); |
684 | } | 697 | } |
685 | } | 698 | } |
686 | } | 699 | } |
... | @@ -708,12 +721,10 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -708,12 +721,10 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
708 | if (links != null) { | 721 | if (links != null) { |
709 | for (Link link : links) { | 722 | for (Link link : links) { |
710 | BiLink biLink = addLink(biLinks, link); | 723 | BiLink biLink = addLink(biLinks, link); |
711 | - if (isInfrastructureEgress(link)) { | 724 | + if (showTraffic) { |
712 | - if (showTraffic) { | 725 | + biLink.addLoad(flowStatsService.load(link)); |
713 | - biLink.addLoad(flowStatsService.load(link)); | ||
714 | - } | ||
715 | - biLink.addClass(type); | ||
716 | } | 726 | } |
727 | + biLink.addClass(type); | ||
717 | } | 728 | } |
718 | } | 729 | } |
719 | } | 730 | } |
... | @@ -731,37 +742,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -731,37 +742,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
731 | return biLink; | 742 | return biLink; |
732 | } | 743 | } |
733 | 744 | ||
734 | - | ||
735 | - // Adds the link segments (path or tree) associated with the specified | ||
736 | - // connectivity intent | ||
737 | - protected void addPathTraffic(ArrayNode paths, String type, String trafficType, | ||
738 | - Iterable<Link> links) { | ||
739 | - ObjectNode pathNode = objectNode(); | ||
740 | - ArrayNode linksNode = arrayNode(); | ||
741 | - | ||
742 | - if (links != null) { | ||
743 | - ArrayNode labels = arrayNode(); | ||
744 | - boolean hasTraffic = false; | ||
745 | - for (Link link : links) { | ||
746 | - if (isInfrastructureEgress(link)) { | ||
747 | - linksNode.add(compactLinkString(link)); | ||
748 | - Load load = flowStatsService.load(link); | ||
749 | - String label = ""; | ||
750 | - if (load.rate() > 0) { | ||
751 | - hasTraffic = true; | ||
752 | - label = formatBytes(load.latest()); | ||
753 | - } | ||
754 | - labels.add(label); | ||
755 | - } | ||
756 | - } | ||
757 | - pathNode.put("class", hasTraffic ? type + " " + trafficType : type); | ||
758 | - pathNode.put("traffic", hasTraffic); | ||
759 | - pathNode.set("links", linksNode); | ||
760 | - pathNode.set("labels", labels); | ||
761 | - paths.add(pathNode); | ||
762 | - } | ||
763 | - } | ||
764 | - | ||
765 | // Poor-mans formatting to get the labels with byte counts looking nice. | 745 | // Poor-mans formatting to get the labels with byte counts looking nice. |
766 | private String formatBytes(long bytes) { | 746 | private String formatBytes(long bytes) { |
767 | // TODO: multiply everything by 8 to compute bits/second | 747 | // TODO: multiply everything by 8 to compute bits/second |
... | @@ -790,10 +770,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -790,10 +770,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
790 | return format.format(number); | 770 | return format.format(number); |
791 | } | 771 | } |
792 | 772 | ||
793 | - private boolean isInfrastructureEgress(Link link) { | ||
794 | - return link.src().elementId() instanceof DeviceId; | ||
795 | - } | ||
796 | - | ||
797 | // Produces compact string representation of a link. | 773 | // Produces compact string representation of a link. |
798 | private static String compactLinkString(Link link) { | 774 | private static String compactLinkString(Link link) { |
799 | return String.format(COMPACT, link.src().elementId(), link.src().port(), | 775 | return String.format(COMPACT, link.src().elementId(), link.src().port(), |
... | @@ -802,7 +778,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -802,7 +778,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
802 | 778 | ||
803 | // Produces JSON property details. | 779 | // Produces JSON property details. |
804 | private ObjectNode json(String id, String type, Prop... props) { | 780 | private ObjectNode json(String id, String type, Prop... props) { |
805 | - ObjectMapper mapper = new ObjectMapper(); | ||
806 | ObjectNode result = objectNode() | 781 | ObjectNode result = objectNode() |
807 | .put("id", id).put("type", type); | 782 | .put("id", id).put("type", type); |
808 | ObjectNode pnode = objectNode(); | 783 | ObjectNode pnode = objectNode(); |
... | @@ -848,7 +823,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -848,7 +823,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
848 | addLoad(load, 0); | 823 | addLoad(load, 0); |
849 | } | 824 | } |
850 | 825 | ||
851 | - void addLoad(Load load, long threshold) { | 826 | + void addLoad(Load load, double threshold) { |
852 | if (load != null) { | 827 | if (load != null) { |
853 | this.hasTraffic = hasTraffic || load.rate() > threshold; | 828 | this.hasTraffic = hasTraffic || load.rate() > threshold; |
854 | this.bytes += load.latest(); | 829 | this.bytes += load.latest(); | ... | ... |
-
Please register or login to post a comment