Skip to content

Commit

Permalink
Merge pull request #201 from Instabug/feature/apm
Browse files Browse the repository at this point in the history
  • Loading branch information
bsameh-at-instabug authored Sep 14, 2021
2 parents 77fce9d + c623ff4 commit a542b26
Show file tree
Hide file tree
Showing 26 changed files with 1,045 additions and 69 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:

flutter_tests:
docker:
- image: cirrusci/flutter
- image: cirrusci/flutter:2.2.3
steps:
- checkout
- run: sudo gem install bundler:1.16.1
Expand Down
28 changes: 28 additions & 0 deletions .github/issue_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!--
Please fill in the template below when creating an issue
to help us reproduce it and fix it faster.
While not required, including a sample project that reproduces
your issue will help us a lot.
-->

### Steps to Reproduce the Problem

### Expected Behavior

### Actual Behavior

### Instabug integration code
<!--Make sure to remove your app token.-->

### SDK Version
<!--Which version of Instabug Flutter are you on?.-->

### Flutter, iOS and Android Versions

### Device Model
<!--If this issue is happening on specific devices, please mention them.-->

### [Optional] Project That Reproduces the Issue
<!--While not required, providing a sample project that reproduces the issue you're having will help us solve it much faster.-->

5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## v10.8.0 (2021-09-13)

* Introduces Instabug's new App Performance Monitoring (APM)


## v10.0.1 (2021-08-25)

* Fixes an issue with http client logger.
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.5.4'
}
}

Expand All @@ -34,6 +34,6 @@ android {
}
}
dependencies {
implementation 'com.instabug.library:instabug:10.8.1'
implementation 'com.instabug.library:instabug:10.9.0'
testImplementation 'junit:junit:4.12'
}
5 changes: 5 additions & 0 deletions android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.instabug.library.InstabugCustomTextPlaceHolder;
import com.instabug.library.extendedbugreport.ExtendedBugReport;
import com.instabug.library.visualusersteps.State;
import com.instabug.apm.model.LogLevel;

import java.util.HashMap;
import java.util.Locale;
Expand Down Expand Up @@ -60,6 +61,7 @@ final class ArgsRegistry {
registerInstabugExtendedBugReportModeArgs(ARGS);
registerInstabugActionTypesArgs(ARGS);
registerReproStepsModeArgs(ARGS);
registerLogLevelArgs(ARGS);
}

/**
Expand Down Expand Up @@ -217,4 +219,13 @@ static void registerReproStepsModeArgs(Map<String, Object> args) {
args.put("ReproStepsMode.enabledWithNoScreenshots",State.ENABLED_WITH_NO_SCREENSHOTS);
}

static void registerLogLevelArgs(Map<String, Object> args) {
args.put("logLevelNone", LogLevel.NONE);
args.put("logLevelError", LogLevel.ERROR);
args.put("logLevelWarning", LogLevel.WARNING);
args.put("logLevelInfo", LogLevel.INFO);
args.put("logLevelDebug", LogLevel.DEBUG);
args.put("logLevelVerbose", LogLevel.VERBOSE);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import android.os.Looper;
import android.util.Log;

import com.instabug.apm.APM;
import com.instabug.apm.model.ExecutionTrace;
import com.instabug.apm.networking.APMNetworkLogger;
import com.instabug.bug.BugReporting;
import com.instabug.bug.invocation.Option;
import com.instabug.chat.Chats;
Expand Down Expand Up @@ -64,6 +67,7 @@ public class InstabugFlutterPlugin implements MethodCallHandler {
final public static String INVOCATION_EVENT_SHAKE = "InvocationEvent.shake";

private InstabugCustomTextPlaceHolder placeHolder = new InstabugCustomTextPlaceHolder();
HashMap<String, ExecutionTrace> traces = new HashMap<String, ExecutionTrace>();

static MethodChannel channel;

Expand Down Expand Up @@ -106,14 +110,14 @@ public void onMethodCall(MethodCall call, Result result) {
}
}

private void setCrossPlatform() {
private void setCurrentPlatform() {
try {
Method method = getMethod(Class.forName("com.instabug.library.Instabug"), "setCrossPlatform", int.class);
Method method = getMethod(Class.forName("com.instabug.library.Instabug"), "setCurrentPlatform", int.class);
if (method != null) {
Log.i("IB-CP-Bridge", "invoking setCrossPlatform with platform: " + Platform.FLUTTER);
Log.i("IB-CP-Bridge", "invoking setCurrentPlatform with platform: " + Platform.FLUTTER);
method.invoke(null, Platform.FLUTTER);
} else {
Log.e("IB-CP-Bridge", "setCrossPlatform was not found by reflection");
Log.e("IB-CP-Bridge", "setCurrentPlatform was not found by reflection");
}
} catch (Exception e) {
e.printStackTrace();
Expand All @@ -129,7 +133,7 @@ private void setCrossPlatform() {
* @param invocationEvents invocationEvents The events that invoke the SDK's UI.
*/
public void start(Application application, String token, ArrayList<String> invocationEvents) {
setCrossPlatform();
setCurrentPlatform();
InstabugInvocationEvent[] invocationEventsArray = new InstabugInvocationEvent[invocationEvents.size()];
for (int i = 0; i < invocationEvents.size(); i++) {
String key = invocationEvents.get(i);
Expand All @@ -138,8 +142,6 @@ public void start(Application application, String token, ArrayList<String> invoc
new Instabug.Builder(application, token).setInvocationEvents(invocationEventsArray).build();
enableScreenShotByMediaProjection();

// Temporarily disabling APM
APM.setEnabled(false);
}

/**
Expand Down Expand Up @@ -422,6 +424,15 @@ public void setSessionProfilerEnabled(boolean sessionProfilerEnabled) {
}
}

/**
* Enable/disable SDK logs
*
* @param debugEnabled desired state of debug mode
*/
public void setDebugEnabled(boolean debugEnabled) {
Instabug.setDebugEnabled(debugEnabled);
}

/**
* Set the primary color that the SDK will use to tint certain UI elements in
* the SDK
Expand Down Expand Up @@ -897,7 +908,7 @@ public void networkLog(HashMap<String, Object> jsonObject) throws JSONException
(new JSONObject((HashMap<String, String>) jsonObject.get("requestHeaders"))).toString(4));
networkLog.setResponseHeaders(
(new JSONObject((HashMap<String, String>) jsonObject.get("responseHeaders"))).toString(4));
networkLog.setTotalDuration(((Number) jsonObject.get("duration")).longValue());
networkLog.setTotalDuration(((Number) jsonObject.get("duration")).longValue() / 1000);
networkLog.insert();
}

Expand Down Expand Up @@ -938,6 +949,211 @@ public void run() {
});
}

/**
* Enables and disables everything related to APM feature.
*
* @param {boolean} isEnabled
*/
public void setAPMEnabled(final boolean isEnabled) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
APM.setEnabled(isEnabled);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Sets the printed logs priority. Filter to one of the following levels.
*
* @param {String} logLevel.
*/
public void setAPMLogLevel(final String logLevel) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
if (ArgsRegistry.getDeserializedValue(logLevel, Integer.class) == null) {
return;
}
APM.setLogLevel((int) ArgsRegistry.getRawValue(logLevel));
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Enables or disables cold app launch tracking.
* @param isEnabled boolean indicating enabled or disabled.
*/
public void setColdAppLaunchEnabled(final boolean isEnabled) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
APM.setAppLaunchEnabled(isEnabled);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Starts an execution trace
* @param name string name of the trace.
*/
public void startExecutionTrace(final String name, final String id) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
String result = null;
ExecutionTrace trace = APM.startExecutionTrace(name);
if (trace != null) {
result = id;
traces.put(id, trace);
}
channel.invokeMethod("startExecutionTraceCallBack", result);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Sets an execution trace attribute
* @param id string id of the trace.
* @param key string key of the attribute.
* @param value string value of the attribute.
*/
public void setExecutionTraceAttribute(final String id, final String key, final String value) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
traces.get(id).setAttribute(key, value);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Ends an execution trace
* @param id string id of the trace.
*/
public void endExecutionTrace(final String id) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
traces.get(id).end();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Enables or disables auto UI tracing
* @param isEnabled boolean indicating enabled or disabled.
*/
public void setAutoUITraceEnabled(final boolean isEnabled) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
APM.setAutoUITraceEnabled(isEnabled);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Starts a UI trace
* @param name string name of the UI trace.
*/
public void startUITrace(final String name) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
APM.startUITrace(name);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Ends the current running UI trace
*/
public void endUITrace() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
APM.endUITrace();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

public void apmNetworkLogByReflection(HashMap<String, Object> jsonObject) throws JSONException {
APMNetworkLogger apmNetworkLogger = new APMNetworkLogger();
final String requestUrl = (String) jsonObject.get("url");
final String requestBody = (String) jsonObject.get("requestBody");
final String responseBody = (String) jsonObject.get("responseBody");
final String requestMethod = (String) jsonObject.get("method");
//--------------------------------------------
final String requestContentType = (String) jsonObject.get("contentType");
final String responseContentType = (String) jsonObject.get("responseContentType");
//--------------------------------------------
final String errorDomain = (String) jsonObject.get("errorDomain");
final Integer statusCode = (Integer) jsonObject.get("responseCode");
final long requestDuration = ((Number) jsonObject.get("duration")).longValue() / 1000;
final long requestStartTime = ((Number) jsonObject.get("startTime")).longValue() * 1000;
final String requestHeaders = (new JSONObject((HashMap<String, String>) jsonObject.get("requestHeaders"))).toString(4);
final String responseHeaders = (new JSONObject((HashMap<String, String>) jsonObject.get("responseHeaders"))).toString(4);
final String errorMessage;

if(errorDomain.equals("")) {
errorMessage = null;
} else {
errorMessage = errorDomain;
}

try {
Method method = getMethod(Class.forName("com.instabug.apm.networking.APMNetworkLogger"), "log", long.class, long.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, int.class, String.class, String.class);
if (method != null) {
method.invoke(apmNetworkLogger, requestStartTime, requestDuration, requestHeaders, requestBody, requestMethod, requestUrl, requestContentType, responseHeaders, responseBody, statusCode, responseContentType, errorMessage);
} else {
Log.e("IB-CP-Bridge", "apmNetworkLogByReflection was not found by reflection");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

}

/*
*
* Reports that the screen has been
Expand Down
Loading

0 comments on commit a542b26

Please sign in to comment.