~junaidali/charms/trusty/plumgrid-director/pg-restart

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/contrib/benchmark/__init__.py

  • Committer: bbaqar at plumgrid
  • Date: 2015-07-29 18:07:31 UTC
  • Revision ID: bbaqar@plumgrid.com-20150729180731-ioynar8x3u5pxytc
Addressed reviews by Charmers

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2014-2015 Canonical Limited.
 
2
#
 
3
# This file is part of charm-helpers.
 
4
#
 
5
# charm-helpers is free software: you can redistribute it and/or modify
 
6
# it under the terms of the GNU Lesser General Public License version 3 as
 
7
# published by the Free Software Foundation.
 
8
#
 
9
# charm-helpers is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU Lesser General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU Lesser General Public License
 
15
# along with charm-helpers.  If not, see <http://www.gnu.org/licenses/>.
 
16
 
 
17
import subprocess
 
18
import time
 
19
import os
 
20
from distutils.spawn import find_executable
 
21
 
 
22
from charmhelpers.core.hookenv import (
 
23
    in_relation_hook,
 
24
    relation_ids,
 
25
    relation_set,
 
26
    relation_get,
 
27
)
 
28
 
 
29
 
 
30
def action_set(key, val):
 
31
    if find_executable('action-set'):
 
32
        action_cmd = ['action-set']
 
33
 
 
34
        if isinstance(val, dict):
 
35
            for k, v in iter(val.items()):
 
36
                action_set('%s.%s' % (key, k), v)
 
37
            return True
 
38
 
 
39
        action_cmd.append('%s=%s' % (key, val))
 
40
        subprocess.check_call(action_cmd)
 
41
        return True
 
42
    return False
 
43
 
 
44
 
 
45
class Benchmark():
 
46
    """
 
47
    Helper class for the `benchmark` interface.
 
48
 
 
49
    :param list actions: Define the actions that are also benchmarks
 
50
 
 
51
    From inside the benchmark-relation-changed hook, you would
 
52
    Benchmark(['memory', 'cpu', 'disk', 'smoke', 'custom'])
 
53
 
 
54
    Examples:
 
55
 
 
56
        siege = Benchmark(['siege'])
 
57
        siege.start()
 
58
        [... run siege ...]
 
59
        # The higher the score, the better the benchmark
 
60
        siege.set_composite_score(16.70, 'trans/sec', 'desc')
 
61
        siege.finish()
 
62
 
 
63
 
 
64
    """
 
65
 
 
66
    BENCHMARK_CONF = '/etc/benchmark.conf'  # Replaced in testing
 
67
 
 
68
    required_keys = [
 
69
        'hostname',
 
70
        'port',
 
71
        'graphite_port',
 
72
        'graphite_endpoint',
 
73
        'api_port'
 
74
    ]
 
75
 
 
76
    def __init__(self, benchmarks=None):
 
77
        if in_relation_hook():
 
78
            if benchmarks is not None:
 
79
                for rid in sorted(relation_ids('benchmark')):
 
80
                    relation_set(relation_id=rid, relation_settings={
 
81
                        'benchmarks': ",".join(benchmarks)
 
82
                    })
 
83
 
 
84
            # Check the relation data
 
85
            config = {}
 
86
            for key in self.required_keys:
 
87
                val = relation_get(key)
 
88
                if val is not None:
 
89
                    config[key] = val
 
90
                else:
 
91
                    # We don't have all of the required keys
 
92
                    config = {}
 
93
                    break
 
94
 
 
95
            if len(config):
 
96
                with open(self.BENCHMARK_CONF, 'w') as f:
 
97
                    for key, val in iter(config.items()):
 
98
                        f.write("%s=%s\n" % (key, val))
 
99
 
 
100
    @staticmethod
 
101
    def start():
 
102
        action_set('meta.start', time.strftime('%Y-%m-%dT%H:%M:%SZ'))
 
103
 
 
104
        """
 
105
        If the collectd charm is also installed, tell it to send a snapshot
 
106
        of the current profile data.
 
107
        """
 
108
        COLLECT_PROFILE_DATA = '/usr/local/bin/collect-profile-data'
 
109
        if os.path.exists(COLLECT_PROFILE_DATA):
 
110
            subprocess.check_output([COLLECT_PROFILE_DATA])
 
111
 
 
112
    @staticmethod
 
113
    def finish():
 
114
        action_set('meta.stop', time.strftime('%Y-%m-%dT%H:%M:%SZ'))
 
115
 
 
116
    @staticmethod
 
117
    def set_composite_score(value, units, direction='asc'):
 
118
        """
 
119
        Set the composite score for a benchmark run. This is a single number
 
120
        representative of the benchmark results. This could be the most
 
121
        important metric, or an amalgamation of metric scores.
 
122
        """
 
123
        return action_set(
 
124
            "meta.composite",
 
125
            {'value': value, 'units': units, 'direction': direction}
 
126
        )