Skip to content

Commit

Permalink
feat: added support for offline storage for events (#150)
Browse files Browse the repository at this point in the history
customers can get info regarding events, crash and exception when user does not have internet
connection.

#113,#147
  • Loading branch information
ndesai-newrelic committed Mar 5, 2024
1 parent ed55330 commit 4a1a4f7
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 8 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog

## 1.3.6

### New in this release
* Added Offline Harvesting Feature: This new feature enables the preservation of harvest data that would otherwise be lost when the application lacks an internet connection. The stored harvests will be sent once the internet connection is re-established and the next harvest upload is successful.
* Introduced setMaxOfflineStorageSize API: This new API allows the user to determine the maximum volume of data that can be stored locally. This aids in better management and control of local data storage.
* Updated native iOS Agent: We've upgraded the native iOS agent to version 7.4.9, which includes performance improvements and bug fixes.
* Updated native Android Agent: We've also upgraded the native Android agent to version 7.3.0 bringing benefits like improved stability and enhanced features.
* Added compatibility for Android dynamic features.
* Resolved an issue where events were not being reported in the event of a forceful termination of the application.

These enhancements help to improve overall user experience and application performance.


## 1.3.5

### New in this release
Expand Down
12 changes: 11 additions & 1 deletion README.md
Expand Up @@ -103,6 +103,9 @@ import {Platform} from 'react-native';

// Optional:Enable or disable reporting data using different endpoints for US government clients.
//fedRampEnabled: false

// Optional: Enable or disable offline data storage when no internet connection is available.
offlineStorageEnabled:true
};


Expand All @@ -125,7 +128,7 @@ AppToken is platform-specific. You need to generate the seprate token for Androi
}
dependencies {
...
classpath "com.newrelic.agent.android:agent-gradle-plugin:7.2.0"
classpath "com.newrelic.agent.android:agent-gradle-plugin:7.3.0"
}
}
```
Expand Down Expand Up @@ -418,6 +421,13 @@ See the examples below, and for more detail, see [New Relic IOS SDK doc](https:/
NewRelic.addHTTPHeadersTrackingFor(["Car","Music"]);
```

### [setMaxOfflineStorageSize](https://docs.newrelic.com/docs/mobile-monitoring/new-relic-mobile/mobile-sdk/set-max-offline-storage/)() : void;
> Sets the maximum size of total data that can be stored for offline storage.By default, mobile monitoring can collect a maximum of 100 megaBytes of offline storage. When a data payload fails to send because the device doesn't have an internet connection, it can be stored in the file system until an internet connection has been made. After a typical harvest payload has been successfully sent, all offline data is sent to New Relic and cleared from storage.
```js
NewRelic.setMaxOfflineStorageSize(200);
```


## How to see JSErrors(Fatal/Non Fatal) in NewRelic One?

