blob: 1fc28d2316af57ce2a56fe2da845a70376e48004 [file] [log] [blame]
Sergio Slobodrianf39aaf82017-02-28 16:10:16 -05001#!/usr/bin/env python
2
3from structlog import get_logger
4from twisted.internet.defer import DeferredList, inlineCallbacks
5import requests
6import sys
7#
8# This file contains the dashboard template information. It gets pulled into
9# the dashd module and used to createt he dashboards. The other option would
10# be to put each of these in an individual text file and read them in when the
11# dashd process starts. There isn't much advantage to doing so at this time.
12#
13# TODO: The creation of a template from Grafana is currently incomplete.
14
15log = get_logger()
16
17class DashTemplate(object):
18 def __init__(self, grafana_url):
19 self.grafana_url = grafana_url
20
21 self.rowSelector = '%port%' # Not currently used
22 self.rows = [
23 dict(
24 title = "%port% packet statistics"
25 )
26 ]
27 self.panels = [
28 dict(
29 title = "%port% Packet Receive Statistics",
30 rx_64 = \
31 ("alias(perSecond(voltha.%device%.%deviceId%.%port%.rx_64), "
32 "'64b pkts/sec')"
33 ),
34 rx_65_127 = \
35 ("alias(perSecond("
36 "voltha.%device%.%deviceId%.%port%.rx_65_127),"
37 " '65-127b pkts/sec')"
38 ),
39 rx_128_255 = \
40 ("alias(perSecond("
41 "voltha.%device%.%deviceId%.%port%.rx_128_255), "
42 "'128-255b pkts/sec')"
43 ),
44 rx_256_511 = \
45 ("alias(perSecond"
46 "(voltha.%device%.%deviceId%.%port%.rx_256_511), "
47 "'256-511b pkts/sec')"
48 ),
49 rx_512_1023 = \
50 ("alias(perSecond("
51 "voltha.%device%.%deviceId%.%port%.rx_512_1023), "
52 "'512-1023b pkts/sec')"
53 ),
54 rx_1024_1518 = \
55 ("alias(perSecond("
56 "voltha.%device%.%deviceId%.%port%.rx_1024_1518), "
57 "'1024-1518b pkts/sec')"
58 ),
59 rx_1519_9k = \
60 ("alias(perSecond("
61 "voltha.%device%.%deviceId%.%port%.rx_1519_9k), "
62 "'1519b-9kb pkts/sec')"
63 )
64 ),
65 dict(
66 title = "%port% Packet Send Statistics",
67 tx_64 = \
68 ("alias(perSecond(voltha.%device%.%deviceId%.%port%.tx_64), "
69 "'64b pkts/sec')"
70 ),
71 tx_65_127 = \
72 ("alias(perSecond("
73 "voltha.%device%.%deviceId%.%port%.tx_65_127), "
74 "'65-127b pkts/sec')"
75 ),
76 tx_128_255 = \
77 ("alias(perSecond("
78 "voltha.%device%.%deviceId%.%port%.tx_128_255), "
79 "'128-255b pkts/sec')"
80 ),
81 tx_256_511 = \
82 ("alias(perSecond("
83 "voltha.%device%.%deviceId%.%port%.tx_256_511), "
84 "'256-511b pkts/sec')"
85 ),
86 tx_512_1023 = \
87 ("alias(perSecond("
88 "voltha.%device%.%deviceId%.%port%.tx_512_1023), "
89 "'512-1023b pkts/sec')"
90 ),
91 tx_1024_1518 = \
92 ("alias(perSecond("
93 "voltha.%device%.%deviceId%.%port%.tx_1024_1518), "
94 "'1024-1518b pkts/sec')"
95 ),
96 tx_1519_9k = \
97 ("alias(perSecond("
98 "voltha.%device%.%deviceId%.%port%.tx_1519_9k), "
99 "'1519b-9kb pkts/sec')"
100 )
101 )
102 ]
103
104
105 self.dashRow = '''
106 {
107 "collapse": false,
108 "editable": true,
109 "height": "250px",
110 "title": "Row",
111 "panels": []
112 }
113 '''
114
115 self.dashTarget = '''
116 {
117 "refId": "",
118 "target": ""
119 }
120 '''
121
122 self.dashPanel = '''
123 {
124 "aliasColors": {},
125 "bars": false,
126 "datasource": "Voltha Stats",
127 "editable": true,
128 "error": false,
129 "fill": 0,
130 "grid": {
131 "threshold1": null,
132 "threshold1Color": "rgba(216, 200, 27, 0.27)",
133 "threshold2": null,
134 "threshold2Color": "rgba(234, 112, 112, 0.22)"
135 },
136 "id": 1,
137 "isNew": true,
138 "legend": {
139 "avg": false,
140 "current": false,
141 "max": false,
142 "min": false,
143 "show": true,
144 "total": false,
145 "values": false
146 },
147 "lines": true,
148 "linewidth": 1,
149 "links": [],
150 "nullPointMode": "connected",
151 "percentage": false,
152 "pointradius": 5,
153 "points": false,
154 "renderer": "flot",
155 "seriesOverrides": [],
156 "span": 6,
157 "stack": false,
158 "steppedLine": false,
159 "targets": [
160 ],
161 "timeFrom": null,
162 "timeShift": null,
163 "title": "",
164 "tooltip": {
165 "msResolution": true,
166 "shared": true,
167 "value_type": "cumulative"
168 },
169 "type": "graph",
170 "xaxis": {
171 "show": true
172 },
173 "yaxes": [
174 {
175 "format": "short",
176 "label": null,
177 "logBase": 1,
178 "max": null,
179 "min": null,
180 "show": true
181 },
182 {
183 "format": "short",
184 "label": null,
185 "logBase": 1,
186 "max": null,
187 "min": null,
188 "show": true
189 }
190 ]
191 }
192 '''
193 self.dashBoard = '''
194 {
195 "dashboard":{
196 "annotations": {
197 "list": []
198 },
199 "refresh": "1m",
200 "editable": true,
201 "hideControls": false,
202 "id": null,
203 "overwrite": true,
204 "links": [],
205 "rows": [
206 ],
207 "schemaVersion": 12,
208 "sharedCrosshair": false,
209 "style": "dark",
210 "tags": [],
211 "templating": {
212 "list": []
213 },
214 "time": {
215 "from": "now-30m",
216 "to": "now"
217 },
218 "timepicker": {
219 "refresh_intervals": [
220 "5s",
221 "10s",
222 "30s",
223 "1m",
224 "5m",
225 "15m",
226 "30m",
227 "1h",
228 "2h",
229 "1d"
230 ],
231 "time_options": [
232 "5m",
233 "15m",
234 "1h",
235 "6h",
236 "12h",
237 "24h",
238 "2d",
239 "7d",
240 "30d"
241 ]
242 },
243 "timezone": "browser",
244 "title": "",
245 "version": 0
246 }
247 }
248 '''
249
250 #TODO This functionality is a work in progress and needs to be completed.
251 def apply_template(self, tplt_info):
252 # The tplt_info is the record returned by Grafana as a result of a
253 # search request. This includes the id, title, uri, and other fields
254 # of no interest to us. The URI provides the key to access the
255 # dashboard definition from which we'll create a template.
256 try:
257 r = requests.get(self.grafana_url + "/dashboards/" + \
258 tplt_info['uri'])
259 db = r.json()
260 # We don't need all the meta-data so just keep the dashboard
261 # definition
262 db = db['dashboard']
263 # We need to null out the id to create new dashboards with the
264 # template.
265 db['id'] = None
266 # Extract the rows and empty them from the template
267 rows = db['rows']
268 db['rows']=[]
269 # Determine if the rows are wildcarded or fixed, if wildcarded they
270 # need to map to the port which will create one row per port if
271 # they're not wildcarded then the title will be used as the port id
272 # and the same fixed number of rows will be used for every
273 # dashboard.
274 # Wildcarding implies a single row so check that first.
275 if len(rows) == 1:
276 # We might have wildcarding, search for it in the row titile
277 match = re.search(r'%port%',rows[0]['title'])
278 if match:
279 # Yes there is a wildcard, flag it
280 log.info("Wildcard found in template row") #debug
281 else:
282 log.info("No wildcard found in template row") #debug
283 else:
284 # We don't have wildcarding
285 log.info("No wildcard possible in multi-row template") #debug
286
287 except:
288 e = sys.exc_info()
289 print("ERROR: ", e)