Skip to content

Commit

Permalink
feat: log Forwarding and ANR Reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
ndesai-newrelic committed Jul 26, 2024
1 parent 062a534 commit e60d501
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 48 deletions.
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
# Changelog

## 1.4.0
## New Features

1. Application Exit Information
- Added ApplicationExitInfo to data reporting
- Enabled by default

2. Log Forwarding to New Relic
- Implement static API for sending logs to New Relic
- Can be enabled/disabled in your mobile application's entity settings page

## Improvements

- Native Android agent updated to version 7.5.0
- Native iOS agent updated to version 7.5.0

## 1.3.9

* Updated the native Android agent to version 7.3.1.



## 1.3.8

* Improvements
Expand Down
61 changes: 60 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ AppToken is platform-specific. You need to generate the seprate token for Androi
}
dependencies {
...
classpath "com.newrelic.agent.android:agent-gradle-plugin:7.3.1"
classpath "com.newrelic.agent.android:agent-gradle-plugin:7.5.0"
}
}
```
Expand Down Expand Up @@ -435,6 +435,65 @@ See the examples below, and for more detail, see [New Relic IOS SDK doc](https:/
NewRelic.setMaxOfflineStorageSize(200);
```
### logInfo(String message) : void
> Logs an informational message to the New Relic log.
``` js
NewRelic.logInfo();
```
### logError(String message) : void
> Logs an error message to the New Relic log.
``` js
NewRelic.logError("This is an error message");
```
### logVerbose(String message) : void
> Logs a verbose message to the New Relic log.
``` js
NewRelic.logVerbose("This is a verbose message");
```
### logWarning(String message) : void
> Logs a warning message to the New Relic log.
``` js
NewRelic.logWarning("This is a warning message");
```
### logDebug(String message) : void
> Logs a debug message to the New Relic log.
``` js
NewRelic.logDebug("This is a debug message");
```
### log(LogLevel level, String message) : void
> Logs a message to the New Relic log with a specified log level.
``` js
NewRelic.log(LogLevel.INFO, "This is an informational message");
```
### logAll(Error error,attributes?: {[key: string]: any}) : void
> Logs an exception with attributes to the New Relic log.
``` js
Newrelic.logAll(new Error("This is an exception"),
{"BreadNumValue": 12.3 ,
"BreadStrValue": "FlutterBread",
"BreadBoolValue": true ,
"message": "This is a message with attributes" }
);
```
### logAttributes(attributes?: {[key: string]: any}) : void
> Logs a message with attributes to the New Relic log.
``` js
Newrelic.logAttributes(
{"BreadNumValue": 12.3 ,
"BreadStrValue": "FlutterBread",
"BreadBoolValue": true ,
"message": "This is a message with attributes",
level:newRelic.LogLevel.INFO });
```
## How to see JSErrors(Fatal/Non Fatal) in NewRelic One?
Expand Down
15 changes: 9 additions & 6 deletions android/src/main/java/com/NewRelic/NRMModularAgentModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,12 @@ public void startAgent(String appKey, String agentVersion, String reactNativeVer
NewRelic.disableFeature(FeatureFlag.NativeReporting);
}

if ((Boolean) agentConfig.get("logReportingEnabled")) {
NewRelic.enableFeature(FeatureFlag.LogReporting);
if ((Boolean) agentConfig.get("backgroundReportingEnabled")) {
NewRelic.enableFeature(FeatureFlag.BackgroundReporting);
} else {
NewRelic.disableFeature(FeatureFlag.LogReporting);
NewRelic.disableFeature(FeatureFlag.BackgroundReporting);
}


Map<String, Integer> strToLogLevel = new HashMap<>();
strToLogLevel.put("ERROR", AgentLog.ERROR);
strToLogLevel.put("WARNING", AgentLog.WARN);
Expand All @@ -138,8 +137,7 @@ public void startAgent(String appKey, String agentVersion, String reactNativeVer
}
}

String configLogLevel = (String) agentConfig.get("logLevel");
LogReporting.setLogLevel(LogLevel.valueOf(configLogLevel));

