Skip to content

[UA] Add ability to split out sub-events in the LogStatsFile #2059

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pkgs/unified_analytics/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 7.0.2
- Allow `LogStatsFile` to contain more granular event types (specifically `property_editor` events).

## 7.0.1
- Fixed `UnsupportedError` thrown when Event.exception is called without providing a value for `args`.

Expand Down
8 changes: 7 additions & 1 deletion pkgs/unified_analytics/USAGE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,10 @@ Explanation of the each key above
- flutterChannelCount: count of flutter channels (can be 0 if developer is a Dart dev only)
- toolCount: count of the Dart and Flutter tools sending analytics
- recordCount: count of the total number of events in the log file
- eventCount: counts each unique event and how many times they occurred in the log file
- eventCount: counts each unique event and how many times they occurred in the log file

Note: You can test any changes to the `LogFileStats` during development by running:

```shell
dart run example/log_stats.dart
```
22 changes: 22 additions & 0 deletions pkgs/unified_analytics/example/log_stats.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:unified_analytics/unified_analytics.dart';

final Analytics analytics = Analytics.development(
tool: DashTool.flutterTool,
flutterChannel: 'ey-test-channel',
flutterVersion: 'Flutter 3.29.2',
clientIde: 'VSCode',
dartVersion: 'Dart 3.7.2',
);

/// Simple CLI to print the logFileStats to the console.
///
/// Run with: dart run example/log_stats.dart
void main() async {
print(analytics.logFileStats());
// Close the client connection on exit.
await analytics.close();
}
11 changes: 10 additions & 1 deletion pkgs/unified_analytics/lib/src/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const int kMaxLogFileSize = 25 * (1 << 20);
const String kLogFileName = 'dart-flutter-telemetry.log';

/// The current version of the package, should be in line with pubspec version.
const String kPackageVersion = '7.0.1';
const String kPackageVersion = '7.0.2';

/// The minimum length for a session.
const int kSessionDurationMinutes = 30;
Expand Down Expand Up @@ -117,3 +117,12 @@ Privacy Policy (https://policies.google.com/privacy).
/// If the message below is altered, the version should be incremented so that
/// users can be prompted with the updated messaging.
const int kToolsMessageVersion = 1;

/// Constants for Dash tools

/// DevTools:
const String devtoolsEventLabel = 'devtools_event';

const String propertyEditorId = 'propertyEditorSidebar';

const String propertyEditorLogStatsName = 'property_editor';
30 changes: 29 additions & 1 deletion pkgs/unified_analytics/lib/src/log_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,10 @@ class LogItem {
// a map for the one event in the value
final eventProp =
(record['events']! as List<Object?>).first as Map<String, Object?>;
final eventName = eventProp['name'] as String;
final eventName = _logItemEventName(
eventProp['name'] as String,
event: eventProp,
);

// Parse the data out of the `user_properties` value
final userProps = record['user_properties'] as Map<String, Object?>;
Expand Down Expand Up @@ -462,3 +465,28 @@ class LogItem {
);
}
}

/// Logic for creating a more granular event name for the [LogItem].
String _logItemEventName(
String eventName, {
required Map<String, Object?> event,
}) {
switch (eventName) {
case devtoolsEventLabel:
return _granularDevToolsEventName(eventName, event: event);
default:
return eventName;
}
}

String _granularDevToolsEventName(
String eventName, {
required Map<String, Object?> event,
}) {
final params = event['params'] as Map<String, Object?>;
final screen = params['screen'];
if (screen is String && screen == propertyEditorId) {
return propertyEditorLogStatsName;
}
return eventName;
}
2 changes: 1 addition & 1 deletion pkgs/unified_analytics/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: >-
# LINT.IfChange
# When updating this, keep the version consistent with the changelog and the
# value in lib/src/constants.dart.
version: 7.0.1
version: 7.0.2
# LINT.ThenChange(lib/src/constants.dart)
repository: https://github.com/dart-lang/tools/tree/main/pkgs/unified_analytics
issue_tracker: https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics
Expand Down
30 changes: 30 additions & 0 deletions pkgs/unified_analytics/test/log_handler_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ void main() {
late File logFile;

final testEvent = Event.hotReloadTime(timeMs: 10);
final propertyEditorEvent = Event.devtoolsEvent(
label: devtoolsEventLabel,
screen: propertyEditorId,
eventCategory: 'test',
value: 1);
final devToolsEvent = Event.devtoolsEvent(
label: devtoolsEventLabel,
screen: 'inspector',
eventCategory: 'test',
value: 1);

setUp(() {
fs = MemoryFileSystem.test(style: FileSystemStyle.posix);
Expand Down Expand Up @@ -71,6 +81,26 @@ void main() {
expect(analytics.logFileStats()!.recordCount, countOfEventsToSend);
});

test('LogFileStats handles granular events', () async {
final countOfPropertyEditorEventsToSend = 5;
final countOfDevToolsEventsToSend = 10;

for (var i = 0; i < countOfPropertyEditorEventsToSend; i++) {
analytics.send(propertyEditorEvent);
}
for (var i = 0; i < countOfDevToolsEventsToSend; i++) {
analytics.send(devToolsEvent);
}

expect(analytics.logFileStats(), isNotNull);
expect(logFile.readAsLinesSync().length,
countOfPropertyEditorEventsToSend + countOfDevToolsEventsToSend);
expect(analytics.logFileStats()!.eventCount['property_editor'],
countOfPropertyEditorEventsToSend);
expect(analytics.logFileStats()!.eventCount['devtools_event'],
countOfDevToolsEventsToSend);
});

test('The only record in the log file is malformed', () async {
// Write invalid json for the only log record
logFile.writeAsStringSync('{{\n');
Expand Down