@cryptotaxi247 / netdata-1 / commits / 3362c4e40

python.d: logger: remove timestamp when logging to journald. (#16516)

rm limited logger and logging time when logging to journal

Ilya Mashchenko committed Nov 30, 2023 at 22:15 UTC 3362c4e405c6a170b88c1e2040690278f4cfe58a
3 files changed +84 -103
collectors/python.d.plugin/python.d.plugin.in
+2 -1
@@ -225,7 +225,8 @@ class ModuleConfig:
225 self.is_stock = False
226
227 def load(self, abs_path):
228 - self.is_stock = abs_path.startswith(DIRS.modules_stock_config)
228 + if not IS_ATTY:
229 + self.is_stock = abs_path.startswith(DIRS.modules_stock_config)
230 self.config.update(load_config(abs_path) or dict())
231
232 def defaults(self):
collectors/python.d.plugin/python_modules/bases/FrameworkServices/SimpleService.py
+3 -3
@@ -8,7 +8,7 @@ import os
8
9 from bases.charts import Charts, ChartError, create_runtime_chart
10 from bases.collection import safe_print
11 -from bases.loggers import PythonDLimitedLogger
11 +from bases.loggers import PythonDLogger
12 from third_party.monotonic import monotonic
13 from time import sleep, time
14
@@ -62,7 +62,7 @@ def clean_module_name(name):
62 return name
63
64
65 -class SimpleService(PythonDLimitedLogger, object):
65 +class SimpleService(PythonDLogger, object):
66 """
67 Prototype of Service class.
68 Implemented basic functionality to run jobs by `python.d.plugin`
@@ -73,7 +73,7 @@ class SimpleService(PythonDLimitedLogger, object):
73 :param configuration: <dict>
74 :param name: <str>
75 """
76 - PythonDLimitedLogger.__init__(self)
76 + PythonDLogger.__init__(self)
77 self.configuration = configuration
78 self.order = list()
79 self.definitions = dict()
collectors/python.d.plugin/python_modules/bases/loggers.py
+79 -99
@@ -4,6 +4,8 @@
4 # SPDX-License-Identifier: GPL-3.0-or-later
5
6 import logging
7 +import os
8 +import stat
9 import traceback
10
11 from sys import exc_info
@@ -15,39 +17,46 @@ except ImportError:
17
18 from bases.collection import on_try_except_finally, unicode_str
19
18 -LOGGING_LEVELS = {'CRITICAL': 50,
19 - 'ERROR': 40,
20 - 'WARNING': 30,
21 - 'INFO': 20,
22 - 'DEBUG': 10,
23 - 'NOTSET': 0}
20 +LOGGING_LEVELS = {
21 + 'CRITICAL': 50,
22 + 'ERROR': 40,
23 + 'WARNING': 30,
24 + 'INFO': 20,
25 + 'DEBUG': 10,
26 + 'NOTSET': 0,
27 +}
28
25 -DEFAULT_LOG_LINE_FORMAT = '%(asctime)s: %(name)s %(levelname)s : %(message)s'
26 -DEFAULT_LOG_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
29
28 -PYTHON_D_LOG_LINE_FORMAT = '%(asctime)s: %(name)s %(levelname)s: %(module_name)s[%(job_name)s] : %(message)s'
29 -PYTHON_D_LOG_NAME = 'python.d'
30 +def is_stderr_connected_to_journal():
31 + journal_stream = os.environ.get("JOURNAL_STREAM")
32 + if not journal_stream:
33 + return False
34
35 + colon_index = journal_stream.find(":")
36 + if colon_index <= 0:
37 + return False
38
32 -def limiter(log_max_count=30, allowed_in_seconds=60):
33 - def on_decorator(func):
39 + device, inode = journal_stream[:colon_index], journal_stream[colon_index + 1:]
40
35 - def on_call(*args):
36 - current_time = args[0]._runtime_counters.start_mono
37 - lc = args[0]._logger_counters
41 + try:
42 + device_number, inode_number = os.fstat(2)[stat.ST_DEV], os.fstat(2)[stat.ST_INO]
43 + except OSError:
44 + return False
45
39 - if lc.logged and lc.logged % log_max_count == 0:
40 - if current_time - lc.time_to_compare <= allowed_in_seconds:
41 - lc.dropped += 1
42 - return
43 - lc.time_to_compare = current_time
46 + return str(device_number) == device and str(inode_number) == inode
47
45 - lc.logged += 1
46 - func(*args)
48
48 - return on_call
49 +is_journal = is_stderr_connected_to_journal()
50 +
51 +DEFAULT_LOG_LINE_FORMAT = '%(asctime)s: %(name)s %(levelname)s : %(message)s'
52 +PYTHON_D_LOG_LINE_FORMAT = '%(asctime)s: %(name)s %(levelname)s: %(module_name)s[%(job_name)s] : %(message)s'
53 +
54 +if is_journal:
55 + DEFAULT_LOG_LINE_FORMAT = '%(name)s %(levelname)s : %(message)s'
56 + PYTHON_D_LOG_LINE_FORMAT = '%(name)s %(levelname)s: %(module_name)s[%(job_name)s] : %(message)s '
57
50 - return on_decorator
58 +DEFAULT_LOG_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
59 +PYTHON_D_LOG_NAME = 'python.d'
60
61
62 def add_traceback(func):
@@ -66,26 +75,14 @@ def add_traceback(func):
75 return on_call
76
77
69 -class LoggerCounters:
70 - def __init__(self):
71 - self.logged = 0
72 - self.dropped = 0
73 - self.time_to_compare = time()
74 -
75 - def __repr__(self):
76 - return 'LoggerCounter(logged: {logged}, dropped: {dropped})'.format(logged=self.logged,
77 - dropped=self.dropped)
78 -
79 -
78 class BaseLogger(object):
81 - def __init__(self, logger_name, log_fmt=DEFAULT_LOG_LINE_FORMAT, date_fmt=DEFAULT_LOG_TIME_FORMAT,
82 - handler=logging.StreamHandler):
83 - """
84 - :param logger_name: <str>
85 - :param log_fmt: <str>
86 - :param date_fmt: <str>
87 - :param handler: <logging handler>
88 - """
79 + def __init__(
80 + self,
81 + logger_name,
82 + log_fmt=DEFAULT_LOG_LINE_FORMAT,
83 + date_fmt=DEFAULT_LOG_TIME_FORMAT,
84 + handler=logging.StreamHandler,
85 + ):
86 self.logger = logging.getLogger(logger_name)
87 self._muted = False
88 if not self.has_handlers():
@@ -97,11 +94,6 @@ class BaseLogger(object):
94 return '<Logger: {name})>'.format(name=self.logger.name)
95
96 def set_formatter(self, fmt, date_fmt=DEFAULT_LOG_TIME_FORMAT):
100 - """
101 - :param fmt: <str>
102 - :param date_fmt: <str>
103 - :return:
104 - """
97 if self.has_handlers():
98 self.logger.handlers[0].setFormatter(logging.Formatter(fmt=fmt, datefmt=date_fmt))
99
@@ -114,36 +106,31 @@ class BaseLogger(object):
106
107 @severity.setter
108 def severity(self, level):
117 - """
118 - :param level: <str> or <int>
119 - :return:
120 - """
109 if level in LOGGING_LEVELS:
110 self.logger.setLevel(LOGGING_LEVELS[level])
111
124 - def debug(self, *msg, **kwargs):
112 + def _log(self, level, *msg, **kwargs):
113 if not self._muted:
126 - self.logger.debug(' '.join(map(unicode_str, msg)), **kwargs)
114 + self.logger.log(level, ' '.join(map(unicode_str, msg)), **kwargs)
115 +
116 + def debug(self, *msg, **kwargs):
117 + self._log(logging.DEBUG, *msg, **kwargs)
118
119 def info(self, *msg, **kwargs):
129 - if not self._muted:
130 - self.logger.info(' '.join(map(unicode_str, msg)), **kwargs)
120 + self._log(logging.INFO, *msg, **kwargs)
121
122 def warning(self, *msg, **kwargs):
133 - if not self._muted:
134 - self.logger.warning(' '.join(map(unicode_str, msg)), **kwargs)
123 + self._log(logging.WARN, *msg, **kwargs)
124
125 def error(self, *msg, **kwargs):
137 - if not self._muted:
138 - self.logger.error(' '.join(map(unicode_str, msg)), **kwargs)
126 + self._log(logging.ERROR, *msg, **kwargs)
127
128 def alert(self, *msg, **kwargs):
141 - if not self._muted:
142 - self.logger.critical(' '.join(map(unicode_str, msg)), **kwargs)
129 + self._log(logging.CRITICAL, *msg, **kwargs)
130
131 @on_try_except_finally(on_finally=(exit, 1))
132 def fatal(self, *msg, **kwargs):
146 - self.logger.critical(' '.join(map(unicode_str, msg)), **kwargs)
133 + self._log(logging.CRITICAL, *msg, **kwargs)
134
135 def mute(self):
136 self._muted = True
@@ -153,15 +140,14 @@ class BaseLogger(object):
140
141
142 class PythonDLogger(object):
156 - def __init__(self, logger_name=PYTHON_D_LOG_NAME, log_fmt=PYTHON_D_LOG_LINE_FORMAT):
157 - """
158 - :param logger_name: <str>
159 - :param log_fmt: <str>
160 - """
143 + def __init__(
144 + self,
145 + logger_name=PYTHON_D_LOG_NAME,
146 + log_fmt=PYTHON_D_LOG_LINE_FORMAT,
147 + ):
148 self.logger = BaseLogger(logger_name, log_fmt=log_fmt)
149 self.module_name = 'plugin'
150 self.job_name = 'main'
164 - self._logger_counters = LoggerCounters()
151
152 _LOG_TRACEBACK = False
153
@@ -174,45 +160,39 @@ class PythonDLogger(object):
160 PythonDLogger._LOG_TRACEBACK = value
161
162 def debug(self, *msg):
177 - self.logger.debug(*msg, extra={'module_name': self.module_name,
178 - 'job_name': self.job_name or self.module_name})
163 + self.logger.debug(*msg, extra={
164 + 'module_name': self.module_name,
165 + 'job_name': self.job_name or self.module_name,
166 + })
167
168 def info(self, *msg):
181 - self.logger.info(*msg, extra={'module_name': self.module_name,
182 - 'job_name': self.job_name or self.module_name})
169 + self.logger.info(*msg, extra={
170 + 'module_name': self.module_name,
171 + 'job_name': self.job_name or self.module_name,
172 + })
173
174 def warning(self, *msg):
185 - self.logger.warning(*msg, extra={'module_name': self.module_name,
186 - 'job_name': self.job_name or self.module_name})
175 + self.logger.warning(*msg, extra={
176 + 'module_name': self.module_name,
177 + 'job_name': self.job_name or self.module_name,
178 + })
179
180 @add_traceback
181 def error(self, *msg):
190 - self.logger.error(*msg, extra={'module_name': self.module_name,
191 - 'job_name': self.job_name or self.module_name})
182 + self.logger.error(*msg, extra={
183 + 'module_name': self.module_name,
184 + 'job_name': self.job_name or self.module_name,
185 + })
186
187 @add_traceback
188 def alert(self, *msg):
195 - self.logger.alert(*msg, extra={'module_name': self.module_name,
196 - 'job_name': self.job_name or self.module_name})
189 + self.logger.alert(*msg, extra={
190 + 'module_name': self.module_name,
191 + 'job_name': self.job_name or self.module_name,
192 + })
193
194 def fatal(self, *msg):
199 - self.logger.fatal(*msg, extra={'module_name': self.module_name,
200 - 'job_name': self.job_name or self.module_name})
201 -
202 -
203 -class PythonDLimitedLogger(PythonDLogger):
204 - @limiter()
205 - def info(self, *msg):
206 - PythonDLogger.info(self, *msg)
207 -
208 - @limiter()
209 - def warning(self, *msg):
210 - PythonDLogger.warning(self, *msg)
211 -
212 - @limiter()
213 - def error(self, *msg):
214 - PythonDLogger.error(self, *msg)
215 -
216 - @limiter()
217 - def alert(self, *msg):
218 - PythonDLogger.alert(self, *msg)
195 + self.logger.fatal(*msg, extra={
196 + 'module_name': self.module_name,
197 + 'job_name': self.job_name or self.module_name,
198 + })