blob: 83baf72d91245a545c6a61ed21cc388c77b40730 [file] [log] [blame]
Allen Li325c0762017-03-02 15:00:19 -08001# Copyright 2017 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Network metrics."""
6
Allen Li13bdf0c2017-03-02 15:18:16 -08007from __future__ import absolute_import
8from __future__ import print_function
Allen Li13bdf0c2017-03-02 15:18:16 -08009
Allen Lieb107022017-05-04 13:19:17 -070010import collections
11
Allen Li325c0762017-03-02 15:00:19 -080012import psutil
13
14from chromite.lib import cros_logging as logging
Allen Lia9c6e802017-07-11 15:42:47 -070015from chromite.lib import metrics
16
Allen Li325c0762017-03-02 15:00:19 -080017from infra_libs import ts_mon
18
19logger = logging.getLogger(__name__)
20
21_BOOT_TIME = psutil.boot_time()
22
Allen Lia9c6e802017-07-11 15:42:47 -070023_net_up_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080024 'dev/net/bytes/up', start_time=_BOOT_TIME,
25 description='Number of bytes sent on interface.',
26 units=ts_mon.MetricsDataUnits.BYTES)
Allen Lia9c6e802017-07-11 15:42:47 -070027_net_down_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080028 'dev/net/bytes/down', start_time=_BOOT_TIME,
29 description='Number of Bytes received on '
30 'interface.',
Allen Lia9c6e802017-07-11 15:42:47 -070031 units=metrics.MetricsDataUnits.BYTES)
32_net_err_up_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080033 'dev/net/err/up', start_time=_BOOT_TIME,
34 description='Total number of errors when '
35 'sending (per interface).')
Allen Lia9c6e802017-07-11 15:42:47 -070036_net_err_down_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080037 'dev/net/err/down', start_time=_BOOT_TIME,
38 description='Total number of errors when '
39 'receiving (per interface).')
Allen Lia9c6e802017-07-11 15:42:47 -070040_net_drop_up_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080041 'dev/net/drop/up', start_time=_BOOT_TIME,
42 description='Total number of outgoing '
43 'packets that have been dropped.')
Allen Lia9c6e802017-07-11 15:42:47 -070044_net_drop_down_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080045 'dev/net/drop/down', start_time=_BOOT_TIME,
46 description='Total number of incoming '
47 'packets that have been dropped.')
48
Allen Lia9c6e802017-07-11 15:42:47 -070049_net_bytes_metric = metrics.CounterMetric(
Allen Lieb107022017-05-04 13:19:17 -070050 'dev/net/bytes', start_time=_BOOT_TIME,
51 description='Number of bytes up/down on interface.',
Allen Lia9c6e802017-07-11 15:42:47 -070052 units=metrics.MetricsDataUnits.BYTES)
53_net_packets_metric = metrics.CounterMetric(
Allen Lieb107022017-05-04 13:19:17 -070054 'dev/net/packets', start_time=_BOOT_TIME,
55 description='Number of packets up/down on interface.',
Allen Lia9c6e802017-07-11 15:42:47 -070056 units=metrics.MetricsDataUnits.BYTES)
57_net_errors_metric = metrics.CounterMetric(
Allen Lieb107022017-05-04 13:19:17 -070058 'dev/net/errors', start_time=_BOOT_TIME,
59 description='Total number of errors up/down on interface.')
Allen Lia9c6e802017-07-11 15:42:47 -070060_net_dropped_metric = metrics.CounterMetric(
Allen Lieb107022017-05-04 13:19:17 -070061 'dev/net/dropped', start_time=_BOOT_TIME,
62 description='Total number of dropped packages up/down on interface.')
63
Allen Lia9c6e802017-07-11 15:42:47 -070064_net_if_isup_metric = metrics.BooleanMetric(
Allen Li325c0762017-03-02 15:00:19 -080065 'dev/net/isup',
66 description='Whether interface is up or down.')
Allen Lia9c6e802017-07-11 15:42:47 -070067_net_if_duplex_metric = metrics.GaugeMetric(
Allen Li325c0762017-03-02 15:00:19 -080068 'dev/net/duplex',
69 description='Whether interface supports full or half duplex.')
Allen Lia9c6e802017-07-11 15:42:47 -070070_net_if_speed_metric = metrics.GaugeMetric(
Allen Li325c0762017-03-02 15:00:19 -080071 'dev/net/speed',
72 description='Network interface speed in Mb.')
Allen Lia9c6e802017-07-11 15:42:47 -070073_net_if_mtu_metric = metrics.GaugeMetric(
Allen Li325c0762017-03-02 15:00:19 -080074 'dev/net/mtu',
75 description='Network interface MTU in B.')
76
77
78def collect_net_info():
79 """Collect network metrics."""
80 _collect_net_io_counters()
Allen Lieb107022017-05-04 13:19:17 -070081 _collect_net_io_duplex_counters()
Allen Li325c0762017-03-02 15:00:19 -080082 _collect_net_if_stats()
83
84
Allen Lieb107022017-05-04 13:19:17 -070085# Network IO metrics to collect
86_IOMetric = collections.namedtuple('_IOMetric', ['metric', 'up_counter_name',
87 'down_counter_name'])
88
89_net_io_duplex_metrics = (
90 _IOMetric(metric=_net_bytes_metric,
91 up_counter_name='bytes_sent',
92 down_counter_name='bytes_recv'),
93 _IOMetric(metric=_net_packets_metric,
94 up_counter_name='packets_sent',
95 down_counter_name='packets_recv'),
96 _IOMetric(metric=_net_errors_metric,
97 up_counter_name='errout',
98 down_counter_name='errin'),
Allen Lif90a22e2017-05-19 18:24:25 -070099 _IOMetric(metric=_net_dropped_metric,
Allen Lieb107022017-05-04 13:19:17 -0700100 up_counter_name='dropout',
101 down_counter_name='dropin'),
102)
103
104
105def _collect_net_io_duplex_counters():
106 """Collect metrics for network IO duplex counters."""
107 for nic, counters in _net_io_iter():
108 fields = {'interface': nic}
109 for metric, up_counter_name, down_counter_name in _net_io_duplex_metrics:
110 try:
111 metric.set(getattr(counters, up_counter_name),
112 fields=dict(direction='up', **fields))
113 metric.set(getattr(counters, down_counter_name),
114 fields=dict(direction='down', **fields))
Allen Lia9c6e802017-07-11 15:42:47 -0700115 except metrics.MonitoringDecreasingValueError as ex:
Allen Lieb107022017-05-04 13:19:17 -0700116 # This normally shouldn't happen, but might if the network
117 # driver module is reloaded, so log an error and continue
118 # instead of raising an exception.
119 logger.warning(str(ex))
120
121
Allen Li325c0762017-03-02 15:00:19 -0800122_net_io_metrics = (
123 (_net_up_metric, 'bytes_sent'),
124 (_net_down_metric, 'bytes_recv'),
125 (_net_err_up_metric, 'errout'),
126 (_net_err_down_metric, 'errin'),
127 (_net_drop_up_metric, 'dropout'),
128 (_net_drop_down_metric, 'dropin'),
129)
130
131
132def _collect_net_io_counters():
133 """Collect metrics for network IO counters."""
Allen Li4bb931f2017-05-04 13:11:56 -0700134 for nic, counters in _net_io_iter():
Allen Li325c0762017-03-02 15:00:19 -0800135 fields = {'interface': nic}
136 for metric, counter_name in _net_io_metrics:
137 try:
138 metric.set(getattr(counters, counter_name), fields=fields)
139 except ts_mon.MonitoringDecreasingValueError as ex:
140 # This normally shouldn't happen, but might if the network
141 # driver module is reloaded, so log an error and continue
142 # instead of raising an exception.
143 logger.warning(str(ex))
144
145
Allen Li4bb931f2017-05-04 13:11:56 -0700146def _net_io_iter():
147 """Generate network IO information."""
148 nics = psutil.net_io_counters(pernic=True)
149 for nic, counters in nics.iteritems():
150 if _is_virtual_netif(nic):
151 continue
152 yield nic, counters
153
154
Allen Li325c0762017-03-02 15:00:19 -0800155_net_if_metrics = (
156 (_net_if_isup_metric, 'isup'),
157 (_net_if_duplex_metric, 'duplex'),
158 (_net_if_speed_metric, 'speed'),
159 (_net_if_mtu_metric, 'mtu'),
160)
161
162
163def _collect_net_if_stats():
164 """Collect metrics for network interface stats."""
165 for nic, stats in psutil.net_if_stats().iteritems():
166 if _is_virtual_netif(nic):
167 continue
168 fields = {'interface': nic}
169 for metric, counter_name in _net_if_metrics:
170 metric.set(getattr(stats, counter_name), fields=fields)
171
172
173def _is_virtual_netif(nic):
174 """Return whether the network interface is virtual."""
175 # TODO(ayatane): Use a different way of identifying virtual interfaces
176 return nic.startswith('veth')