glances_network.py 7.3 KB
Newer Older
A
Alessio Sergi 已提交
1 2
# -*- coding: utf-8 -*-
#
3
# This file is part of Glances.
A
Alessio Sergi 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#
# Copyright (C) 2014 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
N
Nicolas Hennion 已提交
19 20 21
"""
Glances Network interface plugin
"""
A
Alessio Sergi 已提交
22 23

# Import system libs
N
Nicolas Hennion 已提交
24
from psutil import net_io_counters
A
Alessio Sergi 已提交
25 26

# Import Glances lib
N
Nicolas Hennion 已提交
27
from glances.plugins.glances_plugin import GlancesPlugin
A
Alessio Sergi 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
from glances.core.glances_timer import getTimeSinceLastUpdate


class Plugin(GlancesPlugin):
    """
    Glances's network Plugin

    stats is a list
    """

    def __init__(self):
        GlancesPlugin.__init__(self)

        # We want to display the stat in the curse interface
        self.display_curse = True
        # Set the message position
        # It is NOT the curse position but the Glances column/line
        # Enter -1 to right align
        self.column_curse = 0
        # Enter -1 to diplay bottom
        self.line_curse = 2

N
Nicolas Hennion 已提交
50 51 52 53
        # Init stats
        self.network_old = []


A
Alessio Sergi 已提交
54 55 56
    def update(self):
        """
        Update network stats
N
Nicolas Hennion 已提交
57
        Stats is a list of dict (one dict per interface)
A
Alessio Sergi 已提交
58 59
        """

N
Nicolas Hennion 已提交
60 61
        # Grab network interface stat using the PsUtil net_io_counter method
        netiocounters = net_io_counters(pernic=True)
A
Alessio Sergi 已提交
62 63

        # Previous network interface stats are stored in the network_old variable
N
Nicolas Hennion 已提交
64 65
        network = []
        if (self.network_old == []):
A
Alessio Sergi 已提交
66 67
            # First call, we init the network_old var
            try:
N
Nicolas Hennion 已提交
68
                self.network_old = netiocounters
A
Alessio Sergi 已提交
69 70 71
            except (IOError, UnboundLocalError):
                pass
        else:
N
Nicolas Hennion 已提交
72 73 74 75 76 77 78
            # By storing time data we enable Rx/s and Tx/s calculations in the
            # XML/RPC API, which would otherwise be overly difficult work
            # for users of the API
            time_since_update = getTimeSinceLastUpdate('net')

            # Loop over interfaces
            network_new = netiocounters
A
Alessio Sergi 已提交
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
            for net in network_new:
                try:
                    # Try necessary to manage dynamic network interface
                    netstat = {}
                    netstat['time_since_update'] = time_since_update
                    netstat['interface_name'] = net
                    netstat['cumulative_rx'] = network_new[net].bytes_recv
                    netstat['rx'] = (network_new[net].bytes_recv -
                                     self.network_old[net].bytes_recv)
                    netstat['cumulative_tx'] = network_new[net].bytes_sent
                    netstat['tx'] = (network_new[net].bytes_sent -
                                     self.network_old[net].bytes_sent)
                    netstat['cumulative_cx'] = (netstat['cumulative_rx'] +
                                                netstat['cumulative_tx'])
                    netstat['cx'] = netstat['rx'] + netstat['tx']
N
Nicolas Hennion 已提交
94
                except KeyError:
A
Alessio Sergi 已提交
95 96 97 98 99 100 101
                    continue
                else:
                    network.append(netstat)
            self.network_old = network_new

        self.stats = network

N
Nicolas Hennion 已提交
102 103
        return self.stats

A
Alessio Sergi 已提交
104 105 106 107
    def msg_curse(self, args=None):
        """
        Return the dict to display in the curse interface
        """
N
Nicolas Hennion 已提交
108 109 110 111

        #!!! TODO: Add alert on network interface bitrate
        #!!! TODO: Manage the hide tag to hide a list of net interface

A
Alessio Sergi 已提交
112 113 114
        # Init the return message
        ret = []

