summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicolargo <nicolas@nicolargo.com>2019-10-07 13:07:57 +0200
committernicolargo <nicolas@nicolargo.com>2019-10-07 13:07:57 +0200
commit7e6079912961f8cbbc54eb4e2989ade2a28c26f3 (patch)
tree4577be877bc2b6b5c5aea7190f1629430a9bf4b3
parent0f22ba723d31d46fe81f971398030926a7705d0c (diff)
parentf5ea9e8f4d637abf1d558fbdbc975a9abb43b475 (diff)
Resolve issue during merge
-rw-r--r--conf/glances.conf13
-rw-r--r--docs/aoa/connections.rst29
-rw-r--r--glances/outputs/glances_curses.py2
-rw-r--r--glances/plugins/glances_connections.py164
-rw-r--r--glances/plugins/glances_plugin.py3
5 files changed, 208 insertions, 3 deletions
diff --git a/conf/glances.conf b/conf/glances.conf
index 07c6f0c7..028def5a 100644
--- a/conf/glances.conf
+++ b/conf/glances.conf
@@ -6,7 +6,7 @@
# Does Glances should check if a newer version is available on PyPI ?
check_update=true
# History size (maximum number of values)
-# Default is 28800: 1 day with 1 point every 3 seconds (default refresh time)
+# Default is 28800: 1 day with 1 point every 3 seconds
history_size=28800
##############################################################################
@@ -26,7 +26,7 @@ max_processes_display=30
[quicklook]
# Set to true to disable a plugin
# Note: you can also disable it from the command line (see --disable-plugin)
-disable=false
+disable=False
# Graphical percentage char used in the terminal user interface (default is |)
percentage_char=|
# Define CPU, MEM and SWAP thresholds in %
@@ -139,6 +139,15 @@ tx_critical=90
#wlan0_tx_critical=1000000
#wlan0_tx_log=True
+[connections]
+# Display additional information about TCP connections
+# This plugin will be disable by default
+disable=True
+# nf_conntrack thresholds in %
+nf_conntrack_percent_careful=70
+nf_conntrack_percent_warning=80
+nf_conntrack_percent_critical=90
+
[wifi]
# Define the list of hidden wireless network interfaces (comma-separated regexp)
hide=lo,docker.*
diff --git a/docs/aoa/connections.rst b/docs/aoa/connections.rst
new file mode 100644
index 00000000..320dcb29
--- /dev/null
+++ b/docs/aoa/connections.rst
@@ -0,0 +1,29 @@
+.. _connections:
+
+Connections
+===========
+
+.. image:: ../_static/connections.png
+
+This plugin display extended information about network connections.
+
+The states are the following:
+- Listen: all ports created by server and waiting for a client to connect
+- Initialized: All states when a connection is initialized (sum of SYN_SENT and SYN_RECEIVED)
+- Established: All established connections between a client and a server
+- Terminated: All states when a connection is terminated (FIN_WAIT1, CLOSE_WAIT, LAST_ACK, FIN_WAIT2, TIME_WAIT and CLOSE)
+- Tracked: Current number and maximum Netfilter tracker connection (nf_conntrack_count/nf_conntrack_max)
+
+The configuration should be done in the ``[connections]`` section of the
+Glances configuration file.
+
+By default the plugin is **disabled**. Please change your configuration file as following to enable it
+
+.. code-block:: ini
+
+ [connections]
+ disable=False
+ # nf_conntrack thresholds in %
+ nf_conntrack_percent_careful=70
+ nf_conntrack_percent_warning=80
+ nf_conntrack_percent_critical=90
diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py
index 4a4b7632..dac51e07 100644
--- a/glances/outputs/glances_curses.py
+++ b/glances/outputs/glances_curses.py
@@ -96,7 +96,7 @@ class _GlancesCurses(object):
_quicklook_max_width = 68
# Define left sidebar
- _left_sidebar = ['network', 'wifi', 'ports', 'diskio', 'fs',
+ _left_sidebar = ['network', 'connections', 'wifi', 'ports', 'diskio', 'fs',
'irq', 'folders', 'raid', 'sensors', 'now']
_left_sidebar_min_width = 23
_left_sidebar_max_width = 34
diff --git a/glances/plugins/glances_connections.py b/glances/plugins/glances_connections.py
new file mode 100644
index 00000000..cda7a1ba
--- /dev/null
+++ b/glances/plugins/glances_connections.py
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+#
+# This file is part of Glances.
+#
+# Copyright (C) 2019 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/>.
+
+"""Connections plugin."""
+from __future__ import unicode_literals
+
+from glances.logger import logger
+from glances.timer import getTimeSinceLastUpdate
+from glances.plugins.glances_plugin import GlancesPlugin
+from glances.compat import n, u, b, nativestr
+
+import psutil
+
+# Define the history items list
+# items_history_list = [{'name': 'rx',
+# 'description': 'Download rate per second',
+# 'y_unit': 'bit/s'},
+# {'name': 'tx',
+# 'description': 'Upload rate per second',
+# 'y_unit': 'bit/s'}]
+
+
+class Plugin(GlancesPlugin):
+ """Glances connections plugin.
+
+ stats is a dict
+ """
+
+ status_list = [psutil.CONN_LISTEN,
+ psutil.CONN_ESTABLISHED]
+ initiated_states = [psutil.CONN_SYN_SENT,
+ psutil.CONN_SYN_RECV]
+ terminated_states = [psutil.CONN_FIN_WAIT1,
+ psutil.CONN_FIN_WAIT2,
+ psutil.CONN_TIME_WAIT,
+ psutil.CONN_CLOSE,
+ psutil.CONN_CLOSE_WAIT,
+ psutil.CONN_LAST_ACK]
+ conntrack = {'nf_conntrack_count': '/proc/sys/net/netfilter/nf_conntrack_count',
+ 'nf_conntrack_max': '/proc/sys/net/netfilter/nf_conntrack_max'}
+
+ def __init__(self, args=None, config=None):
+ """Init the plugin."""
+ super(Plugin, self).__init__(args=args,
+ config=config,
+ # items_history_list=items_history_list,
+ stats_init_value={})
+
+ # We want to display the stat in the curse interface
+ self.display_curse = True
+
+ # @TODO the plugin should be enable only for Linux OS
+
+ @GlancesPlugin._check_decorator
+ @GlancesPlugin._log_result_decorator
+ def update(self):
+ """Update connections stats using the input method.
+
+ Stats is a dict
+ """
+ # Init new stats
+ stats = self.get_init_value()
+
+ if self.input_method == 'local':
+ # Update stats using the PSUtils lib
+
+ # Grab network interface stat using the psutil net_connections method
+ try:
+ net_connections = psutil.net_connections(kind="tcp")
+ except Exception as e:
+ logger.debug('Can not get network connections stats ({})'.format(e))
+ return self.stats
+
+ for s in self.status_list:
+ stats[s] = len([c for c in net_connections if c.status == s])
+ initiated = 0
+ for s in self.initiated_states:
+ stats[s] = len([c for c in net_connections if c.status == s])
+ initiated += stats[s]
+ stats['initiated'] = initiated
+ terminated = 0
+ for s in self.initiated_states:
+ stats[s] = len([c for c in net_connections if c.status == s])
+ terminated += stats[s]
+ stats['terminated'] = terminated
+
+ # Grab connections track directly from the /proc file
+ for i in self.conntrack:
+ with open(self.conntrack[i], 'r') as f:
+ stats[i] = float(f.readline().rstrip("\n"))
+ stats['nf_conntrack_percent'] = stats['nf_conntrack_count'] * 100 / stats['nf_conntrack_max']
+
+ elif self.input_method == 'snmp':
+ # Update stats using SNMP
+ pass
+
+ # Update the stats
+ self.stats = stats
+
+ return self.stats
+
+ def update_views(self):
+ """Update stats views."""
+ # Call the father's method
+ super(Plugin, self).update_views()
+
+ # Add specifics informations
+ try:
+ # Alert and log
+ self.views['nf_conntrack_percent']['decoration'] = self.get_alert(header='nf_conntrack_percent')
+ except KeyError:
+ # try/except mandatory for Windows compatibility (no conntrack stats)
+ pass
+
+ def msg_curse(self, args=None, max_width=None):
+ """Return the dict to display in the curse interface."""
+ # Init the return message
+ ret = []
+
+ logger.info(self.is_disable())
+
+ # Only process if stats exist and display plugin enable...
+ if not self.stats or self.is_disable():
+ return ret
+
+ # Header
+ msg = '{}'.format('TCP CONNECTIONS')
+ ret.append(self.curse_add_line(msg, "TITLE"))
+ # Connections status
+ for s in [psutil.CONN_LISTEN, 'initiated', psutil.CONN_ESTABLISHED, 'terminated']:
+ ret.append(self.curse_new_line())
+ msg = '{:{width}}'.format(nativestr(s).capitalize(), width=len(s))
+ ret.append(self.curse_add_line(msg))
+ msg = '{:>{width}}'.format(self.stats[s], width=max_width - len(s) + 2)
+ ret.append(self.curse_add_line(msg))
+ # Connections track
+ s = 'Tracked'
+ ret.append(self.curse_new_line())
+ msg = '{:{width}}'.format(nativestr(s).capitalize(), width=len(s))
+ ret.append(self.curse_add_line(msg))
+ msg = '{:>{width}}'.format('{:0.0f}/{:0.0f}'.format(self.stats['nf_conntrack_count'],
+ self.stats['nf_conntrack_max']),
+ width=max_width - len(s) + 2)
+ ret.append(self.curse_add_line(msg,
+ self.get_views(key='nf_conntrack_percent',
+ option='decoration')))
+
+ return ret
diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py
index 84c5cc2f..0856cac3 100644
--- a/glances/plugins/glances_plugin.py
+++ b/glances/plugins/glances_plugin.py
@@ -90,6 +90,9 @@ class GlancesPlugin(object):
if not self.load_limits(config=config):
logger.debug('Can not load section {} in {}'.format(self.plugin_name,
config))
+ else:
+ logger.debug('Load section {} in {}'.format(self.plugin_name,
+ config))
# Init the actions
self.actions = GlancesActions(args=args)