5
5
more efficiently.
6
6
"""
7
7
from typing import Dict , Optional , Union
8
+ from datetime import datetime
8
9
9
10
from grafana_client .model import DatasourceModel
10
11
@@ -114,7 +115,7 @@ def datasource_factory(datasource: DatasourceModel) -> DatasourceModel:
114
115
return datasource
115
116
116
117
117
- def query_factory (datasource , expression : str , store : Optional [str ] = None ) -> Union [Dict , str ]:
118
+ def query_factory (datasource , model : Optional [dict ] ) -> Union [Dict , str ]:
118
119
"""
119
120
Create payload suitable for running a query against a Grafana data source.
120
121
@@ -123,7 +124,17 @@ def query_factory(datasource, expression: str, store: Optional[str] = None) -> U
123
124
124
125
TODO: Complete the list for all popular databases.
125
126
"""
127
+ request = {
128
+ "method" : "POST" ,
129
+ "data" : None ,
130
+ "params" : None ,
131
+ }
132
+ attrs = None
133
+
126
134
datasource_type = datasource ["type" ]
135
+ expression = model .get ("query" )
136
+ if expression is None :
137
+ raise KeyError ("query not set" )
127
138
if datasource_type == "__NEVER__" : # pragma:nocover
128
139
raise NotImplementedError ("__NEVER__" )
129
140
elif datasource_type == "elasticsearch" :
@@ -132,24 +143,45 @@ def query_factory(datasource, expression: str, store: Optional[str] = None) -> U
132
143
query = expression
133
144
elif datasource_type == "grafana-simple-json-datasource" :
134
145
query = expression
146
+ #************************************************************************
135
147
elif datasource_type == "graphite" :
136
- query = {"target" : "constantLine(100)" , "from" : "-1h" , "until" : "now" , "format" : "json" , "maxDataPoints" : 300 }
148
+ query = {
149
+ "target" : expression ,
150
+ "from" : "-1h" ,
151
+ "until" : "now" ,
152
+ "format" : "json" ,
153
+ "maxDataPoints" : 300
154
+ }
155
+ if 'time_from' in model :
156
+ query ['from' ]= model ['time_from' ]
157
+ if 'time_to' in model :
158
+ query ['until' ]= model ['time_to' ]
159
+
160
+ request ["data" ] = query
161
+
162
+ #************************************************************************
137
163
elif datasource_type == "influxdb" :
138
164
dialect = datasource ["jsonData" ].get ("version" , "InfluxQL" )
139
165
query = {
140
166
"refId" : "test" ,
141
- "datasource" : {
142
- "type" : datasource ["type" ],
143
- "uid" : datasource .get ("uid" ),
144
- },
145
- "datasourceId" : datasource .get ("id" ),
167
+ # "datasource": {
168
+ # "type": datasource["type"],
169
+ # "uid": datasource.get("uid"),
170
+ # },
171
+ # "datasourceId": datasource.get("id"),
146
172
}
147
173
if dialect == "InfluxQL" :
148
174
query .update (
149
175
{
150
176
"q" : expression ,
151
177
}
152
178
)
179
+ # this drive the how timestamp are rendered in result (string by default, or in milliseconds ms)
180
+ request ["params" ] = { "epoch" : "ms" }
181
+ if 'database' in datasource :
182
+ request ["params" ].update ({ "db" : datasource ['database' ] })
183
+ request ["data" ] = query
184
+
153
185
elif dialect == "Flux" :
154
186
query .update (
155
187
{
@@ -158,47 +190,59 @@ def query_factory(datasource, expression: str, store: Optional[str] = None) -> U
158
190
"query" : expression ,
159
191
}
160
192
)
193
+ request ["data" ] = query
161
194
else :
162
195
raise KeyError (f"InfluxDB dialect '{ dialect } ' unknown" )
196
+
163
197
elif datasource_type == "jaeger" :
164
198
query = {}
199
+
200
+ #************************************************************************
165
201
elif datasource_type == "loki" :
166
- query = {}
167
- elif datasource_type == "mssql" :
168
202
query = {
169
- "refId" : "test" ,
170
203
"datasource" : {
171
204
"type" : datasource ["type" ],
172
205
"uid" : datasource .get ("uid" ),
173
206
},
174
207
"datasourceId" : datasource .get ("id" ),
175
- "format" : "table" ,
176
- "rawSql" : expression ,
177
- }
178
- elif datasource_type == "mysql" :
179
- query = {
180
- "refId" : "test" ,
181
- "datasource" : {
182
- "type" : datasource ["type" ],
183
- "uid" : datasource .get ("uid" ),
184
- },
185
- "datasourceId" : datasource .get ("id" ),
186
- "format" : "table" ,
187
- "rawSql" : expression ,
208
+ # "exemplar": False,
209
+ "expr" : expression ,
188
210
}
211
+
212
+ attrs = [
213
+ { "name" : "intervalMs" , "default" : 60000 , },
214
+ { "name" : "legendFormat" , "default" : "" , },
215
+ { "name" : "maxLines" , "default" : 1000 , },
216
+ { "name" : "maxDataPoints" , "default" : 1442 , },
217
+ { "name" : "queryType" , "default" : "range" , },
218
+ { "name" : "refId" , "default" : "test" , },
219
+ { "name" : "resolution" , "default" : 1 , },
220
+ ]
221
+
189
222
elif datasource_type == "opentsdb" :
190
223
query = {}
191
- elif datasource_type == "postgres" :
224
+
225
+ #************************************************************************
226
+ elif datasource_type in ( "postgres" , "mssql" , "mysql" ):
192
227
query = {
193
- "refId" : "test" ,
194
228
"datasource" : {
195
229
"type" : datasource ["type" ],
196
230
"uid" : datasource .get ("uid" ),
197
231
},
198
232
"datasourceId" : datasource .get ("id" ),
199
- "format" : "table" ,
200
233
"rawSql" : expression ,
201
234
}
235
+ attrs = [
236
+ { "name" : "format" , "default" : "time_series" ,
237
+ "choices" : [ "time_series" , "table" ],
238
+ # "version": "8.0.0"
239
+ },
240
+ { "name" : "intervalMs" , "default" : 15000 , },
241
+ { "name" : "maxDataPoints" , "default" : None , },
242
+ { "name" : "refId" , "default" : None , },
243
+ ]
244
+
245
+ #************************************************************************
202
246
elif datasource_type == "prometheus" :
203
247
query = {
204
248
"datasource" : {
@@ -208,20 +252,26 @@ def query_factory(datasource, expression: str, store: Optional[str] = None) -> U
208
252
"datasourceId" : datasource .get ("id" ),
209
253
# "exemplar": False,
210
254
"expr" : expression ,
211
- # "format": "time_series",
212
- # "instant": True,
213
- # "interval": "",
214
- # "intervalFactor": 10,
215
- # "intervalMs": 30000,
216
- # "legendFormat": "",
217
- # "maxDataPoints": 100,
218
- # "metric": store,
219
- # "queryType": "timeSeriesQuery",
220
- "refId" : "test" ,
221
- "requestId" : "0test" ,
222
- # "step": 300,
223
- # "utcOffsetSec": 7200,
224
255
}
256
+
257
+ attrs = [
258
+ { "name" : "format" , "default" : "time_series" ,
259
+ "choices" : [ "time_series" , "table" , "heatmap" ],
260
+ # "version": "8.0.0"
261
+ },
262
+ { "name" : "instant" , "default" : False , },
263
+ { "name" : "interval" , "default" : "" , },
264
+ { "name" : "intervalFactor" , "default" : None , },
265
+ { "name" : "intervalMs" , "default" : 15000 , },
266
+ { "name" : "legendFormat" , "default" : "" , },
267
+ { "name" : "maxDataPoints" , "default" : None , },
268
+ { "name" : "queryType" , "default" : "timeSeriesQuery" , },
269
+ { "name" : "refId" , "default" : "test" , },
270
+ { "name" : "requestId" , "default" : "0test" , },
271
+ { "name" : "step" , "default" : 300 , },
272
+ { "name" : "utcOffsetSec" , "default" : 0 , },
273
+ ]
274
+
225
275
elif datasource_type == "simpod-json-datasource" :
226
276
query = expression
227
277
elif datasource_type == "tempo" :
@@ -232,7 +282,35 @@ def query_factory(datasource, expression: str, store: Optional[str] = None) -> U
232
282
query = {}
233
283
else :
234
284
raise NotImplementedError (f"Unknown data source type: { datasource_type } " )
235
- return query
285
+
286
+ if attrs is not None :
287
+ for attr in attrs :
288
+ value = attr ["default" ]
289
+ if attr ["name" ] in model :
290
+ tmp_value = model [attr ["name" ]]
291
+ if "choices" in attr :
292
+ if tmp_value in attr ["choices" ]:
293
+ value = tmp_value
294
+ else :
295
+ value = tmp_value
296
+ if value is not None :
297
+ query [attr ["name" ]] = value
298
+
299
+ if 'time_from' not in model or 'time_to' not in model :
300
+ now = datetime .now ()
301
+ if 'time_from' not in model :
302
+ model ['time_from' ] = int ( now .timestamp () ) - 5 * 60
303
+ if 'time_to' not in model :
304
+ model ['time_to' ] = int ( now .timestamp () )
305
+
306
+ payload = {
307
+ "queries" : [query ],
308
+ "from" : str (model ['time_from' ]* 1000 ),
309
+ "to" : str (model ['time_to' ]* 1000 ),
310
+ }
311
+ request ["data" ] = payload
312
+
313
+ return request
236
314
237
315
238
316
# Define health-check status queries for all database types.
0 commit comments