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
+
12
+ namespace InfluxDB . Collector . Pipeline . Aggregate
13
+ {
14
+ class AggregatePointEmitter : IPointEmitter , IDisposable
15
+ {
16
+ readonly TimeSpan _timeSpan ;
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
+ {
23
+ _timeSpan = timeSpan ;
24
+ _sumIncrements = sumIncrements ;
25
+ _timesAggregation = timesAggregation ;
26
+ _parent = parent ;
27
+ }
28
+
29
+ public void Emit ( PointData [ ] points )
30
+ {
31
+ var grouped = points . GroupBy ( x => new GroupingKey (
32
+ x . UtcTimestamp . HasValue ? x . UtcTimestamp . Value . Ticks / _timeSpan . 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
+ key . Kind )
59
+ } ;
60
+ }
61
+
62
+ if ( kind == MeasurementKind . Time && _timesAggregation != null )
63
+ {
64
+ long ticks = ( long ) _timesAggregation ( group . Select ( x => ( ( TimeSpan ) x . Fields [ "value" ] ) . Ticks ) ) ;
65
+ return new [ ]
66
+ {
67
+ new PointData (
68
+ key . Measurement ,
69
+ new Dictionary < string , object > { { "value" , new TimeSpan ( ticks ) } } ,
70
+ key . Tags ,
71
+ AverageTime ( key ) ,
72
+ key . Kind )
73
+ } ;
74
+ }
75
+
76
+ return group ;
77
+ }
78
+
79
+ private DateTime AverageTime ( GroupingKey key )
80
+ {
81
+ return new DateTime ( key . Bucket + _timeSpan . Ticks / 2 , DateTimeKind . Utc ) ;
82
+ }
83
+
84
+ static MeasurementKind DetermineKind ( PointData x )
85
+ {
86
+ if ( x . Fields . Count != 1 ) return MeasurementKind . Other ;
87
+
88
+ switch ( x . Kind )
89
+ {
90
+ case MeasurementKind . Increment when x . Fields . TryGetValue ( "count" , out var count ) && count is long :
91
+ return MeasurementKind . Increment ;
92
+ case MeasurementKind . Time when x . Fields . TryGetValue ( "value" , out var value ) && value is TimeSpan :
93
+ return MeasurementKind . Time ;
94
+ default :
95
+ return MeasurementKind . Other ;
96
+ }
97
+ }
98
+
99
+ public void Dispose ( )
100
+ {
101
+ }
102
+ }
103
+ }
0 commit comments