Skip to content

Feature -> Develop | Added logging service document #261

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

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -11,61 +11,54 @@ package `get_storage`
::

```dart{4,5,7,10,14,22,26,51,54}
...
class BaseController extends GetxController {
Future<void> init({
required Widget app,
required Widget errorApp,
FirebaseOptions? firebaseOptions,
}) async {
try {
// Storage initialization to store some properties locally
await GetStorage.init();

Future<void> init({
required Widget app,
FirebaseOptions? firebaseOptions,
}) async {
// Storage initialization to store some properties locally
await GetStorage.init();
// Environment initialization
final envController = Get.put(EnvController());
await envController.initialize();
final EnvironmentConfig config = EnvironmentConfig.getConfig;

// Environment initialization
EnvironmentConfig.setEnvConfig();
final EnvironmentConfig config = EnvironmentConfig.getEnvConfig();
// Initialization of Firebase and Services
bool isFirebaseEnabled = firebaseOptions != null;
if (isFirebaseEnabled) {
await Firebase.initializeApp(
options: firebaseOptions,
);
}

// Initialization of Firebase and Services
if (firebaseOptions != null) {
await Firebase.initializeApp(
options: firebaseOptions,
);
DynamicLinks.init();
}
// Other Local Initializations (Depends on your app)
AppTheme.init();
Api.init();

// Other Local Initializations (Depends on your app)
AppTheme.init();
Api.init();
// RootAssets
Get.put(RootAssetsController());

// Sentry Initialization (And/ Or) Running main app
if (null != config.sentryConfig && config.sentryConfig!.dsn.isNotEmpty) {
await SentryFlutter.init(
(options) => options
..dsn = config.sentryConfig!.dsn
..autoAppStart = config.sentryConfig!.autoAppStart
..tracesSampleRate = config.sentryConfig!.tracesSampleRate
..enableAutoPerformanceTracing = config.sentryConfig!.enableAutoPerformanceTracing
..enableUserInteractionTracing = config.sentryConfig!.enableUserInteractionTracing
..environment = config.envType,
);
Widget child = app;
if (config.sentryConfig!.enableUserInteractionTracing) {
child = SentryUserInteractionWidget(
child: child,
);
}
if (config.sentryConfig!.enableAssetsInstrumentation) {
child = DefaultAssetBundle(
bundle: SentryAssetBundle(
enableStructuredDataTracing: true,
// Other Core Services
await PushNotifications.init();
await InternalNotifications.init();
PushNotifications.askPermission();

// Error Monitoring & Logging
Widget child = await Log.init(
app: app,
errorLogging: config.errorLoggingTypeService(
isFirebaseEnabled: isFirebaseEnabled,
),
child: child,
);
runApp(child);
} catch (error, stackTrace) {
debugPrint(error.toString());
debugPrintStack(stackTrace: stackTrace);
runApp(errorApp);
}
// Running main app
runApp(child);
} else {
// Running main app when sentry config is not there
runApp(app);
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ Environment config contains below properties.
| backendUrl | No use |
| apiUrl | Represents root endpoint of url |
| timeoutLimit | Represents timeout limit for requests (in milliseconds) |
| firebaseId | Represents firebase id of app |
| enableLocalLogs | Used for enabling/ disabling Local Logs |
| enableCloudLogs | Used for enabling/ disabling Cloud Logs |
| enableApiLogInterceptor | Used for enabling/ disabling API Request and Response Local logs |
| errorLoggingType | Represent which logging service we want to use |
| sentryConfig | Contains all essential values for sentry |
| datadogConfig | Contains all essential values for datadog |
| pushNotificationsServiceType | Used to set the Push Notifications Service Type |
| oneSignalConfig | Used to set the One signal config **(needed/ works only when push notification service type is remote)** |
| internalNotificationsServiceType | Used to set the Internal Notifications Service Type |
Expand All @@ -69,13 +70,27 @@ check more [here](../directory_structure/vaahextendflutter/services/performance_

| **Property Name** | **Description** |
| --- | --- |
| dsn | Data Source Name (which is unique per project amd developer can obtain that by creating a new project in sentry) |
| dsn | Data Source Name (which is unique per project and developer can obtain that by creating a new project in sentry) |
| enableAutoPerformanceTracing | if set to false nothing will be monitored |
| autoAppStart | if enabled will monitor cold and warm start up time |
| enableUserInteractionTracing | if enabled will monitor User Interaction |
| enableAssetsInstrumentation | if enabled will monitor Asset Performance |
| tracesSampleRate | will report uncaught errors as per rate is set, i.e. if it's 0.4 then 40% of all uncaught error will be reported |

#### DataDog Config (datadogConfig)

Check out more [here](../directory_structure/vaahextendflutter/services/logging_library/logging_library.md)

| **Property Name** | **Description** |
| --- | --- |
| clientToken | Client token for Logging and APM(Application Performance Monitoring) which is unique per project and developer can obtain that by creating a new project in datadog.|
| applicationId | A RUM(Real User Monitoring) Application Id. Obtained on the Datadog website.|
| site | The [DatadogSite] to send information.|
| nativeCrashReportEnabled | Whether or not to enable native crash reporting.|
| firstPartyHosts | This is used in conjunction with Datadog network tracking packages like `datadog_tracking_http_client`.|
| tracesSampleRate | Will report uncaught errors as per rate is set, i.e. if it's 20.0 then 20% of all uncaught error will be reported.|
| reportFlutterPerformance | Whether or not to enable Flutter Performance reporting.|

#### Push Notifications Service Type (pushNotificationsServiceType)

Check [this](../directory_structure/vaahextendflutter/services/notification/push/notification.md).
Expand Down Expand Up @@ -125,7 +140,7 @@ final EnvironmentConfig developConfig = EnvironmentConfig(
backendUrl: '',
apiUrl: '',
timeoutLimit: 20 * 1000, // 20 seconds
firebaseId: '',
errorLoggingType: ErrorLoggingType.noService,
sentryConfig: const SentryConfig(
dsn: '',
enableAutoPerformanceTracing: true,
Expand All @@ -134,6 +149,15 @@ final EnvironmentConfig developConfig = EnvironmentConfig(
enableAssetsInstrumentation: true,
tracesSampleRate: 0.6,
),
datadogConfig: DatadogConfig(
clientToken: '<Your client-token>',
applicationId: '<Your application-id>',
site: DatadogSite.us1,
firstPartyHosts: ['com.webreinvent.vaahflutter'],
nativeCrashReportEnabled: true,
reportFlutterPerformance: true,
tracesSampleRate: 30.0
),
enableLocalLogs: true,
enableCloudLogs: true,
enableApiLogInterceptor: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,39 +81,52 @@ Just toogle environment flags to enable/ disable monitoring.

## Where is the code that handles this?

base_controller handles everything. So if developer is building on our app or has similar code of `base_controller` in their `core_controller or main` then they are good to go.
As we have [SentryLoggingService](./_cloud/sentry_logging_service.md). So if developer is building on our app or has similar code of `service` in their `services` then they are good to go. Just need to initialize the [LoggingLibrary](./logging_library.md) into the BaseController, it will return the updated child and which can parsed to `runApp(updatedChild)`.
```dart
static EnvironmentConfig get _config => EnvironmentConfig.getConfig;
```

```
Widget child = await Log.init(
app: app,
errorLogging: config.errorLoggingTypeService(
isFirebaseEnabled: isFirebaseEnabled,
),
);
runApp(child);
```

```dart
final EnvironmentConfig config = EnvironmentConfig.getEnvConfig();