boolean useDefaultCollectorAddress =
agentConfig.get("collectorAddress") == null ||
((String) agentConfig.get("collectorAddress")).isEmpty();
Expand Down Expand Up @@ -429,6 +427,11 @@ public void noticeHttpTransaction(String url, String method, int statusCode, int
NewRelic.noticeHttpTransaction(url, method, statusCode, startTime, endTime, bytesSent, bytesReceived, responseBody);
}

@ReactMethod
public void logAttributes(ReadableMap attributes) {
NewRelic.logAttributes(mapToAttributes(attributes));
}


@ReactMethod
public void recordStack(String errorName, String errorMessage, String errorStack, boolean isFatal, String jsAppVersion) {
Expand Down
54 changes: 27 additions & 27 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
* SPDX-License-Identifier: Apache-2.0
*/

import utils from './new-relic/nr-utils';
import {LOG} from './new-relic/nr-logger';
import utils from 'newrelic-react-native-agent/new-relic/nr-utils';
import {LOG} from 'newrelic-react-native-agent/new-relic/nr-logger';
import {Platform} from 'react-native';
import NRMAModularAgentWrapper from './new-relic/nrma-modular-agent-wrapper';
import version from './new-relic/version';
import NRMAModularAgentWrapper from 'newrelic-react-native-agent/new-relic/nrma-modular-agent-wrapper';
import version from 'newrelic-react-native-agent/new-relic/version';
import forEach from 'lodash.foreach';
import getCircularReplacer from './new-relic/circular-replacer';
import getCircularReplacer from 'newrelic-react-native-agent/new-relic/circular-replacer';

import {
getUnhandledPromiseRejectionTracker,
setUnhandledPromiseRejectionTracker,
} from 'react-native-promise-rejection-utils'
} from 'newrelic-react-native-agent/node_modules/react-native-promise-rejection-utils'


/**
Expand Down Expand Up @@ -48,7 +48,6 @@ class NewRelic {
crashCollectorAddress: "",
fedRampEnabled: false,
offlineStorageEnabled: true,
logReportingEnabled: true,
backgroundReportingEnabled: false,
newEventSystemEnabled: true
};
Expand All @@ -57,10 +56,11 @@ class NewRelic {
LogLevel = {
// ERROR is least verbose and AUDIT is most verbose
ERROR: "ERROR",
WARNING: "WARNING",
WARN: "WARN",
INFO: "INFO",
VERBOSE: "VERBOSE",
AUDIT: "AUDIT"
AUDIT: "AUDIT",
DEBUG: "DEBUG"
};

NetworkFailure = {
Expand Down Expand Up @@ -458,7 +458,7 @@ class NewRelic {
var attributes = {};
// Set the message and log level as attributes
attributes["message"] = message;
attributes["logLevel"] = logLevel;
attributes["level"] = logLevel;
// Log the attributes
this.logAttributes(attributes);
}
Expand Down Expand Up @@ -505,7 +505,7 @@ class NewRelic {
*
* @param {string} message - The warning message to be logged.
*/
logWarning(message) {
logWarn(message) {
this.log(this.LogLevel.WARN, message);
}

Expand Down Expand Up @@ -654,6 +654,13 @@ class NewRelic {
self.sendConsole('error', arguments);
defaultError.apply(console, arguments);
};

console.debug = function () {
self.sendConsole('debug', arguments);
defaultError.apply(console, arguments);
}


this.state.didOverrideConsole = true;
}
}
Expand All @@ -662,22 +669,15 @@ class NewRelic {
const argsStr = JSON.stringify(args, getCircularReplacer());

if(type === 'error') {
this.logError(argsStr);
} else if (type === 'warn') {
this.logWarning(argsStr);
} else {
this.logInfo(argsStr);
}
this.send('JSConsole', {consoleType: type, args: argsStr});
}

