4
4
5
5
import 'dart:convert' ;
6
6
7
+ import 'package:clock/clock.dart' ;
7
8
import 'package:file/file.dart' ;
8
9
import 'package:path/path.dart' as p;
9
10
@@ -16,9 +17,15 @@ class LogFileStats {
16
17
/// The oldest timestamp in the log file
17
18
final DateTime startDateTime;
18
19
20
+ /// Number of minutes from [startDateTime] to [clock.now()]
21
+ final int minsFromStartDateTime;
22
+
19
23
/// The latest timestamp in the log file
20
24
final DateTime endDateTime;
21
25
26
+ /// Number of minutes from [endDateTime] to [clock.now()]
27
+ final int minsFromEndDateTime;
28
+
22
29
/// The number of unique session ids found in the log file
23
30
final int sessionCount;
24
31
@@ -28,22 +35,37 @@ class LogFileStats {
28
35
/// The number of unique tools found in the log file
29
36
final int toolCount;
30
37
38
+ /// The map containing all of the events in the file along with
39
+ /// how many times they have occured
40
+ final Map <String , int > eventCount;
41
+
42
+ /// Total number of records in the log file
43
+ final int recordCount;
44
+
31
45
/// Contains the data from the [LogHandler.logFileStats] method
32
46
const LogFileStats ({
33
47
required this .startDateTime,
48
+ required this .minsFromStartDateTime,
34
49
required this .endDateTime,
50
+ required this .minsFromEndDateTime,
35
51
required this .sessionCount,
36
52
required this .flutterChannelCount,
37
53
required this .toolCount,
54
+ required this .recordCount,
55
+ required this .eventCount,
38
56
});
39
57
40
58
@override
41
59
String toString () => jsonEncode (< String , Object ? > {
42
60
'startDateTime' : startDateTime.toString (),
61
+ 'minsFromStartDateTime' : minsFromStartDateTime,
43
62
'endDateTime' : endDateTime.toString (),
63
+ 'minsFromEndDateTime' : minsFromEndDateTime,
44
64
'sessionCount' : sessionCount,
45
65
'flutterChannelCount' : flutterChannelCount,
46
66
'toolCount' : toolCount,
67
+ 'recordCount' : recordCount,
68
+ 'eventCount' : eventCount,
47
69
});
48
70
}
49
71
@@ -89,26 +111,42 @@ class LogHandler {
89
111
final DateTime startDateTime = records.first.localTime;
90
112
final DateTime endDateTime = records.last.localTime;
91
113
92
- // Collection of unique sessions
114
+ // Map with counters for user properties
93
115
final Map <String , Set <Object >> counter = < String , Set <Object >> {
94
116
'sessions' : < int > {},
95
117
'flutter_channel' : < String > {},
96
118
'tool' : < String > {},
97
119
};
120
+
121
+ // Map of counters for each event
122
+ final Map <String , int > eventCount = < String , int > {};
98
123
for (LogItem record in records) {
99
124
counter['sessions' ]! .add (record.sessionId);
100
125
counter['tool' ]! .add (record.tool);
101
126
if (record.flutterChannel != null ) {
102
127
counter['flutter_channel' ]! .add (record.flutterChannel! );
103
128
}
129
+
130
+ // Count each event, if it doesn't exist in the [eventCount]
131
+ // it will be added first
132
+ if (! eventCount.containsKey (record.eventName)) {
133
+ eventCount[record.eventName] = 0 ;
134
+ }
135
+ eventCount[record.eventName] = eventCount[record.eventName]! + 1 ;
104
136
}
105
137
138
+ final DateTime now = clock.now ();
139
+
106
140
return LogFileStats (
107
141
startDateTime: startDateTime,
142
+ minsFromStartDateTime: now.difference (startDateTime).inMinutes,
108
143
endDateTime: endDateTime,
144
+ minsFromEndDateTime: now.difference (endDateTime).inMinutes,
109
145
sessionCount: counter['sessions' ]! .length,
110
146
flutterChannelCount: counter['flutter_channel' ]! .length,
111
147
toolCount: counter['tool' ]! .length,
148
+ eventCount: eventCount,
149
+ recordCount: records.length,
112
150
);
113
151
}
114
152
@@ -135,6 +173,7 @@ class LogHandler {
135
173
136
174
/// Data class for each record persisted on the client's machine
137
175
class LogItem {
176
+ final String eventName;
138
177
final int sessionId;
139
178
final String ? flutterChannel;
140
179
final String host;
@@ -144,6 +183,7 @@ class LogItem {
144
183
final DateTime localTime;
145
184
146
185
LogItem ({
186
+ required this .eventName,
147
187
required this .sessionId,
148
188
this .flutterChannel,
149
189
required this .host,
@@ -194,18 +234,27 @@ class LogItem {
194
234
/// "value": "flutter-tools"
195
235
/// },
196
236
/// "local_time": {
197
- /// "value": "2023-01-31 14:32:14.592898"
237
+ /// "value": "2023-01-31 14:32:14.592898 -0500 "
198
238
/// }
199
239
/// }
200
240
/// }
201
241
/// ```
202
242
static LogItem ? fromRecord (Map <String , Object ?> record) {
203
- if (! record.containsKey ('user_properties' )) return null ;
243
+ if (! record.containsKey ('user_properties' ) ||
244
+ ! record.containsKey ('events' )) {
245
+ return null ;
246
+ }
204
247
205
248
// Using a try/except here to parse out the fields if possible,
206
249
// if not, it will quietly return null and won't get processed
207
250
// downstream
208
251
try {
252
+ // Parse out values from the top level key = 'events' and return
253
+ // a map for the one event in the value
254
+ final Map <String , Object ?> eventProp =
255
+ ((record['events' ]! as List <Object ?>).first as Map <String , Object ?>);
256
+ final String eventName = eventProp['name' ] as String ;
257
+
209
258
// Parse the data out of the `user_properties` value
210
259
final Map <String , Object ?> userProps =
211
260
record['user_properties' ] as Map <String , Object ?>;
@@ -230,6 +279,10 @@ class LogItem {
230
279
// indicates the record is malformed; note that `flutter_version`
231
280
// and `flutter_channel` are nullable fields in the log file
232
281
final List <Object ?> values = < Object ? > [
282
+ // Values associated with the top level key = 'events'
283
+ eventName,
284
+
285
+ // Values associated with the top level key = 'events'
233
286
sessionId,
234
287
host,
235
288
dartVersion,
@@ -241,9 +294,10 @@ class LogItem {
241
294
}
242
295
243
296
// Parse the local time from the string extracted
244
- final DateTime localTime = DateTime .parse (localTimeString! );
297
+ final DateTime localTime = DateTime .parse (localTimeString! ). toLocal () ;
245
298
246
299
return LogItem (
300
+ eventName: eventName,
247
301
sessionId: sessionId! ,
248
302
flutterChannel: flutterChannel,
249
303
host: host! ,
0 commit comments