@@ -359,108 +359,89 @@ def _get_template_values_from_paths(self, paths, _filter, template,
359
359
'fields' , []):
360
360
path_measurements [measurement ].setdefault (
361
361
'fields' , []).append (field )
362
- path_measurements [measurement ][ 'tags' ] = list (
363
- itertools . product ( * _tags . values ()) )
362
+ path_measurements [measurement ]. setdefault (
363
+ 'template' , template )
364
364
return _measurements , _tags , _fields , matched_paths
365
365
366
366
def _get_all_template_values (self , paths ):
367
367
paths = paths [:]
368
- query_data = deque ()
369
368
path_measurements = {}
369
+ measurements , tags , fields = deque (), deque (), set ()
370
370
for (_filter , template , default_tags , separator ) in self .graphite_templates :
371
- # One influx query statement per template
371
+ # One influx measurement queried per template
372
372
if not paths :
373
373
break
374
374
_measurements , _tags , _fields , matched_paths = \
375
375
self ._get_template_values_from_paths (
376
376
paths , _filter , template , default_tags , separator ,
377
377
path_measurements )
378
378
if _measurements :
379
- # Found template match for path, add query data and
379
+ # Found template match for path, append query data and
380
380
# remove matched paths so we do not try to match them again
381
- query_data .append ((_measurements , _tags , _fields ))
381
+ measurements .extend (_measurements )
382
+ tags .append (_tags )
383
+ fields = fields .union (_fields )
382
384
for path in matched_paths :
383
385
del paths [paths .index (path )]
384
- return query_data , path_measurements
386
+ return measurements , tags , fields , path_measurements
385
387
386
- def _gen_query (self , _measurements , _tags , _fields , retention ):
387
- # import ipdb; ipdb.set_trace( )
388
+ def _gen_query (self , measurements , tags , fields , retention ):
389
+ groupings = set ([ k for t in tags for k in t . keys ()] )
388
390
measurements = ', ' .join (
389
- ('"%s"."%s"' % (retention , measure ,) for measure in _measurements )) \
391
+ ('"%s"."%s"' % (retention , measure ,) for measure in measurements )) \
390
392
if retention \
391
- else ', ' .join (('"%s"' % (measure ,) for measure in _measurements ))
392
- groupings = deque ()
393
- tags = deque ()
394
- for tag in _tags :
395
- if len (_tags [tag ]) > 1 :
396
- groupings .append (tag )
397
- continue
398
- tags .append (""""%s" = '%s'""" % (tag , _tags [tag ],))
399
- # tag_sets = [[""""%s" = '%s'""" % (tag, tag_val,)
400
- # for tag_val in _tags[tag]]
401
- # for tag in _tags] \
402
- # if _tags else None
403
- ####
404
- # tags = [' AND '.join(['(%s)' % ' OR '.join(
405
- # [""""%s" = '%s'""" % (tag, tag_val,) for tag_val in _tags[tag]])
406
- # for tag in _tags])] if _tags else None
407
- ####
408
- # tag_pairs = itertools.product(*tag_sets) if tag_sets else None
409
- # tags = [" AND ".join(t) for t in tag_pairs] if tag_pairs else None
410
- fields = _fields if _fields else ['value' ]
411
- return measurements , tags , fields , groupings
393
+ else ', ' .join (('"%s"' % (measure ,) for measure in measurements ))
394
+ _tags = ' OR ' .join (['(%s)' % (tag_set ,) for tag_set in [
395
+ ' AND ' .join (['(%s)' % ' OR ' .join ([
396
+ """"%s" = '%s'""" % (tag , tag_val ,)
397
+ for tag_val in __tags [tag ]])
398
+ for tag in __tags ])
399
+ for __tags in tags ]]) if tags else None
400
+ fields = fields if fields else ['value' ]
401
+ return measurements , _tags , fields , groupings
412
402
413
403
def _gen_query_values_from_templates (self , paths , retention ):
414
- _query_data , path_measurements = self ._get_all_template_values (paths )
415
- if len (_query_data ) == 0 :
416
- return
417
- query_data = deque ()
418
- for (_measurements , _tags , _fields ) in _query_data :
419
- measurements , tags , fields , groupings = self ._gen_query (
420
- _measurements , _tags , _fields , retention )
421
- query_data .append ((measurements , tags , fields , groupings ),)
422
- # import ipdb; ipdb.set_trace()
423
- return query_data , path_measurements
404
+ measurements , tags , fields , path_measurements = \
405
+ self ._get_all_template_values (paths )
406
+ measurements , tags , fields , groupings = self ._gen_query (
407
+ measurements , tags , fields , retention )
408
+ return measurements , tags , fields , groupings , path_measurements
424
409
425
410
def _gen_query_values (self , paths , retention ):
426
411
if self .graphite_templates :
427
412
return self ._gen_query_values_from_templates (paths , retention )
428
413
measurement = ', ' .join (('"%s"."%s"' % (retention , path ,) for path in paths )) \
429
414
if retention \
430
415
else ', ' .join (('"%s"' % (path ,) for path in paths ))
431
- return ((measurement , None , ['value' ]),), None
432
-
433
- def _gen_unique_infl_queries (self , query_data , start_time , end_time ,
434
- aggregation_func , interval ):
435
- queries = deque ()
436
- for (measurement , tags , fields ) in query_data :
437
- query_fields = ', ' .join (['%s("%s") as "%s"' % (
438
- aggregation_func , field , field ) for field in fields ])
439
- query = 'select %s from %s where (time > %ds and time <= %ds)' % (
440
- query_fields , measurement , start_time , end_time ,)
441
- group_by = 'GROUP BY time(%ss) fill(previous)' % (interval ,)
442
- if tags :
443
- # Add sub queries
444
- queries .append (';' .join (
445
- ["%s AND %s %s" % (query , tag , group_by ,)
446
- for tag in tags ]))
447
- else :
448
- queries .append (" " .join ([query , group_by ]))
449
- return queries
416
+ return measurement , None , ['value' ], None , None
417
+
418
+ def _gen_infl_stmt (self , measurements , tags , fields , groupings , start_time ,
419
+ end_time , aggregation_func , interval ):
420
+ time_clause = "(time > %ds and time <= %ds)" % (start_time , end_time ,)
421
+ query_fields = ', ' .join (['%s("%s") as "%s"' % (
422
+ aggregation_func , field , field ) for field in fields ])
423
+ groupings = ['"%s"' % (grouping ,) for grouping in groupings ] \
424
+ if groupings else []
425
+ groupings .insert (0 , 'time(%ss)' % (interval ,))
426
+ groupings = ', ' .join (groupings )
427
+ where_clause = "%s AND %s" % (time_clause , tags ,) if tags else \
428
+ time_clause
429
+ group_by = '%s fill(previous)' % (groupings ,)
430
+ query = 'select %s from %s where %s GROUP BY %s' % (
431
+ query_fields , measurements , where_clause , group_by ,)
432
+ return query
450
433
451
434
def _gen_influxdb_stmt (self , start_time , end_time , paths , interval ):
452
435
retention = get_retention_policy (interval , self .retention_policies ) \
453
436
if self .retention_policies else None
454
437
aggregation_func = self ._gen_aggregation_func (paths )
455
438
memcache_key = gen_memcache_key (start_time , end_time , aggregation_func ,
456
439
paths )
457
- try :
458
- query_data , path_measurements = self ._gen_query_values (paths , retention )
459
- except TypeError :
460
- return
461
- queries = self ._gen_unique_infl_queries (
462
- query_data , start_time , end_time , aggregation_func , interval )
463
- query = ';' .join (queries )
440
+ measurements , tags , fields , groupings , path_measurements = \
441
+ self ._gen_query_values (paths , retention )
442
+ query = self ._gen_infl_stmt (measurements , tags , fields , groupings ,
443
+ start_time , end_time , aggregation_func ,
444
+ interval )
464
445
return query , memcache_key , path_measurements
465
446
466
447
def _make_empty_multi_fetch_result (self , time_info , paths ):
@@ -488,7 +469,8 @@ def fetch_multi(self, nodes, start_time, end_time):
488
469
try :
489
470
query , memcache_key , path_measurements = self ._gen_influxdb_stmt (
490
471
start_time , end_time , paths , interval )
491
- except TypeError :
472
+ except TypeError as ex :
473
+ logger .error ("Type error generating query statement - %s" , ex )
492
474
return self ._make_empty_multi_fetch_result (time_info , paths )
493
475
data = self .memcache .get (memcache_key ) if self .memcache else None
494
476
if data :
@@ -506,7 +488,6 @@ def fetch_multi(self, nodes, start_time, end_time):
506
488
logger .debug ("Calling influxdb multi fetch with query - %s" , query )
507
489
data = self .client .query (query , params = _INFLUXDB_CLIENT_PARAMS )
508
490
logger .debug ('fetch_multi() - Retrieved %d result set(s)' , len (data ))
509
- # import ipdb; ipdb.set_trace()
510
491
data = read_influxdb_values (data , paths , path_measurements )
511
492
timer .stop ()
512
493
# Graphite API requires that data contain keys for
0 commit comments