send(name, args) {
const nameStr = String(name);
const argsStr = {};
forEach(args, (value, key) => {
argsStr[String(key)] = String(value);
});
this.NRMAModularAgentWrapper.execute('recordCustomEvent', 'consoleEvents', nameStr, argsStr);
this.logError("[CONSOLE][ERROR]" + argsStr);
} else if (type === 'warn') {
this.logWarn("[CONSOLE][WARN]" +argsStr);
} else if (type === 'debug') {
this.logDebug("[CONSOLE][DEBUG]" +argsStr);
}else {
this.logInfo("[CONSOLE][LOG]" +argsStr);
}

}

}
Expand Down
2 changes: 1 addition & 1 deletion ios/bridge/NRMModularAgent.m
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ - (dispatch_queue_t)methodQueue{

RCT_EXPORT_METHOD(logAttributes:(NSDictionary* _Nullable)attributes)
{
[NewRelic logAll:attributes];
[NewRelic logAttributes:attributes];
}

RCT_EXPORT_METHOD(incrementAttribute:(NSString *)key withNumber:(NSNumber* _Nonnull)value) {
Expand Down
10 changes: 2 additions & 8 deletions new-relic/__tests__/new-relic.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ describe('New Relic', () => {
expect(NewRelic.agentConfiguration.fedRampEnabled).toBe(false);
expect(NewRelic.agentConfiguration.nativeCrashReportingEnabled).toBe(true);
expect(NewRelic.agentConfiguration.offlineStorageEnabled).toBe(true);
expect(NewRelic.agentConfiguration.logReportingEnabled).toBe(true);

expect(NewRelic.agentConfiguration.logReportingEnabled).toBe(true);

expect(NewRelic.agentConfiguration.newEventSystemEnabled).toBe(true);
expect(NewRelic.agentConfiguration.backgroundReportingEnabled).toBe(false);

Expand All @@ -110,7 +106,6 @@ describe('New Relic', () => {
fedRampEnabled: true,
nativeCrashReportingEnabled:false,
offlineStorageEnabled:false,
logReportingEnabled: false
newEventSystemEnabled:false,
backgroundReportingEnabled:true
};
Expand All @@ -131,7 +126,6 @@ describe('New Relic', () => {
expect(NewRelic.agentConfiguration.fedRampEnabled).toBe(true);
expect(NewRelic.agentConfiguration.offlineStorageEnabled).toBe(false);
expect(NewRelic.agentConfiguration.nativeCrashReportingEnabled).toBe(false);
expect(NewRelic.agentConfiguration.logReportingEnabled).toBe(false);
expect(NewRelic.agentConfiguration.newEventSystemEnabled).toBe(false);
expect(NewRelic.agentConfiguration.backgroundReportingEnabled).toBe(true);

Expand Down Expand Up @@ -422,7 +416,7 @@ describe('New Relic', () => {
// Each agent start call is 2 custom event calls (5 actual calls prior to this test) = 10
NewRelic.startAgent("12345");
console.log('hello');
expect(MockNRM.recordCustomEvent.mock.calls.length).toBe(15);
expect(MockNRM.recordCustomEvent.mock.calls.length).toBe(0);
});

it('sends console.warn to record custom Events', () => {
Expand All @@ -431,7 +425,7 @@ describe('New Relic', () => {
console.log('hello');
console.warn('hello');
console.error('hello');
expect(MockNRM.recordCustomEvent.mock.calls.length).toBe(30);
expect(MockNRM.recordCustomEvent.mock.calls.length).toBe(0);
});

it('sends breadcrumb for navigation if it is not first screen', () => {
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "newrelic-react-native-agent",
"version": "1.3.9",
"version": "1.4.0",
"description": "A New Relic Mobile Agent for React Native",
"main": "./index.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -92,11 +92,11 @@
},
"sdkVersions": {
"ios": {
"newrelic": "7.4.12"
"newrelic": "7.5.0"
},
"android": {
"newrelic": "7.3.1",
"ndk": "1.0.4"
"newrelic": "7.5.+",
"ndk": "1.1.+"
}
}
}

0 comments on commit e60d501

Please sign in to comment.