Finsihed implementing chart gemerator script for impstats.

CSV Data generated by statslog-splitter is needed.
To run the chart script, the following packages need to be installed:
	- python pip
	- python cairosvg
With pip install these packages:
	- pip install CairoSVG tinycss cssselect pygal
This commit is contained in:
Andre Lorbach 2013-07-03 12:16:40 +02:00
parent fe88c0cd17
commit 1d22bd58d4
2 changed files with 151 additions and 41 deletions

View File

@ -5,25 +5,38 @@
# * This file is part of RSyslog
# *
# * This script processes csv stats logfiles created by statslog-splitter.py and creates graphs
# * Dependecies: - python pip
# * - pip install CairoSVG tinycss cssselect pygal
# * 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 = "output.svg"
nLineCount = 0
nHelpOutput = 0
nDataRecordCound = 0
szOutputFile = ""
bHelpOutput = False
nMaxDataCount = 25
bUseDateTime = True
bLineChart = True
bBarChart = False
bConvertPng = False
# Init variables
aFields = []
aData = {}
aMajorXData = []
# Helper variables
nDataRecordCound = 0
nLineCount = 0
iStartSeconds = 0
# Process Arguments
for arg in sys.argv[-4:]:
@ -31,19 +44,54 @@ for arg in sys.argv[-4:]:
szInput = arg[8:]
elif arg.find("--outputdir=") != -1:
szOutputFile = arg[12:]
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("--linechart") != -1:
bLineChart = True
bBarChart = False
elif arg.find("--barchart") != -1:
bLineChart = False
bBarChart = True
elif arg.find("--h") != -1 or arg.find("-h") != -1 or arg.find("--help") != -1:
nHelpOutput = 1
bHelpOutput = True
if nHelpOutput == 1:
if bHelpOutput == True:
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 " --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:
if szInput.rfind(".") == -1:
szOutputFile += szInput + ".svg"
else:
szOutputFile += szInput[:-4] + ".svg"
else:
print "Error, no input file specified!"
sys.exit(0)
# Process inputfile
inputfile = open(szInput, 'r')
for line in inputfile.readlines():
if nLineCount == 0:
@ -66,7 +114,21 @@ else:
# Loop Through line data
iFieldNum = 0
for field in aFields:
if iFieldNum > 2:
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:
aData[field].append( int(aLineData[iFieldNum]) )
else:
aData[field].append( aLineData[iFieldNum] )
@ -82,26 +144,68 @@ else:
# Increment counter
nLineCount += 1
# if nLineCount > 25:
# break
if nMaxDataCount > 0:
# Check if we need to reduce the data amount
nTotalDataCount = len( aData[aFields[0]] )
nDataStepCount = nTotalDataCount / (nMaxDataCount)
if nTotalDataCount > nMaxDataCount:
for iDataNum in reversed(range(0, nTotalDataCount)):
# Remove all entries who
if iDataNum % nDataStepCount == 0:
aMajorXData.append( aData[aFields[0]][iDataNum] )
# for field in aFields:
# aData[field].pop(iDataNum)
# print len(aMajorXData)
# sys.exit(0)
# Create Config object
from pygal import Config
chartCfg = Config()
chartCfg.show_legend = True
chartCfg.human_readable = True
chartCfg.pretty_print=True
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
chartCfg.show_minor_x_labels=False
#chartCfg.logarithmic=True # Makes chart more readable
# Barchart Test!
bar_chart = pygal.Bar()
bar_chart.title = 'CSV Chart of "' + szInput + '"'
bar_chart.x_labels = aData[ aFields[0] ]
bar_chart.add(aFields[3], aData[ aFields[3] ]) # Add some values
bar_chart.render_to_file(szOutputFile)
#Linechart
if bLineChart:
myChart = pygal.Line(chartCfg)
myChart.title = 'Line Chart of "' + szInput + '"'
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) ):
myChart.add(aFields[iChartNum], aData[ aFields[iChartNum] ]) # Add some values
elif bBarChart:
myChart = pygal.Bar(chartCfg)
myChart.title = 'Bar Chart of "' + szInput + '"'
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) ):
myChart.add(aFields[iChartNum], aData[ aFields[iChartNum] ]) # Add some values
# Render Chart now and output to file!
myChart.render_to_file(szOutputFile)
# Convert to PNG and remove SVG
if bConvertPng:
szPngFileName = szOutputFile[:-4] + ".png"
iReturn = os.system("cairosvg " + szOutputFile + " -f png -o " + szPngFileName)
print "File SVG converted to PNG: '" + szPngFileName + "', return value of cairosvg: " + str(iReturn)
os.remove(szOutputFile)
# Finished
sys.exit(0)
line_chart = pygal.Line()
line_chart.title = 'Browser usage evolution (in %)'
line_chart.x_labels = map(str, range(2002, 2013))
line_chart.add('Firefox', [None, None, 0, 16.6, 25, 31, 36.4, 45.5, 46.3, 42.8, 37.1])
line_chart.add('Chrome', [None, None, None, None, None, None, 0, 3.9, 10.8, 23.8, 35.3])
line_chart.add('IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6, 54.7, 44.8, 36.2, 26.6, 20.1])
line_chart.add('Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4, 8.9, 5.8, 6.7, 6.8, 7.5])
line_chart.render_to_file('bar_chart.svg')

View File

@ -15,8 +15,8 @@ import re
# Set default variables
szInput = "rsyslog-stats.log"
szOutputDir = "./"
nSingleObjectOutput = 1
nHelpOutput = 0
bSingleObjectOutput = True
bHelpOutput = True
nLogLineNum = 0
nLogFileCount = 0
@ -37,23 +37,29 @@ for arg in sys.argv[-4:]:
szInput = arg[8:]
elif arg.find("--outputdir=") != -1:
szOutputDir = arg[12:]
elif arg.find("--singlefile=") != -1:
bSingleObjectOutput = True
elif arg.find("--h") != -1 or arg.find("-h") != -1 or arg.find("--help") != -1:
nHelpOutput = 1
bHelpOutput = True
#sys.exit(0)
if nHelpOutput == 1:
if bHelpOutput == 1:
print "\n\nStatslog-splitter command line options:"
print "======================================="
print " --input=<filename> Contains the path and filename of your impstats logfile. "
print " Default is 'rsyslog-stats.log' \n"
print " --input=<filename> Contains the path and filename of your impstats logfile. "
print " Default is 'rsyslog-stats.log' \n"
print " --outputdir=<dir> Output directory to be used. "
print " Default is current directory. "
print " --h / -h / --help Displays this help message. \n"
print " singlefile Splits the stats logfile into single CSV Files"
print " (Default)"
print "\n Sampleline: ./statslog-splitter.py singlefile --input=rsyslog-stats.log --outputdir=/home/user/csvlogs/"
elif nSingleObjectOutput == 1:
print " Default is current directory. "
print " --h / -h / --help Displays this help message. \n"
print " --singlefile Splits the stats logfile into single CSV Files"
print " Default is enabled."
print " --enablecharts Generate Charts for each exported CSV File.
print " Default is disabled."
print " --chartsformat=<svg|png> Format which should be used for Charts.
print " Default is svg format
print "\n Sampleline: ./statslog-splitter.py singlefile --input=rsyslog-stats.log --outputdir=/home/user/csvlogs/ --enablecharts --chartsformat=png"
elif bSingleObjectOutput:
inputfile = open(szInput, 'r')
for line in inputfile.readlines():
if line.find("rsyslogd-pstats") != -1: