Skip to content

Commit

Permalink
release 1.0.6 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ndesai-newrelic committed Dec 19, 2023
1 parent 95c9bb0 commit 37fff4a
Show file tree
Hide file tree
Showing 15 changed files with 161 additions and 56 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 1.0.6

* Adds configurable request header instrumentation to network events
The agent will now produce network event attributes for select header values if the headers are detected on the request. The header names to instrument are passed into the agent when started.
* Updated the native Android agent to version 7.2.0.
* Updated the native iOS agent to version 7.4.8.

## 1.0.5

* Fixed issue in Flutter agent causing appbuild and appversion fields to overwrite for iOS mobile-handled exceptions.
Expand Down
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Install NewRelic plugin into your dart project by adding it to dependecies in yo
```yaml

dependencies:
newrelic_mobile: 1.0.5
newrelic_mobile: 1.0.6

```

Expand Down Expand Up @@ -203,7 +203,7 @@ final router = GoRouter(
}
dependencies {
...
classpath "com.newrelic.agent.android:agent-gradle-plugin:7.1.0"
classpath "com.newrelic.agent.android:agent-gradle-plugin:7.2.0"
}
}
```
Expand Down Expand Up @@ -353,6 +353,18 @@ or [Android SDK](https://docs.newrelic.com/docs/mobile-monitoring/new-relic-mobi
NewrelicMobile.instance.incrementAttribute("FlutterCustomAttrNumber",value :5.0);
```

### [shutdown](https://docs.newrelic.com/docs/mobile-monitoring/new-relic-mobile-android/android-sdk-api/shut-down/)() : void;
> Shut down the agent within the current application lifecycle during runtime.
```dart
NewrelicMobile.instance.shutdown();
```
### [shutdown](https://docs.newrelic.com/docs/mobile-monitoring/new-relic-mobile/mobile-sdk/add-tracked-headers/)() : void;
> This API allows you to add any header field strings to a list that gets recorded as attributes with networking request events. After header fields have been added using this function, if the headers are in a network call they will be included in networking events in NR1.
```dart
NewrelicMobile.instance.addHTTPHeadersTrackingFor(["Car","Music"]);
```


## Manual Error reporting

You can register non fatal exceptions using the following method with Custom Attributes:
Expand Down
8 changes: 7 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ android {
if (agpVersion >= 7) {
namespace "com.newrelic.newrelic_mobile"
}

defaultConfig {
minSdkVersion 24
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
Expand All @@ -55,6 +59,8 @@ android {

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.newrelic.agent.android:android-agent:7.0.0'
implementation 'com.newrelic.agent.android:android-agent:7.2.0'
// implementation "com.newrelic.agent.android:agent-ndk:1.0.4"


}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.os.Build
import androidx.annotation.NonNull
import com.newrelic.agent.android.ApplicationFramework
import com.newrelic.agent.android.FeatureFlag
import com.newrelic.agent.android.HttpHeaders
import com.newrelic.agent.android.NewRelic
import com.newrelic.agent.android.metric.MetricUnit
import com.newrelic.agent.android.stats.StatsEngine
Expand Down Expand Up @@ -93,9 +94,9 @@ class NewrelicMobilePlugin : FlutterPlugin, MethodCallHandler {
applicationToken
).withLoggingEnabled(loggingEnabled!!)
.withLogLevel(5)
.withApplicationFramework(ApplicationFramework.Flutter, "1.0.5").start(context)
.withApplicationFramework(ApplicationFramework.Flutter, "1.0.6").start(context)
NewRelic.setAttribute("DartVersion", dartVersion)
StatsEngine.get().inc("Supportability/Mobile/Android/Flutter/Agent/1.0.5");
StatsEngine.get().inc("Supportability/Mobile/Android/Flutter/Agent/1.0.6");
result.success("Agent Started")
}
"setUserId" -> {
Expand Down Expand Up @@ -149,7 +150,7 @@ class NewrelicMobilePlugin : FlutterPlugin, MethodCallHandler {
}
}
val eventRecorded =
NewRelic.recordCustomEvent(eventType, eventName, eventAttributes);
NewRelic.recordCustomEvent(eventType, eventName, eventAttributes)
result.success(eventRecorded)
}
"startInteraction" -> {
Expand Down Expand Up @@ -213,6 +214,8 @@ class NewrelicMobilePlugin : FlutterPlugin, MethodCallHandler {
val bytesReceived: Long = call.argument("bytesReceived")!!
val responseBody: String? = call.argument("responseBody")!!
val traceAttributes: HashMap<String, Any>? = call.argument("traceAttributes")
val params: HashMap<String, String>? = call.argument("params")


NewRelic.noticeHttpTransaction(
url,
Expand All @@ -223,11 +226,11 @@ class NewrelicMobilePlugin : FlutterPlugin, MethodCallHandler {
bytesSent,
bytesReceived,
responseBody,
null,
params,
null,
traceAttributes
)
result.success("Http Transcation Recorded")
result.success("Http Transaction Recorded")

}
"noticeNetworkFailure" -> {
Expand Down Expand Up @@ -318,6 +321,13 @@ class NewrelicMobilePlugin : FlutterPlugin, MethodCallHandler {
"currentSessionId" -> {
result.success(NewRelic.currentSessionId())
}
"addHTTPHeadersTrackingFor" -> {
val headers: ArrayList<String>? = call.argument("headers") as ArrayList<String>?
result.success(NewRelic.addHTTPHeadersTrackingFor(headers))
}
"getHTTPHeadersTrackingFor" -> {
result.success(HttpHeaders.getInstance().httpHeaders.toList())
}
else -> {
result.notImplemented()
}
Expand Down
2 changes: 1 addition & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.newrelic.newrelic_mobile_example"
minSdkVersion flutter.minSdkVersion
minSdkVersion 24
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
Expand Down
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.newrelic.agent.android:agent-gradle-plugin:7.1.0'
classpath 'com.newrelic.agent.android:agent-gradle-plugin:7.2.0'
}
}

Expand Down
6 changes: 3 additions & 3 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6P59W973U9;
DEVELOPMENT_TEAM = SU7SUNGZJP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand Down Expand Up @@ -475,7 +475,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6P59W973U9;
DEVELOPMENT_TEAM = SU7SUNGZJP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -498,7 +498,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6P59W973U9;
DEVELOPMENT_TEAM = SU7SUNGZJP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand Down
6 changes: 5 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ void main() {
});
NewrelicMobile.instance.setMaxEventPoolSize(3000);
NewrelicMobile.instance.setMaxEventBufferTime(200);
NewrelicMobile.instance.addHTTPHeadersTrackingFor(["Car","Music"]);
}

/// The main app.
Expand Down Expand Up @@ -141,6 +142,7 @@ class Page1Screen extends StatelessWidget {
"https://8f1d-2600-1006-b003-7627-ca1-491c-9b0-25ff.ngrok.io/notice_error"));
request.headers.set(HttpHeaders.contentTypeHeader,
"application/json; charset=UTF-8");
request.headers.set("Car", "Honda");
request.headers.set("ngrok-skip-browser-warning", 69420);
request.write(
'{"title": "Foo","body": "Bar", "userId": 99}');
Expand All @@ -158,7 +160,8 @@ class Page1Screen extends StatelessWidget {
final client = HttpClient();
var uri = Uri.parse("http://graph.facebook.com/");
var request = await client.getUrl(uri);
request.followRedirects = false;
request.headers.set("Car", "BMW");
// request.followRedirects = false;
var response = await request.close();

// var url = Uri.parse(
Expand All @@ -173,6 +176,7 @@ class Page1Screen extends StatelessWidget {
onPressed: () async {
try {
var dio = Dio();
dio.options.headers['Car'] = 'Toyota';
dio.options.followRedirects = false;
var response =
await dio.get('http://graph.facebook.com/');
Expand Down
10 changes: 10 additions & 0 deletions ios/Classes/SwiftNewrelicMobilePlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,16 @@ public class SwiftNewrelicMobilePlugin: NSObject, FlutterPlugin {
case "noticeDistributedTrace":

result(NewRelic.generateDistributedTracingHeaders())

case "addHTTPHeadersTrackingFor":

let headers = args!["headers"] as! [String]
NewRelic.addHTTPHeaderTracking(for: headers)
result("headers added")

case "getHTTPHeadersTrackingFor":

result([])

case "noticeHttpTransaction":

Expand Down
4 changes: 2 additions & 2 deletions ios/newrelic_mobile.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#
Pod::Spec.new do |s|
s.name = 'newrelic_mobile'
s.version = '1.0.5'
s.version = '1.0.6'
s.summary = 'Flutter plugin for NewRelic Mobile.'
s.description = <<-DESC
Flutter plugin for NewRelic Mobile.
Expand All @@ -22,7 +22,7 @@ Flutter plugin for NewRelic Mobile.
s.dependency 'Flutter'
s.platform = :ios, '9.0'

s.dependency 'NewRelicAgent', '7.4.7'
s.dependency 'NewRelicAgent', '7.4.8'

# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
Expand Down
34 changes: 27 additions & 7 deletions lib/newrelic_http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ Future<NewRelicHttpClientRequest> _wrapRequest(
Map<String, dynamic> traceAttributes =
await NewrelicMobile.instance.noticeDistributedTrace({});

Map<String, dynamic> params = Map();



return request.then((actualRequest) {
actualRequest.headers
.add(DTTraceTags.traceState, traceAttributes[DTTraceTags.traceState]);
Expand All @@ -192,35 +196,49 @@ Future<NewRelicHttpClientRequest> _wrapRequest(
return request as Future<NewRelicHttpClientRequest>;
}




return Future.value(
NewRelicHttpClientRequest(actualRequest, timestamp, traceAttributes));
NewRelicHttpClientRequest(actualRequest, timestamp, traceAttributes,params));
}, onError: (dynamic err) {
NewrelicMobile.instance.recordError(err, StackTrace.current);
throw err;
});
}

NewRelicHttpClientResponse _wrapResponse(HttpClientResponse response,
HttpClientRequest request, int timestamp, Map<String, dynamic> traceData) {
Future<NewRelicHttpClientResponse> _wrapResponse(HttpClientResponse response,
HttpClientRequest request, int timestamp, Map<String, dynamic> traceData) async {
if (response is NewRelicHttpClientResponse) {
return response;
}

return NewRelicHttpClientResponse(response, request, timestamp, traceData);
dynamic headersList = await NewrelicMobile.instance.getHTTPHeadersTrackingFor();
Map<String,String> params = Map();

for(String header in headersList) {
if(request.headers.value(header) != null) {
params.putIfAbsent(header, () => request.headers.value(header)!);
}
}

return NewRelicHttpClientResponse(response, request, timestamp, traceData,params: params);
}

class NewRelicHttpClientRequest extends HttpClientRequest {
final int timestamp;
final HttpClientRequest _httpClientRequest;
StringBuffer? _sendBuffer = StringBuffer();
Map<String, dynamic> traceData;
Map<String, dynamic>? params;


NewRelicHttpClientRequest(
this._httpClientRequest, this.timestamp, this.traceData) {
this._httpClientRequest, this.timestamp, this.traceData,[this.params]) {
var request = this;
request.done.then((value) {
var response =
_wrapResponse(value, request, this.timestamp, this.traceData);
_wrapResponse(value, request, this.timestamp, this.traceData,);
return response;
}, onError: (dynamic err) {
NewrelicMobile.instance.recordError(err, StackTrace.current);
Expand Down Expand Up @@ -376,9 +394,10 @@ class NewRelicHttpClientResponse extends HttpClientResponse {
StringBuffer? _receiveBuffer = StringBuffer();
String? responseData;
dynamic traceData;
dynamic params;

NewRelicHttpClientResponse(
this._httpClientResponse, this.request, this.timestamp, this.traceData) {
this._httpClientResponse, this.request, this.timestamp, this.traceData,{this.params}) {
_wrapperStream = _readAndRecreateStream(_httpClientResponse);
}

Expand Down Expand Up @@ -416,6 +435,7 @@ class NewRelicHttpClientResponse extends HttpClientResponse {
request.contentLength,
_httpClientResponse.contentLength,
traceData,
httpParams: params,
responseBody: responseData ?? '');
}

Expand Down
20 changes: 17 additions & 3 deletions lib/newrelic_mobile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class NewrelicMobile {
await NewrelicMobile.instance.startAgent(config);
runApp();
await NewrelicMobile.instance
.setAttribute("Flutter Agent Version", "1.0.5");
.setAttribute("Flutter Agent Version", "1.0.6");
}, (Object error, StackTrace stackTrace) {
NewrelicMobile.instance.recordError(error, stackTrace);
FlutterError.presentError(
Expand Down Expand Up @@ -216,6 +216,18 @@ class NewrelicMobile {
return interactionId;
}

void addHTTPHeadersTrackingFor(List<String> headers) async {
final Map<String, List<String>> params = <String, List<String>>{
'headers': headers
};

await _channel.invokeMethod('addHTTPHeadersTrackingFor', params);
}

Future<dynamic> getHTTPHeadersTrackingFor() async {
return await _channel.invokeMethod('getHTTPHeadersTrackingFor');
}

Future<Map<String, dynamic>> noticeDistributedTrace(
Map<String, dynamic> requestAttributes) async {
final dynamic traceAttributes =
Expand Down Expand Up @@ -267,7 +279,8 @@ class NewrelicMobile {
int bytesSent,
int bytesReceived,
Map<String, dynamic>? traceData,
{String responseBody = ""}) async {
{Map<String, dynamic>? httpParams,
String responseBody = ""}) async {
Map<String, dynamic>? traceAttributes;
if (traceData != null) {
if (PlatformManager.instance.isAndroid()) {
Expand All @@ -294,7 +307,8 @@ class NewrelicMobile {
'bytesSent': bytesSent != -1 ? bytesSent : 0,
'bytesReceived': bytesReceived != -1 ? bytesReceived : 0,
'responseBody': responseBody,
'traceAttributes': traceAttributes
'traceAttributes': traceAttributes,
'params':httpParams
};
return await _channel.invokeMethod('noticeHttpTransaction', params);
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: newrelic_mobile
description: Flutter plugin for NewRelic Mobile. This plugin allows you to instrument Flutter apps with help of native New Relic Android and iOS agents.
version: 1.0.5
version: 1.0.6

homepage: https://github.com/newrelic/newrelic-flutter-agent

Expand Down
Loading

0 comments on commit 37fff4a

Please sign in to comment.