blob: 1472a1d78c767e51dbcb30ad1aae91fd1a7e91e1 [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
9from __future__ import unicode_literals
10
Allen Li325c0762017-03-02 15:00:19 -080011import psutil
12
13from chromite.lib import cros_logging as logging
14from infra_libs import ts_mon
15
16logger = logging.getLogger(__name__)
17
18_BOOT_TIME = psutil.boot_time()
19
20_net_up_metric = ts_mon.CounterMetric(
21 'dev/net/bytes/up', start_time=_BOOT_TIME,
22 description='Number of bytes sent on interface.',
23 units=ts_mon.MetricsDataUnits.BYTES)
24_net_down_metric = ts_mon.CounterMetric(
25 'dev/net/bytes/down', start_time=_BOOT_TIME,
26 description='Number of Bytes received on '
27 'interface.',
28 units=ts_mon.MetricsDataUnits.BYTES)
29_net_err_up_metric = ts_mon.CounterMetric(
30 'dev/net/err/up', start_time=_BOOT_TIME,
31 description='Total number of errors when '
32 'sending (per interface).')
33_net_err_down_metric = ts_mon.CounterMetric(
34 'dev/net/err/down', start_time=_BOOT_TIME,
35 description='Total number of errors when '
36 'receiving (per interface).')
37_net_drop_up_metric = ts_mon.CounterMetric(
38 'dev/net/drop/up', start_time=_BOOT_TIME,
39 description='Total number of outgoing '
40 'packets that have been dropped.')
41_net_drop_down_metric = ts_mon.CounterMetric(
42 'dev/net/drop/down', start_time=_BOOT_TIME,
43 description='Total number of incoming '
44 'packets that have been dropped.')
45
46_net_if_isup_metric = ts_mon.BooleanMetric(
47 'dev/net/isup',
48 description='Whether interface is up or down.')
49_net_if_duplex_metric = ts_mon.GaugeMetric(
50 'dev/net/duplex',
51 description='Whether interface supports full or half duplex.')
52_net_if_speed_metric = ts_mon.GaugeMetric(
53 'dev/net/speed',
54 description='Network interface speed in Mb.')
55_net_if_mtu_metric = ts_mon.GaugeMetric(
56 'dev/net/mtu',
57 description='Network interface MTU in B.')
58
59
60def collect_net_info():
61 """Collect network metrics."""
62 _collect_net_io_counters()
63 _collect_net_if_stats()
64
65
66_net_io_metrics = (
67 (_net_up_metric, 'bytes_sent'),
68 (_net_down_metric, 'bytes_recv'),
69 (_net_err_up_metric, 'errout'),
70 (_net_err_down_metric, 'errin'),
71 (_net_drop_up_metric, 'dropout'),
72 (_net_drop_down_metric, 'dropin'),
73)
74
75
76def _collect_net_io_counters():
77 """Collect metrics for network IO counters."""
Allen Li4bb931f2017-05-04 13:11:56 -070078 for nic, counters in _net_io_iter():
Allen Li325c0762017-03-02 15:00:19 -080079 fields = {'interface': nic}
80 for metric, counter_name in _net_io_metrics:
81 try:
82 metric.set(getattr(counters, counter_name), fields=fields)
83 except ts_mon.MonitoringDecreasingValueError as ex:
84 # This normally shouldn't happen, but might if the network
85 # driver module is reloaded, so log an error and continue
86 # instead of raising an exception.
87 logger.warning(str(ex))
88
89
Allen Li4bb931f2017-05-04 13:11:56 -070090def _net_io_iter():
91 """Generate network IO information."""
92 nics = psutil.net_io_counters(pernic=True)
93 for nic, counters in nics.iteritems():
94 if _is_virtual_netif(nic):
95 continue
96 yield nic, counters
97
98
Allen Li325c0762017-03-02 15:00:19 -080099_net_if_metrics = (
100 (_net_if_isup_metric, 'isup'),
101 (_net_if_duplex_metric, 'duplex'),
102 (_net_if_speed_metric, 'speed'),
103 (_net_if_mtu_metric, 'mtu'),
104)
105
106
107def _collect_net_if_stats():
108 """Collect metrics for network interface stats."""
109 for nic, stats in psutil.net_if_stats().iteritems():
110 if _is_virtual_netif(nic):
111 continue
112 fields = {'interface': nic}
113 for metric, counter_name in _net_if_metrics:
114 metric.set(getattr(stats, counter_name), fields=fields)
115
116
117def _is_virtual_netif(nic):
118 """Return whether the network interface is virtual."""
119 # TODO(ayatane): Use a different way of identifying virtual interfaces
120 return nic.startswith('veth')