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