### React Native Agent v1.2.0 and above:
Expand Down
2 changes: 2 additions & 0 deletions __mocks__/nrm-modular-agent.js
Expand Up @@ -38,6 +38,8 @@ export default {
recordHandledException:jest.fn(),
shutdown:jest.fn(),
addHTTPHeadersTrackingFor:jest.fn(),
setMaxOfflineStorageSize: jest.fn(),


isAgentStarted: (name, callback) => {
callback(true);
Expand Down
12 changes: 12 additions & 0 deletions android/src/main/java/com/NewRelic/NRMModularAgentModule.java
Expand Up @@ -97,6 +97,13 @@ public void startAgent(String appKey, String agentVersion, String reactNativeVer
NewRelic.disableFeature(FeatureFlag.FedRampEnabled);
}

// Add condition for offlineStorage flag
if ((Boolean) agentConfig.get("offlineStorageEnabled")) {
NewRelic.enableFeature(FeatureFlag.OfflineStorage);
} else {
NewRelic.disableFeature(FeatureFlag.OfflineStorage);
}

if ((Boolean) agentConfig.get("nativeCrashReportingEnabled")) {
NewRelic.enableFeature(FeatureFlag.NativeReporting);
} else {
Expand Down Expand Up @@ -318,6 +325,11 @@ public void setMaxEventBufferTime(int maxEventBufferTimeInSeconds) {
NewRelic.setMaxEventBufferTime(maxEventBufferTimeInSeconds);
}

@ReactMethod
public void setMaxOfflineStorageSize(int megaBytes) {
NewRelic.setMaxOfflineStorageSize(megaBytes);
}

@ReactMethod
public void setMaxEventPoolSize(int maxSize) {
NewRelic.setMaxEventPoolSize(maxSize);
Expand Down
13 changes: 12 additions & 1 deletion index.js
Expand Up @@ -46,7 +46,8 @@ class NewRelic {
webViewInstrumentation: true,
collectorAddress: "",
crashCollectorAddress: "",
fedRampEnabled: false
fedRampEnabled: false,
offlineStorageEnabled: true
};
}

Expand Down Expand Up @@ -363,6 +364,16 @@ class NewRelic {
this.NRMAModularAgentWrapper.execute('setMaxEventPoolSize', maxSize);
}

/**
* Sets the maximum size of total data that can be stored for offline storage.By default, mobile monitoring can collect a maximum of 100 megaBytes of offline storage.
* When a data payload fails to send because the device doesn't have an internet connection, it can be stored in the file system until an internet connection has been made.
* After a typical harvest payload has been successfully sent, all offline data is sent to New Relic and cleared from storage.
* @param megaBytes {number} Maximum size in megaBytes that can be stored in the file system..
*/
setMaxOfflineStorageSize(megaBytes) {
this.NRMAModularAgentWrapper.execute('setMaxOfflineStorageSize', megaBytes);
}

/**
* Track a method as an interaction
*/
Expand Down
13 changes: 11 additions & 2 deletions ios/bridge/NRMModularAgent.m
Expand Up @@ -62,7 +62,11 @@ - (dispatch_queue_t)methodQueue{
if ([[agentConfig objectForKey:@"interactionTracingEnabled"]boolValue] == NO) {
[NewRelic disableFeatures:NRFeatureFlag_InteractionTracing];
}


if ([[agentConfig objectForKey:@"offlineStorageEnabled"] boolValue] == NO) {
[NewRelic disableFeatures:NRFeatureFlag_OfflineStorage];
}

if ([[agentConfig objectForKey:@"fedRampEnabled"]boolValue] == YES) {
[NewRelic enableFeatures:NRFeatureFlag_FedRampEnabled];
}
Expand Down Expand Up @@ -115,7 +119,7 @@ - (dispatch_queue_t)methodQueue{
[NewRelic setAttribute:@"React Native Version" value:reactNativeVersion];

resolve(@(TRUE));
}
}


RCT_EXPORT_METHOD(isAgentStarted:(NSString* _Nonnull)call
Expand Down Expand Up @@ -254,6 +258,11 @@ - (dispatch_queue_t)methodQueue{
[NewRelic setMaxEventBufferTime:uint_seconds];
}

RCT_EXPORT_METHOD(setMaxOfflineStorageSize:(NSNumber* _Nonnull)megaBytes) {
unsigned int uint_megaBytes = megaBytes.unsignedIntValue;
[NewRelic setMaxOfflineStorageSize:uint_megaBytes];
}

RCT_EXPORT_METHOD(setMaxEventPoolSize:(NSNumber* _Nonnull)maxSize) {
unsigned int uint_maxSize = maxSize.unsignedIntValue;
[NewRelic setMaxEventPoolSize:uint_maxSize];
Expand Down
23 changes: 22 additions & 1 deletion new-relic/__tests__/new-relic.spec.js
Expand Up @@ -84,6 +84,7 @@ describe('New Relic', () => {
expect(NewRelic.agentConfiguration.crashCollectorAddress).toBe("");
expect(NewRelic.agentConfiguration.fedRampEnabled).toBe(false);
expect(NewRelic.agentConfiguration.nativeCrashReportingEnabled).toBe(true);
expect(NewRelic.agentConfiguration.offlineStorageEnabled).toBe(true);

});

Expand All @@ -100,7 +101,9 @@ describe('New Relic', () => {
webViewInstrumentation: false,
collectorAddress: "gov-mobile-collector.newrelic.com",
crashCollectorAddress: "gov-mobile-crash.newrelic.com",
fedRampEnabled: true
fedRampEnabled: true,
nativeCrashReportingEnabled:false,
offlineStorageEnabled:false
};

NewRelic.startAgent("12345", customerConfiguration);
Expand All @@ -117,6 +120,9 @@ describe('New Relic', () => {
expect(NewRelic.agentConfiguration.collectorAddress).toBe("gov-mobile-collector.newrelic.com");
expect(NewRelic.agentConfiguration.crashCollectorAddress).toBe("gov-mobile-crash.newrelic.com");
expect(NewRelic.agentConfiguration.fedRampEnabled).toBe(true);
expect(NewRelic.agentConfiguration.offlineStorageEnabled).toBe(false);
expect(NewRelic.agentConfiguration.nativeCrashReportingEnabled).toBe(false);

});

it('should set the analytics event flag', () => {
Expand Down Expand Up @@ -276,6 +282,21 @@ describe('New Relic', () => {
expect(MockNRM.setMaxEventPoolSize.mock.calls.length).toBe(1);
});

it('should set max offline storage size', () => {
NewRelic.setMaxOfflineStorageSize(100);
expect(MockNRM.setMaxOfflineStorageSize.mock.calls.length).toBe(1);
expect(MockNRM.setMaxOfflineStorageSize.mock.calls[0][0]).toBe(100);
});

it('should not set max offline storage size with invalid size', () => {
NewRelic.setMaxOfflineStorageSize(null);
NewRelic.setMaxOfflineStorageSize('100');
NewRelic.setMaxOfflineStorageSize(true);
NewRelic.setMaxOfflineStorageSize(-100);

expect(MockNRM.setMaxOfflineStorageSize.mock.calls.length).toBe(4);
});

it('should set a valid Attribute', () => {
NewRelic.setAttribute('eventType', 'eventName');
NewRelic.setAttribute('eventType', 123);
Expand Down
5 changes: 5 additions & 0 deletions new-relic/nrma-modular-agent-wrapper.js
Expand Up @@ -137,6 +137,11 @@ class NRMAModularAgentWrapper {
setMaxEventPoolSize = (maxSize) => {
NRMModularAgent.setMaxEventPoolSize(maxSize);
};

setMaxOfflineStorageSize = (megaBytes) => {
NRMModularAgent.setMaxOfflineStorageSize(megaBytes);
};


setAttribute = (attributeName, value) => {
const attribute = new Attribute({ attributeName, value });
Expand Down
6 changes: 3 additions & 3 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "newrelic-react-native-agent",
"version": "1.3.5",
"version": "1.3.6",
"description": "A New Relic Mobile Agent for React Native",
"main": "./index.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -92,10 +92,10 @@
},
"sdkVersions": {
"ios": {
"newrelic": "7.4.8"
"newrelic": "7.4.9"
},
"android": {
"newrelic": "7.2.0",
"newrelic": "7.3.0",
"ndk": "1.0.4"
}
}
Expand Down

0 comments on commit 4a1a4f7

Please sign in to comment.