if (null != config.sentryConfig && config.sentryConfig!.dsn.isNotEmpty) {
await SentryFlutter.init(
(options) => options
..dsn = config.sentryConfig!.dsn
..autoAppStart = config.sentryConfig!.autoAppStart
..tracesSampleRate = config.sentryConfig!.tracesSampleRate
..enableAutoPerformanceTracing = config.sentryConfig!.enableAutoPerformanceTracing
..enableUserInteractionTracing = config.sentryConfig!.enableUserInteractionTracing
..environment = config.envType,
@override
Future<Widget> init({
required Widget app,
}) async {
Widget widget = app;
await SentryFlutter.init(
(options) => options
..dsn = _config.sentryConfig!.dsn
..autoAppStart = _config.sentryConfig!.autoAppStart
..tracesSampleRate = _config.sentryConfig!.tracesSampleRate
..enableAutoPerformanceTracing = _config.sentryConfig!.enableAutoPerformanceTracing
..enableUserInteractionTracing = _config.sentryConfig!.enableUserInteractionTracing
..environment = _config.envType,
);
Widget child = app; // Main (Material) App
if (config.sentryConfig!.enableUserInteractionTracing) {
child = SentryUserInteractionWidget(
child: child,
);

if (_config.sentryConfig!.enableUserInteractionTracing) {
widget = SentryUserInteractionWidget(
child: widget,
);
}
if (config.sentryConfig!.enableAssetsInstrumentation) {
child = DefaultAssetBundle(
bundle: SentryAssetBundle(
enableStructuredDataTracing: true,
),
child: child,
);
if (_config.sentryConfig!.enableAssetsInstrumentation) {
widget = DefaultAssetBundle(
bundle: SentryAssetBundle(
enableStructuredDataTracing: true,
),
child: widget,
);
}
runApp(child);
} else {
runApp(app);
}
return widget;
}
```

As you can see depending on environment variables we apply different performance monitoring mechanisms.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,39 +45,123 @@ Developer Guide
## Source code

```dart
import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

import './logging_service.dart';
import '../../../env/env.dart';
import '../_local/console_service.dart';
import '../models/log.dart';
import 'logging_service.dart';

abstract class SentryLoggingService implements LoggingService {
static logEvent({
class SentryLoggingService implements LoggingService {
static EnvironmentConfig get _config => EnvironmentConfig.getConfig;

@override
Future<Widget> init({
required Widget app,
}) async {
Widget widget = app;
await SentryFlutter.init(
(options) => options
..dsn = _config.sentryConfig!.dsn
..autoAppStart = _config.sentryConfig!.autoAppStart
..tracesSampleRate = _config.sentryConfig!.tracesSampleRate
..enableAutoPerformanceTracing = _config.sentryConfig!.enableAutoPerformanceTracing
..enableUserInteractionTracing = _config.sentryConfig!.enableUserInteractionTracing
..environment = _config.envType,
);

if (_config.sentryConfig!.enableUserInteractionTracing) {
widget = SentryUserInteractionWidget(
child: widget,
);
}
if (_config.sentryConfig!.enableAssetsInstrumentation) {
widget = DefaultAssetBundle(
bundle: SentryAssetBundle(
enableStructuredDataTracing: true,
),
child: widget,
);
}
return widget;
}

@override
Future<void> addEventsLogger({
required dynamic rumActionType,
required String eventName,
Map<String, Object>? eventProperties,
}) async {
Console.log(
"~~~~~~> This method should be avoided with this logging service, as it doesn't do anything",
);
}

@override
Future<void> addSectionLogger({
required String sectionName,
required sectionValue,
}) async {
Console.log(
"~~~~~~> This method should be avoided with this logging service, as it doesn't do anything",
);
}

@override
Future<void> logEvent({
required String message,
SentryLevel? level,
EventType? type,
Object? data,
}) {
final SentryEvent event = SentryEvent(message: SentryMessage(message), level: level);
}) async {
final SentryEvent event = SentryEvent(
message: SentryMessage(message),
level: type!.toSentryLevel,
);
Sentry.captureEvent(
event,
hint: data == null ? null : Hint.withMap({'data': data}),
);
}

static logException(
dynamic throwable, {
dynamic stackTrace,
dynamic hint,
}) {
Sentry.captureException(throwable, stackTrace: stackTrace, hint: hint);
@override
Future<void> logException(
throwable, {
source,
stackTrace,
hint,
}) async {
Sentry.captureException(
throwable,
stackTrace: stackTrace,
hint: hint,
);
}

static logTransaction({
@override
Future<void> logTransaction({
required Function execute,
required TransactionDetails details,
}) async {
final ISentrySpan transaction = Sentry.startTransaction(details.name, details.operation);
final ISentrySpan transaction = Sentry.startTransaction(
details.name,
details.operation,
);
await execute();
await transaction.finish();
}

@override
Future<void> setUserInfoLogger({
String? id,
String? name,
String? email,
Map<String, dynamic>? extraInfo,
}) async {
Console.log(
"~~~~~~> This method should be avoided with this logging service, as it doesn't do anything",
);
}
}

```
Loading