blob: b0087e719b40e25d38b1a0204b3dd0231e34bc57 [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
Allen Li325c0762017-03-02 15:00:19 -080016from infra_libs import ts_mon
17
18logger = logging.getLogger(__name__)
19
20_BOOT_TIME = psutil.boot_time()
21
Allen Lia9c6e802017-07-11 15:42:47 -070022_net_up_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080023 'dev/net/bytes/up', start_time=_BOOT_TIME,
Allen Li22989bd2017-07-12 10:34:37 -070024 description='Number of bytes sent on interface.')
Allen Lia9c6e802017-07-11 15:42:47 -070025_net_down_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080026 'dev/net/bytes/down', start_time=_BOOT_TIME,
27 description='Number of Bytes received on '
Allen Li22989bd2017-07-12 10:34:37 -070028 'interface.')
Allen Lia9c6e802017-07-11 15:42:47 -070029_net_err_up_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080030 'dev/net/err/up', start_time=_BOOT_TIME,
31 description='Total number of errors when '
32 'sending (per interface).')
Allen Lia9c6e802017-07-11 15:42:47 -070033_net_err_down_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080034 'dev/net/err/down', start_time=_BOOT_TIME,
35 description='Total number of errors when '
36 'receiving (per interface).')
Allen Lia9c6e802017-07-11 15:42:47 -070037_net_drop_up_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080038 'dev/net/drop/up', start_time=_BOOT_TIME,
39 description='Total number of outgoing '
40 'packets that have been dropped.')
Allen Lia9c6e802017-07-11 15:42:47 -070041_net_drop_down_metric = metrics.CounterMetric(
Allen Li325c0762017-03-02 15:00:19 -080042 'dev/net/drop/down', start_time=_BOOT_TIME,
43 description='Total number of incoming '
44 'packets that have been dropped.')
45
Allen Lia9c6e802017-07-11 15:42:47 -070046_net_bytes_metric = metrics.CounterMetric(
Allen Lieb107022017-05-04 13:19:17 -070047 'dev/net/bytes', start_time=_BOOT_TIME,
Allen Li22989bd2017-07-12 10:34:37 -070048 description='Number of bytes up/down on interface.')
Allen Lia9c6e802017-07-11 15:42:47 -070049_net_packets_metric = metrics.CounterMetric(
Allen Lieb107022017-05-04 13:19:17 -070050 'dev/net/packets', start_time=_BOOT_TIME,
Allen Li22989bd2017-07-12 10:34:37 -070051 description='Number of packets up/down on interface.')
Allen Lia9c6e802017-07-11 15:42:47 -070052_net_errors_metric = metrics.CounterMetric(
Allen Lieb107022017-05-04 13:19:17 -070053 'dev/net/errors', start_time=_BOOT_TIME,
54 description='Total number of errors up/down on interface.')
Allen Lia9c6e802017-07-11 15:42:47 -070055_net_dropped_metric = metrics.CounterMetric(
Allen Lieb107022017-05-04 13:19:17 -070056 'dev/net/dropped', start_time=_BOOT_TIME,
57 description='Total number of dropped packages up/down on interface.')
58
Allen Lia9c6e802017-07-11 15:42:47 -070059_net_if_isup_metric = metrics.BooleanMetric(
Allen Li325c0762017-03-02 15:00:19 -080060 'dev/net/isup',
61 description='Whether interface is up or down.')
Allen Lia9c6e802017-07-11 15:42:47 -070062_net_if_duplex_metric = metrics.GaugeMetric(
Allen Li325c0762017-03-02 15:00:19 -080063 'dev/net/duplex',
64 description='Whether interface supports full or half duplex.')
Allen Lia9c6e802017-07-11 15:42:47 -070065_net_if_speed_metric = metrics.GaugeMetric(
Allen Li325c0762017-03-02 15:00:19 -080066 'dev/net/speed',
67 description='Network interface speed in Mb.')
Allen Lia9c6e802017-07-11 15:42:47 -070068_net_if_mtu_metric = metrics.GaugeMetric(
Allen Li325c0762017-03-02 15:00:19 -080069 'dev/net/mtu',
70 description='Network interface MTU in B.')
71
72
73def collect_net_info():
74 """Collect network metrics."""
75 _collect_net_io_counters()
Allen Lieb107022017-05-04 13:19:17 -070076 _collect_net_io_duplex_counters()
Allen Li325c0762017-03-02 15:00:19 -080077 _collect_net_if_stats()
78
79
Allen Lieb107022017-05-04 13:19:17 -070080# Network IO metrics to collect
81_IOMetric = collections.namedtuple('_IOMetric', ['metric', 'up_counter_name',
82 'down_counter_name'])
83
84_net_io_duplex_metrics = (
Allen Li22989bd2017-07-12 10:34:37 -070085 _IOMetric(metric=_net_bytes_metric,
86 up_counter_name='bytes_sent',
87 down_counter_name='bytes_recv'),
88 _IOMetric(metric=_net_packets_metric,
89 up_counter_name='packets_sent',
90 down_counter_name='packets_recv'),
91 _IOMetric(metric=_net_errors_metric,
92 up_counter_name='errout',
93 down_counter_name='errin'),
94 _IOMetric(metric=_net_dropped_metric,
95 up_counter_name='dropout',
96 down_counter_name='dropin'),
Allen Lieb107022017-05-04 13:19:17 -070097)
98
99
100def _collect_net_io_duplex_counters():
101 """Collect metrics for network IO duplex counters."""
102 for nic, counters in _net_io_iter():
103 fields = {'interface': nic}
104 for metric, up_counter_name, down_counter_name in _net_io_duplex_metrics:
105 try:
106 metric.set(getattr(counters, up_counter_name),
107 fields=dict(direction='up', **fields))
108 metric.set(getattr(counters, down_counter_name),
109 fields=dict(direction='down', **fields))
Allen Lia9c6e802017-07-11 15:42:47 -0700110 except metrics.MonitoringDecreasingValueError as ex:
Allen Lieb107022017-05-04 13:19:17 -0700111 # This normally shouldn't happen, but might if the network
112 # driver module is reloaded, so log an error and continue
113 # instead of raising an exception.
114 logger.warning(str(ex))
115
116
Allen Li325c0762017-03-02 15:00:19 -0800117_net_io_metrics = (
Allen Li22989bd2017-07-12 10:34:37 -0700118 (_net_up_metric, 'bytes_sent'),
119 (_net_down_metric, 'bytes_recv'),
120 (_net_err_up_metric, 'errout'),
121 (_net_err_down_metric, 'errin'),
122 (_net_drop_up_metric, 'dropout'),
123 (_net_drop_down_metric, 'dropin'),
Allen Li325c0762017-03-02 15:00:19 -0800124)
125
126
127def _collect_net_io_counters():
128 """Collect metrics for network IO counters."""
Allen Li4bb931f2017-05-04 13:11:56 -0700129 for nic, counters in _net_io_iter():
Allen Li325c0762017-03-02 15:00:19 -0800130 fields = {'interface': nic}
131 for metric, counter_name in _net_io_metrics:
132 try:
133 metric.set(getattr(counters, counter_name), fields=fields)
134 except ts_mon.MonitoringDecreasingValueError as ex:
135 # This normally shouldn't happen, but might if the network
136 # driver module is reloaded, so log an error and continue
137 # instead of raising an exception.
138 logger.warning(str(ex))
139
140
Allen Li4bb931f2017-05-04 13:11:56 -0700141def _net_io_iter():
142 """Generate network IO information."""
143 nics = psutil.net_io_counters(pernic=True)
144 for nic, counters in nics.iteritems():
145 if _is_virtual_netif(nic):
146 continue
147 yield nic, counters
148
149
Allen Li325c0762017-03-02 15:00:19 -0800150_net_if_metrics = (
Allen Li22989bd2017-07-12 10:34:37 -0700151 (_net_if_isup_metric, 'isup'),
152 (_net_if_duplex_metric, 'duplex'),
153 (_net_if_speed_metric, 'speed'),
154 (_net_if_mtu_metric, 'mtu'),
Allen Li325c0762017-03-02 15:00:19 -0800155)
156
157
158def _collect_net_if_stats():
159 """Collect metrics for network interface stats."""
160 for nic, stats in psutil.net_if_stats().iteritems():
161 if _is_virtual_netif(nic):
162 continue
163 fields = {'interface': nic}
164 for metric, counter_name in _net_if_metrics:
165 metric.set(getattr(stats, counter_name), fields=fields)
166
167
168def _is_virtual_netif(nic):
Allen Li22989bd2017-07-12 10:34:37 -0700169 """Return whether the network interface is virtual."""
170 # TODO(ayatane): Use a different way of identifying virtual interfaces
171 return nic.startswith('veth')