1
+ // ==========================================================================
2
+ // AggregatePointEmitter.cs
3
+ // Bus Portal (busliniensuche.de)
4
+ // ==========================================================================
5
+ // All rights reserved.
6
+ // ==========================================================================
7
+
8
+ using System ;
9
+ using System . Collections . Generic ;
10
+ using System . Linq ;
11
+ using InfluxDB . Collector . Pipeline . Common ;
12
+
13
+ namespace InfluxDB . Collector . Pipeline . Aggregate
14
+ {
15
+ class AggregatePointEmitter : IntervalEmitterBase
16
+ {
17
+ readonly bool _sumIncrements ;
18
+ readonly Func < IEnumerable < long > , double > _timesAggregation ;
19
+ readonly IPointEmitter _parent ;
20
+
21
+ public AggregatePointEmitter ( TimeSpan timeSpan , bool sumIncrements , Func < IEnumerable < long > , double > timesAggregation , IPointEmitter parent )
22
+ : base ( timeSpan )
23
+ {
24
+ _sumIncrements = sumIncrements ;
25
+ _timesAggregation = timesAggregation ;
26
+ _parent = parent ;
27
+ }
28
+
29
+ protected override void HandleBatch ( IReadOnlyCollection < PointData > batch )
30
+ {
31
+ var grouped = batch . GroupBy ( x => new GroupingKey (
32
+ x . UtcTimestamp . HasValue ? x . UtcTimestamp . Value . Ticks / _interval . Ticks : 0 ,
33
+ DetermineKind ( x ) ,
34
+ x . Measurement ,
35
+ x . Tags
36
+ ) ) ;
37
+
38
+ var aggregated = grouped . SelectMany ( Aggregate ) . ToArray ( ) ;
39
+
40
+ _parent . Emit ( aggregated ) ;
41
+ }
42
+
43
+ IEnumerable < PointData > Aggregate ( IGrouping < GroupingKey , PointData > group )
44
+ {
45
+ GroupingKey key = group . Key ;
46
+ MeasurementKind kind = key . Kind ;
47
+
48
+ if ( kind == MeasurementKind . Increment && _sumIncrements )
49
+ {
50
+ long sum = group . Sum ( x => ( long ) x . Fields [ "count" ] ) ;
51
+ return new [ ]
52
+ {
53
+ new PointData (
54
+ key . Measurement ,
55
+ new Dictionary < string , object > { { "count" , sum } } ,
56
+ key . Tags ,
57
+ AverageTime ( key ) )
58
+ } ;
59
+ }
60
+
61
+ if ( kind == MeasurementKind . Time && _timesAggregation != null )
62
+ {
63
+ long ticks = ( long ) _timesAggregation ( group . Select ( x => ( ( TimeSpan ) x . Fields [ "value" ] ) . Ticks ) ) ;
64
+ return new [ ]
65
+ {
66
+ new PointData (
67
+ key . Measurement ,
68
+ new Dictionary < string , object > { { "value" , new TimeSpan ( ticks ) } } ,
69
+ key . Tags ,
70
+ AverageTime ( key ) )
71
+ } ;
72
+ }
73
+
74
+ return group ;
75
+ }
76
+
77
+ private DateTime AverageTime ( GroupingKey key )
78
+ {
79
+ return new DateTime ( key . Bucket * _interval . Ticks + _interval . Ticks / 2 , DateTimeKind . Utc ) ;
80
+ }
81
+
82
+ static MeasurementKind DetermineKind ( PointData x )
83
+ {
84
+ if ( x . Fields . Count != 1 ) return MeasurementKind . Other ;
85
+
86
+ if ( x . Fields . TryGetValue ( "count" , out var count ) && count is long )
87
+ {
88
+ return MeasurementKind . Increment ;
89
+ }
90
+ else if ( x . Fields . TryGetValue ( "value" , out var value ) && value is TimeSpan )
91
+ {
92
+ return MeasurementKind . Time ;
93
+ }
94
+ else
95
+ {
96
+ return MeasurementKind . Other ;
97
+ }
98
+ }
99
+ }
100
+ }
0 commit comments