~vcs-imports/bts-lin/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/python
# vim:set encoding=utf-8:
###############################################################################
# Generate historical graphs from data stored in RRD
#
# Docs used:
# http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html
# http://oss.oetiker.ch/rrdtool/doc/rrdgraph_data.en.html
# http://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html
# http://oss.oetiker.ch/rrdtool/tut/rrdtutorial.en.html#ITime_to_create_some_graphics
###############################################################################
# Copyright:
#   © 2015 Sandro Tosi <morph@debian.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The names of its contributors may not be used to endorse or promote
#    products derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
# EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
###############################################################################

import rrdtool
import os.path
import os
import itertools

history = ['3 months', '6 months',
           '1 year', '5 years', '10 years',
          ]

tags = {
        'A': 'actions to perform',
        'C': 'checks successfully done',
        'D': 'bugs done',
        'E': 'errors',
        'I': 'no status',
        'M': 'mails sent',
        'N': 'not a bts/ignored',
        'S': 'SMTP errors (sending mails)',
        'T': 'total bugs count',
        'U': 'unmatched/unconfigured bts',
        'X': 'bugs not existing',
}
tags['elapsed_time'] = 'Elapsed time'

overview = ['A', 'C', 'E', 'T', 'U', 'elapsed_time']
colors = dict(zip(overview,
                  ['00CC00', '009900', 'CC0000', '0066CC', 'FF9900', 'CCCC00']
             ))
max_ov_tag_length = max(len(tags[x]) for x in overview)

basedir = os.path.dirname(os.path.abspath(__file__))
imgdir = os.path.join(basedir, '../htdocs/img')
rrdfile = os.path.join(basedir, 'bts-link.rrd')

for ds in sorted(tags.keys()):
    for start in history:
        outfile = os.path.join(imgdir, ds + '_' + start.replace(' ', '') + '.png')
        rrdtool.graph(outfile,
            "--start", "-%s" % start,
            "--width", "600",
            "--height", "250",
            '--title', '%s in the last %s' % (tags[ds], start),
            "DEF:%s=%s:%s:LAST" % (ds, rrdfile, ds),
            "LINE:%s#0000FF" % ds,
        )

outfile = os.path.join(imgdir, 'overview' + '.png' )
rrdtool.graph(outfile,
              "--start", "-1 year",
              "--width", "600",
              "--height", "250",
              "--logarithmic",
              '--title', 'bts-link last year executions overview',
              # graph() expect to receive the directives one-by-one as arguments, but
              # since we want to generate them dinamically, we need to force the expansions
              # of the list with *
              *(["DEF:%s=%s:%s:LAST" % (x, rrdfile, x) for x in overview]
              +
              # we can define alle the DEF at once, but LINE and GPRINT for each
              # datasource need to be one next to each other
              # since we generate a list of tuples, we unpack them using chain() which
              # returns a generator, so we list() it
              # we pad the Current string taking the max length of a tag in the overview
              # and then removing the current string length
              list(itertools.chain.from_iterable(
                  ('LINE:%s#%s:%s' % (x, colors[x], tags[x]),
                   'GPRINT:%s:LAST:%sCurrent\:%%8.2lf %%s' % (x, ' '*(max_ov_tag_length - len(tags[x]))), 'COMMENT:\\n') for x in overview
                  ))
              )
        )