115 116
        # Only process if stats exist and display plugin enable...
        if ((self.stats == []) or (args.disable_network)):
117 118
            return ret

A
Alessio Sergi 已提交
119 120
        # Build the string message
        # Header
121
        msg = "{0:9}".format(_("NETWORK"))
A
Alessio Sergi 已提交
122
        ret.append(self.curse_add_line(msg, "TITLE"))
123
        if (args.network_cumul):
N
Nicolas Hennion 已提交
124
            # Cumulative stats
125 126
            if (args.network_sum):
                # Sum stats
127
                msg = "{0:>14}".format(_("Rx+Tx"))
128 129 130
                ret.append(self.curse_add_line(msg))
            else:
                # Rx/Tx stats
131
                msg = "{0:>7}".format(_("Rx"))
132
                ret.append(self.curse_add_line(msg))
133
                msg = "{0:>7}".format(_("Tx"))
134
                ret.append(self.curse_add_line(msg))
N
Nicolas Hennion 已提交
135 136
        else:
            # Bitrate stats
137 138
            if (args.network_sum):
                # Sum stats
139
                msg = "{0:>14}".format(_("Rx+Tx/s"))
140 141
                ret.append(self.curse_add_line(msg))
            else:
142
                msg = "{0:>7}".format(_("Rx/s"))
143
                ret.append(self.curse_add_line(msg))
144
                msg = "{0:>7}".format(_("Tx/s"))
145
                ret.append(self.curse_add_line(msg))            
A
Alessio Sergi 已提交
146 147
        # Interface list (sorted by name)
        for i in sorted(self.stats, key=lambda network: network['interface_name']):
148 149 150
            # Do not display hidden interfaces
            if (self.is_hide(i['interface_name'])):
                continue
A
Alessio Sergi 已提交
151 152 153
            # Format stats
            ifname = i['interface_name'].split(':')[0]
            if (args.byte):
154 155 156 157 158
                if (args.network_cumul):
                    rx = self.auto_unit(int(i['cumulative_rx']))
                    tx = self.auto_unit(int(i['cumulative_tx']))
                    sx = self.auto_unit(int(i['cumulative_tx']) 
                                        + int(i['cumulative_tx']))
N
Nicolas Hennion 已提交
159
                else:
160 161 162 163
                    rx = self.auto_unit(int(i['rx'] // i['time_since_update']))
                    tx = self.auto_unit(int(i['tx'] // i['time_since_update']))
                    sx = self.auto_unit(int(i['rx'] // i['time_since_update']) 
                                        + int(i['tx'] // i['time_since_update']))
A
Alessio Sergi 已提交
164
            else:
165 166 167 168 169
                if (args.network_cumul):
                    rx = self.auto_unit(int(i['cumulative_rx'] * 8)) + "b"
                    tx = self.auto_unit(int(i['cumulative_tx'] * 8)) + "b"
                    sx = self.auto_unit(int(i['cumulative_rx'] * 8) 
                                        + int(i['cumulative_tx'] * 8)) + "b"
N
Nicolas Hennion 已提交
170
                else:
171 172 173 174
                    rx = self.auto_unit(int(i['rx'] // i['time_since_update'] * 8)) + "b"
                    tx = self.auto_unit(int(i['tx'] // i['time_since_update'] * 8)) + "b"                    
                    sx = self.auto_unit(int(i['rx'] // i['time_since_update'] * 8) +
                                        int(i['tx'] // i['time_since_update'] * 8)) + "b"
A
Alessio Sergi 已提交
175 176
            # New line
            ret.append(self.curse_new_line())
177
            msg = "{0:9}".format(ifname)
A
Alessio Sergi 已提交
178
            ret.append(self.curse_add_line(msg))
179
            if (args.network_sum):
180
                msg = "{0:>14}".format(sx)
181 182
                ret.append(self.curse_add_line(msg))
            else:
183
                msg = "{0:>7}".format(rx)
184
                ret.append(self.curse_add_line(msg))
185
                msg = "{0:>7}".format(tx)
186
                ret.append(self.curse_add_line(msg))
A
Alessio Sergi 已提交
187 188

        return ret