Skip to content

Commit

Permalink
1 adding dash analytics (#2)
Browse files Browse the repository at this point in the history
Includes the initial commit for the dash_analytics package – additional work includes adding more `DashTool` enum values as deciding if we want to standardize the `eventData` within the `Analytics.sendEvent(...)` method
  • Loading branch information
eliasyishak authored Feb 14, 2023
1 parent 73f15e4 commit ecd5bdd
Show file tree
Hide file tree
Showing 24 changed files with 2,586 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.DS_Store
5 changes: 5 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# The CODEOWNERS file helps to define individuals or teams that responsible
# for code within the repository
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

/pkgs/dash_analytics/ @eliasyishak
14 changes: 14 additions & 0 deletions pkgs/dash_analytics/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Files and directories created by pub.
.dart_tool/
.packages

# Conventional directory for build outputs.
build/

# Omit committing pubspec.lock for library packages; see
# https://dart.dev/guides/libraries/private-files#pubspeclock.
pubspec.lock

.vscode/
coverage/
*.DS_Store
3 changes: 3 additions & 0 deletions pkgs/dash_analytics/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.1.0

- Initial version.
27 changes: 27 additions & 0 deletions pkgs/dash_analytics/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Copyright 2023, the Dart project authors.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google LLC nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10 changes: 10 additions & 0 deletions pkgs/dash_analytics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## What's This?

This package is intended to be used on Dash (Flutter, Dart, etc.) related tooling only.
It provides APIs to send events to Google Analytics using the Measurement Protocol.

This is not intended to be general purpose or consumed by the community. It is responsible for toggling analytics collection for Dash related tooling on each developer's machine.

## Using This Package As A Dash Tool

Refer to the [guide](USAGE_GUIDE.md)
160 changes: 160 additions & 0 deletions pkgs/dash_analytics/USAGE_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
This package is intended to be used on Dash (Flutter, Dart, etc.) related tooling only.
It provides APIs to send events to Google Analytics using the Measurement Protocol.

## Usage

To get started using this package, import at the entrypoint dart file and
initialize with the required parameters

```dart
import 'dash_analytics';
// Constants that should be resolved by the client using package
final DashTool tool = DashTool.flutterTools; // Restricted to enum provided by package
final String measurementId = 'xxxxxxxxxxxx'; // To be provided to client
final String apiSecret = 'xxxxxxxxxxxx'; // To be provided to client
// Values that need to be provided by the client that may
// need to be calculated
final String branch = ...;
final String flutterVersion = ...;
final String dartVersion = ...;
// Initialize the [Analytics] class with the required parameters;
// preferably outside of the [main] method
final Analytics analytics = Analytics(
tool: tool,
measurementId: measurementId,
apiSecret: apiSecret,
branch: branch,
flutterVersion: flutterVersion,
dartVersion: dartVersion,
);
// Timing a process and sending the event
void main() {
DateTime start = DateTime.now();
int count = 0;
// Example of long running process
for (int i = 0; i < 2000; i++) {
count += i;
}
// Calculate the metric to send
final int runTime = DateTime.now().difference(start).inMilliseconds;
// Generate the body for the event data
final Map<String, int> eventData = {
'time_ns': runTime,
};
// Choose one of the enum values for [DashEvent] which should
// have all possible events; if not there, open an issue for the
// team to add
final DashEvent eventName = ...; // Select appropriate DashEvent enum value
// Make a call to the [Analytics] api to send the data
analytics.sendEvent(
eventName: eventName,
eventData: eventData,
);
// Close the client connection on exit
analytics.close();
}
```

## Opting In and Out of Analytics Collection

It will be important for each Dash tool to expose a trivial method to
disabling or enabling analytics collection. Based on how the user interacts
with the tool, this can be done through the CLI, IDE, etc. The Dash tool will
then pass a boolean to an API exposed by the package as shown below

```dart
// Begin by initializing the class
final Analytics analytics = Analytics(...);
// The boolean below simulates the user deciding to opt-out
// of Analytics collection
final bool status = false;
// Call the method to pass the boolean
analytics.setTelemetry(status);
```

## Informing Users About Analytics Opt-In Status

When a user first uses any Dash tool with this package enabled, they
will be enrolled into Analytics collection. It will be the responsiblity
of the Dash tool using this package to display the proper Analytics messaging
and inform them on how to Opt-Out of Analytics collection if they wish. The
package will expose APIs that will make it easy to configure Opt-In status.

```dart
// Begin by initializing the class
final Analytics analytics = Analytics(...);
// This should be performed every time the Dash tool starts up
if (analytics.shouldShowMessage) {
// How each Dash tool displays the message will be unique,
// print statement used for trivial usage example
print(analytics.toolsMessage);
}
```

## Checking User Opt-In Status

Some Dash tools may need to know if the user has opted in for Analytics
collection in order to enable additional functionality. The example below
shows how to check the status

```dart
// Begin by initializing the class
final Analytics analytics = Analytics(...);
// This getter will return a boolean showing the status;
// print statement used for trivial usage example
print('This user's status: ${analytics.telemetryEnabled}'); // true if opted-in
```

## Advanced Usage: Querying Locally Persisted Logs

This package enables dash tools to persist the events that have been
sent to Google Analytics for logging by default. This can be very helpful if
dash tools would like to understand the user's activity level across all
dash related tooling. For example, if querying the locally persisted logs
shows that the user has not been active for N number of days, a dash tool that
works within an IDE can prompt the user with a survey to understand why their
level of activity has dropped.

The snippet below shows how to invoke the query and a sample response

```dart
// Begin by initializing the class
final Analytics analytics = Analytics(...);
// Printing the query results returns json formatted
// string to view; data can also be accessed through
// [LogFileStats] getters
print(analytics.logFileStats());
// Prints out the below
// {
// "startDateTime": "2023-02-08 15:07:10.293728",
// "endDateTime": "2023-02-08 15:07:10.299678",
// "sessionCount": 1,
// "flutterChannelCount": 1,
// "toolCount": 1
// }
```

Explanation of the each key above

- startDateTime: the earliest event that was sent
- endDateTime: the latest, most recent event that was sent
- sessionCount: count of sessions; sessions have a minimum time of 30 minutes
- flutterChannelCount: count of flutter channels (can be 0 if developer is a Dart dev only)
- toolCount: count of the dash tools sending analytics
34 changes: 34 additions & 0 deletions pkgs/dash_analytics/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This file configures the static analysis results for your project (errors,
# warnings, and lints).
#
# This enables the 'recommended' set of lints from `package:lints`.
# This set helps identify many issues that may lead to problems when running
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
# style and format.
#
# If you want a smaller set of lints you can change this to specify
# 'package:lints/core.yaml'. These are just the most critical lints
# (the recommended set includes the core lints).
# The core lints are also what is used by pub.dev for scoring packages.

include: package:lints/recommended.yaml

# Uncomment the following section to specify additional rules.

linter:
rules:
- always_declare_return_types
- always_specify_types
- camel_case_types
- prefer_single_quotes
- unawaited_futures

# analyzer:
# exclude:
# - path/to/excluded/files/**

# For more information about the core and recommended set of lints, see
# https://dart.dev/go/core-lints

# For additional information about configuring this file, see
# https://dart.dev/guides/language/analysis-options
11 changes: 11 additions & 0 deletions pkgs/dash_analytics/coverage_runner.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

# Generate `coverage/lcov.info` file
flutter test --coverage

# Generate HTML report
# Note: on macOS you need to have lcov installed on your system (`brew install lcov`) to use this:
genhtml coverage/lcov.info -o coverage/html

# Open the report
open coverage/html/index.html
36 changes: 36 additions & 0 deletions pkgs/dash_analytics/example/dash_analytics_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2023, 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:dash_analytics/dash_analytics.dart';

final String measurementId = 'G-N1NXG28J5B';
final String apiSecret = '4yT8__oER3Cd84dtx6r-_A';

// Globally instantiate the analytics class at the entry
// point of the tool
final Analytics analytics = Analytics(
tool: DashTool.flutterTools,
measurementId: measurementId,
apiSecret: apiSecret,
flutterChannel: 'ey-test-channel',
flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
dartVersion: 'Dart 2.19.0',
);

void main() {
DateTime start = DateTime.now();
print('###### START ###### $start');

print(analytics.telemetryEnabled);
analytics.sendEvent(
eventName: DashEvent.hotReloadTime,
eventData: <String, int>{'time_ns': 345},
);
print(analytics.logFileStats());
analytics.close();

DateTime end = DateTime.now();
print(
'###### DONE ###### ${DateTime.now()} ${end.difference(start).inMilliseconds}ms');
}
7 changes: 7 additions & 0 deletions pkgs/dash_analytics/lib/dash_analytics.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) 2023, 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.

export 'src/analytics.dart' show Analytics;
export 'src/enums.dart';
export 'src/log_handler.dart' show LogFileStats;
Loading

0 comments on commit ecd5bdd

Please sign in to comment.