import sys
import time
import threading
+from re import sub
# -----------------------------------------------------------------------------
# globals & environment setup
PROGRAM = os.path.basename(__file__).replace(".plugin", "")
DEBUG_FLAG = False
+TRACE_FLAG = False
OVERRIDE_UPDATE_EVERY = False
# -----------------------------------------------------------------------------
except ImportError:
msg.fatal('Cannot find yaml library')
+try:
+ from collections import OrderedDict
+ ORDERED = True
+ DICT = OrderedDict
+ msg.info('YAML output is ordered')
+except ImportError:
+ try:
+ from ordereddict import OrderedDict
+ ORDERED = True
+ DICT = OrderedDict
+ msg.info('YAML output is ordered')
+ except ImportError:
+ ORDERED = False
+ DICT = dict
+ msg.info('YAML output is unordered')
+if ORDERED:
+ def ordered_load(stream, Loader=yaml.Loader, object_pairs_hook=OrderedDict):
+ class OrderedLoader(Loader):
+ pass
+ def construct_mapping(loader, node):
+ loader.flatten_mapping(node)
+ return object_pairs_hook(loader.construct_pairs(node))
+ OrderedLoader.add_constructor(
+ yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
+ construct_mapping)
+ return yaml.load(stream, OrderedLoader)
class PythonCharts(object):
"""
# check if there are dict in config dict
many_jobs = False
for name in config:
- if type(config[name]) is dict:
+ if isinstance(config[name], DICT):
many_jobs = True
break
job = self.jobs[i]
try:
if not job.check():
- msg.error(job.chart_name, "check function failed.")
+ msg.error(job.chart_name, "check() failed - disabling job")
self._stop(job)
else:
msg.info("CHECKED OK:", job.chart_name)
i += 1
try:
if job.override_name is not None:
- new_name = job.__module__ + '_' + job.override_name
+ new_name = job.__module__ + '_' + sub(r'\s+', '_', job.override_name)
if new_name in overridden:
msg.info("DROPPED:", job.name, ", job '" + job.override_name + "' is already served by another job.")
self._stop(job)
"""
try:
with open(path, 'r') as stream:
- config = yaml.load(stream)
+ if ORDERED:
+ config = ordered_load(stream, yaml.SafeLoader)
+ else:
+ config = yaml.load(stream)
except (OSError, IOError):
msg.error(str(path), "is not a valid configuration file")
return None
:param commands: list of str
:return: dict
"""
- global DEBUG_FLAG
+ global DEBUG_FLAG, TRACE_FLAG
global OVERRIDE_UPDATE_EVERY
global BASE_CONFIG
elif cmd == "debug" or cmd == "all":
DEBUG_FLAG = True
# redirect stderr to stdout?
+ elif cmd == "trace" or cmd == "all":
+ TRACE_FLAG = True
elif os.path.isfile(directory + cmd + ".chart.py") or os.path.isfile(directory + cmd):
#DEBUG_FLAG = True
mods.append(cmd.replace(".chart.py", ""))
"""
Main program.
"""
- global DEBUG_FLAG, BASE_CONFIG
+ global DEBUG_FLAG, TRACE_FLAG, BASE_CONFIG
# read configuration file
- disabled = []
+ disabled = ['nginx_log', 'gunicorn_log']
configfile = CONFIG_DIR + "python.d.conf"
msg.PROGRAM = PROGRAM
msg.info("reading configuration file:", configfile)
msg.fatal('disabled in configuration file.\n')
except (KeyError, TypeError):
pass
+
try:
for param in BASE_CONFIG:
BASE_CONFIG[param] = conf[param]
except (KeyError, TypeError):
pass # use default update_every from NETDATA_UPDATE_EVERY
+
try:
DEBUG_FLAG = conf['debug']
except (KeyError, TypeError):
pass
+
+ try:
+ TRACE_FLAG = conf['trace']
+ except (KeyError, TypeError):
+ pass
+
try:
log_throttle = conf['logs_per_interval']
except (KeyError, TypeError):
pass
+
try:
log_interval = conf['log_interval']
except (KeyError, TypeError):
pass
+
for k, v in conf.items():
if k in ("update_every", "debug", "enabled"):
continue
# parse passed command line arguments
modules = parse_cmdline(MODULES_DIR, *sys.argv)
msg.DEBUG_FLAG = DEBUG_FLAG
+ msg.TRACE_FLAG = TRACE_FLAG
msg.LOG_THROTTLE = log_throttle
msg.LOG_INTERVAL = log_interval
msg.LOG_COUNTER = 0