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