Merge branch 'issue3528' into develop

This commit is contained in:
nicolargo 2025-08-01 17:20:08 +02:00
commit 04fee963cc
8 changed files with 5260 additions and 4579 deletions

View File

@ -605,6 +605,11 @@ disable=False
# Exports
##############################################################################
[export]
# Common section for all exporters
# Do not export following fields (comma separated list of regex)
exclude_fields=.*_critical,.*_careful,.*_warning,.*\.key$
[graph]
# Configuration for the --export graph option
# Set the path where the graph (.svg files) will be created

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,24 @@
Gateway To Other Services
=========================
Glances can exports stats to a CSV file. Also, it can act as a gateway
to providing stats to multiple services (see list below).
Glances can exports stats in files or to other services like databases, message queues, etc.
Each exporter has its own configuration options, which can be set in the Glances
configuration file (`glances.conf`).
A common options section is also available:
is the `exclude_fields` option, which allows you to specify
.. code-block:: ini
[export]
# Common section for all exporters
# Do not export following fields (comma separated list of regex)
exclude_fields=.*_critical,.*_careful,.*_warning,.*\.key$
This section describes the available exporters and how to configure them:
.. toctree::
:maxdepth: 2
@ -14,6 +30,7 @@ to providing stats to multiple services (see list below).
couchdb
elastic
graph
graphite
influxdb
json
kafka

View File

@ -28,7 +28,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "GLANCES" "1" "Jul 27, 2025" "4.4.0_dev1" "Glances"
.TH "GLANCES" "1" "Aug 01, 2025" "4.4.0_dev1" "Glances"
.SH NAME
glances \- An eye on your system
.SH SYNOPSIS

View File

@ -365,3 +365,4 @@ class Config:
return self.parser.getboolean(section, option)
except (NoOptionError, NoSectionError):
return bool(default)
return bool(default)

View File

@ -11,6 +11,8 @@ I am your father...
...for all Glances exports IF.
"""
import re
from glances.globals import NoOptionError, NoSectionError, json_dumps
from glances.logger import logger
from glances.timer import Counter
@ -53,6 +55,10 @@ class GlancesExport:
# Fields description
self._fields_description = None
# Load the default common export configuration
if self.config is not None:
self.load_common_conf()
def _log_result_decorator(fct):
"""Log (DEBUG) the result of the function fct."""
@ -71,6 +77,24 @@ class GlancesExport:
"""Close the export module."""
logger.debug(f"Finalise export interface {self.export_name}")
def load_common_conf(self):
"""Load the common export configuration in the Glances configuration file.
:returns: Boolean -- True if section is found
"""
# Read the common [export] section
section = "export"
opt = "exclude_fields"
try:
setattr(self, opt, self.config.get_list_value(section, opt))
except NoOptionError:
logger.debug(f"{opt} option not found in the {section} configuration section")
logger.debug(f"Load common {section} from the Glances configuration file")
return True
def load_conf(self, section, mandatories=["host", "port"], options=None):
"""Load the export <section> configuration in the Glances configuration file.
@ -101,7 +125,7 @@ class GlancesExport:
try:
setattr(self, opt, self.config.get_value(section, opt))
except NoOptionError:
pass
logger.debug(f"{opt} option not found in the {section} configuration section")
logger.debug(f"Load {section} from the Glances configuration file")
logger.debug(f"{section} parameters: { ({opt: getattr(self, opt) for opt in mandatories + options}) }")
@ -199,6 +223,10 @@ class GlancesExport:
ret.append({"measurement": name, "tags": tags, "fields": fields})
return ret
def is_excluded(self, field):
"""Return true if the field is excluded."""
return hasattr(self, 'exclude_fields') and any(re.fullmatch(i, field, re.I) for i in self.exclude_fields)
def plugins_to_export(self, stats):
"""Return the list of plugins to export.
@ -285,6 +313,8 @@ class GlancesExport:
export_values += item_values
else:
# We are on a simple value
if self.is_excluded(pre_key + key.lower()):
continue
export_names.append(pre_key + key.lower())
export_values.append(value)
elif isinstance(stats, list):

View File

@ -17,15 +17,7 @@ import re
from glances.actions import GlancesActions
from glances.events_list import glances_events
from glances.globals import (
dictlist,
dictlist_json_dumps,
json_dumps,
list_to_dict,
listkeys,
mean,
nativestr,
)
from glances.globals import dictlist, dictlist_json_dumps, json_dumps, list_to_dict, listkeys, mean, nativestr
from glances.history import GlancesHistory
from glances.logger import logger
from glances.outputs.glances_unicode import unicode_message