/
githubmirror
/
rsyslog
Обзор
Документация
Войти
/
githubmirror
/
rsyslog
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
plugins/impstats/statslog-graph.py
287 строк
11 KB
Rainer Gerhards
python: clean up style and add optional checks
22 май 2026, 12:02
22 май 2026, 12:02
44a8a00
Код
Авторство
О чём код?
#! /usr/bin/env python # -*- coding: utf-8 -*- # * Copyright (C) 2013-2018 Adiscon GmbH. # * This file is part of RSyslog # * # * This script processes csv stats logfiles created by statslog-splitter.py and creates graphs # * Dependecies: - python pip -> Needed to install python packages # * - python cairosvg -> Needed for PNG converting support! # * - Install python packages using this command: # * pip install CairoSVG tinycss cssselect pygal # * import sys import datetime import time # import os import pygal # Set default variables szInput = "" szOutputFile = "" szChartName = "" szCounters = "" bHelpOutput = False nMaxDataCount = 25 bUseDateTime = True bLineChart = True bBarChart = False bConvertPng = False bLogarithmicChart = False bFilledLineChart = False bChartCalcDelta = False bDeltaIgnoreFirstValue = False bDeltaIgnoreNegativeValues = False # Init variables aFields = [] aData = {} aMajorXData = [] aCounters = None errorlog = None def writeErrorLog(message): errorlog.write(message) # Helper variables nDataRecordCound = 0 nLineCount = 0 iStartSeconds = 0 # Process Arguments for arg in sys.argv: # [-4:]: if arg.find("--input=") != -1: szInput = arg[8:] elif arg.find("--outputfile=") != -1: szOutputFile = arg[13:] elif arg.find("--maxdataxlabel=") != -1: nMaxDataCount = int(arg[16:]) elif arg.find("--xlabeldatetime") != -1: bUseDateTime = True elif arg.find("--xlabelseconds") != -1: bUseDateTime = False elif arg.find("--convertpng") != -1: bConvertPng = True elif arg.find("--deltaignorefirstvalue") != -1: bDeltaIgnoreFirstValue = True elif arg.find("--deltaignorenegativevalues") != -1: bDeltaIgnoreNegativeValues = True elif arg.find("--linechart") != -1: bLineChart = True bBarChart = False elif arg.find("--barchart") != -1: bLineChart = False bBarChart = True elif arg.find("--logarithmic") != -1: bLogarithmicChart = True elif arg.find("--filledlinechart") != -1: bFilledLineChart = True elif arg.find("--chartscalcdelta") != -1: bChartCalcDelta = True elif arg.find("--counters=") != -1: szCounters = arg[11:] elif arg.find("--h") != -1 or arg.find("-h") != -1 or arg.find("--help") != -1: bHelpOutput = True if bHelpOutput: print "\n\nStatslog-graph command line options:" print "=======================================" print " --input=<filename> Contains the path and filename of your impstats logfile. " print " Default is 'rsyslog-stats.log' \n" print " --outputfile=<dir> Output directory and file to be used. " print " Default is '" + szOutputFile + "'. " print " --maxdataxlabel=<num> Max Number of data shown on the x-label." print " Default is 25 label entries." print " --xlabeldatetime Use Readable Datetime for x label data. (Cannot be used with --xlabelseconds)" print " Default is enabled." print " --xlabelseconds Use seconds instead of datetime, starting at 0. (Cannot be used with --xlabeldatetime)" print " Default is disabled." print " --linechart Generates a Linechart (Default chart mode) (Cannot be used with --barchart)" print " --barchart Generates a Barchart (Cannot be used with --linechart)" print " --logarithmic Uses Logarithmic to scale the Y Axis, maybe useful in some cases. Default is OFF" print " --filledlinechart Use filled lines on Linechart, maybe useful in some cases. Default is OFF" print " --chartscalcdelta If set, charts will use calculated delta values instead of cumulative values." print " --convertpng Generate PNG Output rather than SVG. " print " Default is SVG output." print " --h / -h / --help Displays this help message. \n" print "\n Sampleline: ./statslog-graph.py --input=imuxsock.csv --outputfile=/home/user/csvgraphs/imuxsock.svg" else: # Generate output filename if len(szInput) > 0: # Only set output filename if not specified if len(szOutputFile) == 0: if szInput.rfind(".") == -1: szOutputFile += szInput + ".svg" else: szOutputFile += szInput[:-4] + ".svg" else: print "Error, no input file specified!" sys.exit(0) # Generate Counters Array if necessary if len(szCounters) > 0: aCounters = szCounters.strip().split(";") # Open Errorlog on init szErrorLog = szOutputFile + ".corrupted.log" errorlog = open(szErrorLog, 'w') # Process inputfile try: with open(szInput) as inputfile: aLineDataPrev = [] # Helper variable for previous line! for line in inputfile: if nLineCount == 0: aFields = line.strip().split(";") # remove last item if empty if len(aFields[len(aFields)-1]) == 0: aFields.pop() # print aFields # sys.exit(0) # Init data arrays for field in aFields: aData[field] = [] else: aLineData = line.strip().split(";") # remove last item if empty if len(aLineData[len(aLineData)-1]) == 0: aLineData.pop() # Loop Through line data iFieldNum = 0 for field in aFields: if iFieldNum == 0: if bUseDateTime: aData[field].append(datetime.datetime.strptime( aLineData[iFieldNum], "%Y/%b/%d %H:%M:%S")) else: # Convert Time String into UNIX Timestamp myDateTime = datetime.datetime.strptime(aLineData[iFieldNum], "%Y/%b/%d %H:%M:%S") iTimeStamp = int(time.mktime(myDateTime.timetuple())) # Init Start Seconds if iStartSeconds == 0: iStartSeconds = iTimeStamp # Set data field aData[field].append(iTimeStamp - iStartSeconds) elif iFieldNum == 2 and szChartName == "": szChartName = aLineData[iFieldNum] elif iFieldNum > 2: # Check if we need to calculate Deltas! # Do not calc delta für SIZE! if bChartCalcDelta and len(aLineDataPrev) > 0 and field.find("size") == -1: try: iPreviousVal = int(aLineDataPrev[iFieldNum]) iCurrentVal = int(aLineData[iFieldNum]) if iCurrentVal != 0: # Calc DELTA iCurrentDelta = iCurrentVal - iPreviousVal if bDeltaIgnoreNegativeValues: if iCurrentDelta >= 0: aData[field].append(iCurrentDelta) else: aData[field].append(0) else: aData[field].append(iCurrentDelta) else: # Don't Calc delta value! aData[field].append(iCurrentVal) except ValueError: writeErrorLog("Error, Field not an INTEGER: " + aLineData[iFieldNum]) else: try: # Try as INTEGER aData[field].append(int(aLineData[iFieldNum])) except ValueError: # Not an INTEGER, skip value writeErrorLog("Error, Field not an INTEGER: " + aLineData[iFieldNum]) else: aData[field].append(aLineData[iFieldNum]) iFieldNum += 1 # print aData[field[nLineCount]] # Increment counter nDataRecordCound += 1 # in case deltas need to be calculated, Store current line into previous line if bChartCalcDelta: aLineDataPrev = aLineData # Increment counter nLineCount += 1 finally: if errorlog is not None: errorlog.close() # Import Style # from pygal.style import LightSolarizedStyle # from pygal.style import DefaultStyle from pygal.style import RotateStyle # Create Config object from pygal import Config chartCfg = Config() chartCfg.show_legend = True chartCfg.human_readable = True chartCfg.pretty_print = True if bFilledLineChart: chartCfg.fill = True else: chartCfg.fill = False chartCfg.x_scale = 1 chartCfg.y_scale = 1 chartCfg.x_label_rotation = 45 chartCfg.include_x_axis = True chartCfg.show_dots = False if nMaxDataCount > 0: chartCfg.show_minor_x_labels = False chartCfg.x_labels_major_count = nMaxDataCount # chartCfg.style = DefaultStyle #LightSolarizedStyle chartCfg.style = RotateStyle('#FF0000') chartCfg.print_values = True # False chartCfg.print_zeroes = True chartCfg.no_data_text = "All values are 0" if bLogarithmicChart: chartCfg.logarithmic = True # Makes chart Y-Axis data more readable # remove first item if configured! if bDeltaIgnoreFirstValue: for iChartNum in range(3, len(aFields)): if aCounters is None or aFields[iChartNum] in aCounters: aData[aFields[iChartNum]].pop(0) # Create Linechart if bLineChart: myChart = pygal.Line(chartCfg) myChart.title = 'Line Chart of "' + szChartName + '"' myChart.x_title = "Time elasped in seconds" myChart.x_labels = map(str, aData[aFields[0]]) # myChart.x_labels_major = map(str, aMajorXData ) for iChartNum in range(3, len(aFields)): if aCounters is None or aFields[iChartNum] in aCounters: myChart.add(aFields[iChartNum], aData[aFields[iChartNum]]) # Add some values # Create BarChart elif bBarChart: myChart = pygal.Bar(chartCfg) myChart.title = 'Bar Chart of "' + szChartName + '"' myChart.x_title = "Time elasped in seconds" myChart.x_labels = map(str, aData[aFields[0]]) # myChart.x_labels_major = map(str, aMajorXData ) for iChartNum in range(3, len(aFields)): if aCounters is None or aFields[iChartNum] in aCounters: myChart.add(aFields[iChartNum], aData[aFields[iChartNum]]) # Add some values # for iChartNum in range(3, len(aFields) ): # myChart.add(aFields[iChartNum], aData[ aFields[iChartNum] ]) # Add some values # Render Chart now and output to file! if bConvertPng: szPngFileName = szOutputFile[:-4] + ".png" myChart.render_to_png(szPngFileName) else: myChart.render_to_file(szOutputFile) # Finished sys.exit(0)