f93dc1a4bf81d2e788e5fc8876debbca867b3fcc
[plstackapi.git] / planetstack / openstack_observer / ceilometer.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 from ceilometerclient import client
5 from os import environ as env
6 import keystoneclient.v2_0.client as ksclient
7 import re
8 import datetime
9 import time
10 from monitor.monitordriver import *
11 from core.models import *
12
13 def object_to_filter(model_name, pk):
14         filter_dict = {
15                 'Slice':[Slice, 'tenant_id', 'project_id'],
16                 'Sliver':[Sliver, 'instance_id', 'resource_id'],
17                 'Site':[Site, 'tenant_id', 'project_id']
18         }
19         
20         mod,field,tag = filter_dict[model_name]
21         obj = mod.objects.get(pk=pk)
22         return '%s=%s'%(tag,mod[field])
23         
24
25 def cli_to_array(cli_query):
26     '''This converts from the cli list of queries to what is required
27     by the python api.
28     so from:
29     "this<=34;that=foo"
30     to
31     "[{field=this,op=le,value=34},{field=that,op=eq,value=foo}]"
32     '''
33     if cli_query is None:
34         return None
35
36     op_lookup = {'!=': 'ne',
37                  '>=': 'ge',
38                  '<=': 'le',
39                  '>': 'gt',
40                  '<': 'lt',
41                  '=': 'eq'}
42
43     def split_by_op(string):
44         # two character split (<=,!=)
45         frags = re.findall(r'([[a-zA-Z0-9_.]+)([><!]=)([^ -,\t\n\r\f\v]+)',
46                            string)
47         if len(frags) == 0:
48             #single char split (<,=)
49             frags = re.findall(r'([a-zA-Z0-9_.]+)([><=])([^ -,\t\n\r\f\v]+)',
50                                string)
51         return frags
52
53     opts = []
54     queries = cli_query.split(';')
55     for q in queries:
56         frag = split_by_op(q)
57         if len(frag) > 1:
58             raise ValueError('incorrect seperator %s in query "%s"' %
59                              ('(should be ";")', q))
60         if len(frag) == 0:
61             raise ValueError('invalid query %s' % q)
62         query = frag[0]
63         opt = {}
64         opt['field'] = query[0]
65         opt['op'] = op_lookup[query[1]]
66         opt['value'] = query[2]
67         opts.append(opt)
68     return opts
69
70 def meters_to_stats(meters):
71     stats = DashboardStatistics()
72     for m in meters:
73         timestamp = datetime.datetime.strptime(m.duration_start,'%Y-%m-%dT%H:%M:%S')
74         stats.stat_list.append({'timestamp':timestamp, 'value':m.sum})
75         stats.sum+=m.sum
76         stats.average+=m.sum
77         stats.unit = 'ns'
78
79     stats.average/=len(meters)
80     return stats
81         
82                 
83
84 class CeilometerDriver(MonitorDriver):
85     def get_meter(self, meter, obj, pk, keystone=None):
86         if (not keystone):
87             keystone = {}
88             keystone['username']=env['OS_USERNAME']
89             keystone['password']=env['OS_PASSWORD']
90             keystone['auth_url']=env['OS_AUTH_URL']
91             keystone['tenant_name']=env['OS_TENANT_NAME']
92             keystone['os_cacert']=env['OS_CACERT']
93
94         ceilometer_client = client._get_ksclient(**keystone)
95         token = ceilometer_client.auth_token
96
97         ceilo_endpoint = client._get_endpoint(ceilometer_client, **keystone)
98         #ceilometer = client.get_client(2, username=keystone['username'], password=keystone['password'], tenant_name=keystone['tenant_name'], auth_url=keystone['auth_url'])
99
100         ceilometer = client.Client('2',endpoint = ceilo_endpoint, token = lambda: token)
101
102         cur_ts = datetime.datetime.fromtimestamp(time.time()-86400)
103         str_ts = cur_ts.strftime('%Y-%m-%dT%H:%M:%S')
104         
105                 object_filter = object_to_filter(obj, pk)
106         filter=';'.join([object_filter,'timestamp>%s'%str_ts])
107         #query = cli_to_array("project_id=124de34266b24f57957345cdb43cc9ff;timestamp>2014-12-11T00:00:00")
108         query = cli_to_array(filter)
109
110         meters = ceilometer.statistics.list(meter,q=query,period=3600)
111
112         stats = meters_to_stats(meters)
113         return stats
114