Skip to content

Commit e9484d9

Browse files
Ali Abdelfattahahmed1hisham
authored andcommitted
Feature/apm support (#7)
* Feature/apm support flutter (#6) * Add setEnabled API for APM * Add setColdAppLaunchEnabled API for APM * Add setAutoUITraceEnabled API for APM * Add support for APM Execution Traces metric * Add APIs that start and end UI trace * Add specs for APIs that start and end UI trace * Fix APM.setEnabled * Add setLogLevel API for APM * Fix iOS setLogLevel missing variable * Fix execution traces APIs * Update network logging to support APM for iOS * Fix network requests always getting logged as a failure * Fix APM null safety * Fix network logger responseHeaders population * Fix network data model * Add ignore static member warning * Add network logging for Android * Remove unwanted logs * Fix execution traces specs * Fix network log payload size for iOS * Fix InstabugCustomHttpClient request closing * Call setCurrentPlatform instead of setCrossPlatform * Adjust APM Network logger for other network libs * Add debugging log for apmNetworkLog * Undo comments in InstabugFlutterPlugin.java * Fix duration in Android bug reporting network logs * Remove commented code * Undo SDK versions Co-authored-by: Ahmed Hisham Rihan <[email protected]>
1 parent 77fce9d commit e9484d9

13 files changed

+877
-57
lines changed

android/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ android {
3131
}
3232
lintOptions {
3333
disable 'InvalidPackage'
34+
abortOnError false
3435
}
3536
}
3637
dependencies {

android/src/main/java/com/instabug/instabugflutter/ArgsRegistry.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.instabug.library.InstabugCustomTextPlaceHolder;
88
import com.instabug.library.extendedbugreport.ExtendedBugReport;
99
import com.instabug.library.visualusersteps.State;
10+
import com.instabug.apm.model.LogLevel;
1011

1112
import java.util.HashMap;
1213
import java.util.Locale;
@@ -60,6 +61,7 @@ final class ArgsRegistry {
6061
registerInstabugExtendedBugReportModeArgs(ARGS);
6162
registerInstabugActionTypesArgs(ARGS);
6263
registerReproStepsModeArgs(ARGS);
64+
registerLogLevelArgs(ARGS);
6365
}
6466

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

222+
static void registerLogLevelArgs(Map<String, Object> args) {
223+
args.put("logLevelNone", LogLevel.NONE);
224+
args.put("logLevelError", LogLevel.ERROR);
225+
args.put("logLevelWarning", LogLevel.WARNING);
226+
args.put("logLevelInfo", LogLevel.INFO);
227+
args.put("logLevelDebug", LogLevel.DEBUG);
228+
args.put("logLevelVerbose", LogLevel.VERBOSE);
229+
}
230+
220231
}

android/src/main/java/com/instabug/instabugflutter/InstabugFlutterPlugin.java

Lines changed: 215 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import android.os.Looper;
88
import android.util.Log;
99

10+
import com.instabug.apm.APM;
11+
import com.instabug.apm.model.ExecutionTrace;
12+
import com.instabug.apm.networking.APMNetworkLogger;
1013
import com.instabug.bug.BugReporting;
1114
import com.instabug.bug.invocation.Option;
1215
import com.instabug.chat.Chats;
@@ -64,6 +67,7 @@ public class InstabugFlutterPlugin implements MethodCallHandler {
6467
final public static String INVOCATION_EVENT_SHAKE = "InvocationEvent.shake";
6568

6669
private InstabugCustomTextPlaceHolder placeHolder = new InstabugCustomTextPlaceHolder();
70+
HashMap<String, ExecutionTrace> traces = new HashMap<String, ExecutionTrace>();
6771

6872
static MethodChannel channel;
6973

@@ -106,14 +110,14 @@ public void onMethodCall(MethodCall call, Result result) {
106110
}
107111
}
108112

109-
private void setCrossPlatform() {
113+
private void setCurrentPlatform() {
110114
try {
111-
Method method = getMethod(Class.forName("com.instabug.library.Instabug"), "setCrossPlatform", int.class);
115+
Method method = getMethod(Class.forName("com.instabug.library.Instabug"), "setCurrentPlatform", int.class);
112116
if (method != null) {
113-
Log.i("IB-CP-Bridge", "invoking setCrossPlatform with platform: " + Platform.FLUTTER);
117+
Log.i("IB-CP-Bridge", "invoking setCurrentPlatform with platform: " + Platform.FLUTTER);
114118
method.invoke(null, Platform.FLUTTER);
115119
} else {
116-
Log.e("IB-CP-Bridge", "setCrossPlatform was not found by reflection");
120+
Log.e("IB-CP-Bridge", "setCurrentPlatform was not found by reflection");
117121
}
118122
} catch (Exception e) {
119123
e.printStackTrace();
@@ -129,7 +133,7 @@ private void setCrossPlatform() {
129133
* @param invocationEvents invocationEvents The events that invoke the SDK's UI.
130134
*/
131135
public void start(Application application, String token, ArrayList<String> invocationEvents) {
132-
setCrossPlatform();
136+
setCurrentPlatform();
133137
InstabugInvocationEvent[] invocationEventsArray = new InstabugInvocationEvent[invocationEvents.size()];
134138
for (int i = 0; i < invocationEvents.size(); i++) {
135139
String key = invocationEvents.get(i);
@@ -897,7 +901,7 @@ public void networkLog(HashMap<String, Object> jsonObject) throws JSONException
897901
(new JSONObject((HashMap<String, String>) jsonObject.get("requestHeaders"))).toString(4));
898902
networkLog.setResponseHeaders(
899903
(new JSONObject((HashMap<String, String>) jsonObject.get("responseHeaders"))).toString(4));
900-
networkLog.setTotalDuration(((Number) jsonObject.get("duration")).longValue());
904+
networkLog.setTotalDuration(((Number) jsonObject.get("duration")).longValue() / 1000);
901905
networkLog.insert();
902906
}
903907

@@ -938,6 +942,211 @@ public void run() {
938942
});
939943
}
940944

945+
/**
946+
* Enables and disables everything related to APM feature.
947+
*
948+
* @param {boolean} isEnabled
949+
*/
950+
public void setAPMEnabled(final boolean isEnabled) {
951+
new Handler(Looper.getMainLooper()).post(new Runnable() {
952+
@Override
953+
public void run() {
954+
try {
955+
APM.setEnabled(isEnabled);
956+
} catch (Exception e) {
957+
e.printStackTrace();
958+
}
959+
}
960+
});
961+
}
962+
963+
/**
964+
* Sets the printed logs priority. Filter to one of the following levels.
965+
*
966+
* @param {String} logLevel.
967+
*/
968+
public void setAPMLogLevel(final String logLevel) {
969+
new Handler(Looper.getMainLooper()).post(new Runnable() {
970+
@Override
971+
public void run() {
972+
try {
973+
if (ArgsRegistry.getDeserializedValue(logLevel, Integer.class) == null) {
974+
return;
975+
}
976+
APM.setLogLevel((int) ArgsRegistry.getRawValue(logLevel));
977+
} catch (Exception e) {
978+
e.printStackTrace();
979+
}
980+
}
981+
});
982+
}
983+
984+
/**
985+
* Enables or disables cold app launch tracking.
986+
* @param isEnabled boolean indicating enabled or disabled.
987+
*/
988+
public void setColdAppLaunchEnabled(final boolean isEnabled) {
989+
new Handler(Looper.getMainLooper()).post(new Runnable() {
990+
@Override
991+
public void run() {
992+
try {
993+
APM.setAppLaunchEnabled(isEnabled);
994+
} catch (Exception e) {
995+
e.printStackTrace();
996+
}
997+
}
998+
});
999+
}
1000+
/**
1001+
* Starts an execution trace
1002+
* @param name string name of the trace.
1003+
*/
1004+
public void startExecutionTrace(final String name, final String id) {
1005+
new Handler(Looper.getMainLooper()).post(new Runnable() {
1006+
@Override
1007+
public void run() {
1008+
try {
1009+
String result = null;
1010+
ExecutionTrace trace = APM.startExecutionTrace(name);
1011+
if (trace != null) {
1012+
result = id;
1013+
traces.put(id, trace);
1014+
}
1015+
channel.invokeMethod("startExecutionTraceCallBack", result);
1016+
} catch (Exception e) {
1017+
e.printStackTrace();
1018+
}
1019+
}
1020+
});
1021+
}
1022+
1023+
/**
1024+
* Sets an execution trace attribute
1025+
* @param id string id of the trace.
1026+
* @param key string key of the attribute.
1027+
* @param value string value of the attribute.
1028+
*/
1029+
public void setExecutionTraceAttribute(final String id, final String key, final String value) {
1030+
new Handler(Looper.getMainLooper()).post(new Runnable() {
1031+
@Override
1032+
public void run() {
1033+
try {
1034+
traces.get(id).setAttribute(key, value);
1035+
} catch (Exception e) {
1036+
e.printStackTrace();
1037+
}
1038+
}
1039+
});
1040+
}
1041+
1042+
/**
1043+
* Ends an execution trace
1044+
* @param id string id of the trace.
1045+
*/
1046+
public void endExecutionTrace(final String id) {
1047+
new Handler(Looper.getMainLooper()).post(new Runnable() {
1048+
@Override
1049+
public void run() {
1050+
try {
1051+
traces.get(id).end();
1052+
} catch (Exception e) {
1053+
e.printStackTrace();
1054+
}
1055+
}
1056+
});
1057+
}
1058+
1059+
/**
1060+
* Enables or disables auto UI tracing
1061+
* @param isEnabled boolean indicating enabled or disabled.
1062+
*/
1063+
public void setAutoUITraceEnabled(final boolean isEnabled) {
1064+
new Handler(Looper.getMainLooper()).post(new Runnable() {
1065+
@Override
1066+
public void run() {
1067+
try {
1068+
APM.setAutoUITraceEnabled(isEnabled);
1069+
} catch (Exception e) {
1070+
e.printStackTrace();
1071+
}
1072+
}
1073+
});
1074+
}
1075+
1076+
/**
1077+
* Starts a UI trace
1078+
* @param name string name of the UI trace.
1079+
*/
1080+
public void startUITrace(final String name) {
1081+
new Handler(Looper.getMainLooper()).post(new Runnable() {
1082+
@Override
1083+
public void run() {
1084+
try {
1085+
APM.startUITrace(name);
1086+
} catch (Exception e) {
1087+
e.printStackTrace();
1088+
}
1089+
}
1090+
});
1091+
}
1092+
1093+
/**
1094+
* Ends the current running UI trace
1095+
*/
1096+
public void endUITrace() {
1097+
new Handler(Looper.getMainLooper()).post(new Runnable() {
1098+
@Override
1099+
public void run() {
1100+
try {
1101+
APM.endUITrace();
1102+
} catch (Exception e) {
1103+
e.printStackTrace();
1104+
}
1105+
}
1106+
});
1107+
}
1108+
1109+
public void apmNetworkLogByReflection(HashMap<String, Object> jsonObject) throws JSONException {
1110+
APMNetworkLogger apmNetworkLogger = new APMNetworkLogger();
1111+
final String requestUrl = (String) jsonObject.get("url");
1112+
final String requestBody = (String) jsonObject.get("requestBody");
1113+
final String responseBody = (String) jsonObject.get("responseBody");
1114+
final String requestMethod = (String) jsonObject.get("method");
1115+
//--------------------------------------------
1116+
final String requestContentType = (String) jsonObject.get("contentType");
1117+
final String responseContentType = (String) jsonObject.get("responseContentType");
1118+
//--------------------------------------------
1119+
final String errorDomain = (String) jsonObject.get("errorDomain");
1120+
final Integer statusCode = (Integer) jsonObject.get("responseCode");
1121+
final long requestDuration = ((Number) jsonObject.get("duration")).longValue() / 1000;
1122+
final long requestStartTime = ((Number) jsonObject.get("startTime")).longValue() * 1000;
1123+
final String requestHeaders = (new JSONObject((HashMap<String, String>) jsonObject.get("requestHeaders"))).toString(4);
1124+
final String responseHeaders = (new JSONObject((HashMap<String, String>) jsonObject.get("responseHeaders"))).toString(4);
1125+
final String errorMessage;
1126+
1127+
if(errorDomain.equals("")) {
1128+
errorMessage = null;
1129+
} else {
1130+
errorMessage = errorDomain;
1131+
}
1132+
1133+
try {
1134+
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);
1135+
if (method != null) {
1136+
method.invoke(apmNetworkLogger, requestStartTime, requestDuration, requestHeaders, requestBody, requestMethod, requestUrl, requestContentType, responseHeaders, responseBody, statusCode, responseContentType, errorMessage);
1137+
} else {
1138+
Log.e("IB-CP-Bridge", "apmNetworkLogByReflection was not found by reflection");
1139+
}
1140+
} catch (ClassNotFoundException e) {
1141+
e.printStackTrace();
1142+
} catch (IllegalAccessException e) {
1143+
e.printStackTrace();
1144+
} catch (InvocationTargetException e) {
1145+
e.printStackTrace();
1146+
}
1147+
1148+
}
1149+
9411150
/*
9421151
*
9431152
* Reports that the screen has been

ios/Classes/InstabugFlutterPlugin.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,4 +424,65 @@
424424

425425
+ (void)networkLog:(NSDictionary *)networkData;
426426

427+
/**
428+
* Enables and disables everything related to APM feature.
429+
* @param isEnabled isEnabled
430+
*/
431+
+ (void)setAPMEnabled:(NSNumber *)isEnabled;
432+
433+
/**
434+
* Sets the printed logs priority. Filter to one of the following levels:
435+
*
436+
* - logLevelNone disables all APM SDK console logs.
437+
*
438+
* - logLevelError prints errors only, we use this level to let you know if something goes wrong.
439+
*
440+
* - logLevelWarning displays warnings that will not necessarily lead to errors but should be addressed nonetheless.
441+
*
442+
* - logLevelInfo (default) logs information that we think is useful without being too verbose.
443+
*
444+
* - logLevelDebug use this in case you are debugging an issue. Not recommended for production use.
445+
*
446+
* - logLevelVerbose use this only if logLevelDebug was not enough and you need more visibility
447+
* on what is going on under the hood.
448+
*
449+
* Similar to the logLevelDebug level, this is not meant to be used on production environments.
450+
*
451+
* Each log level will also include logs from all the levels above it. For instance,
452+
* logLevelInfo will include logLevelInfo logs as well as logLevelWarning
453+
* and logLevelError logs.
454+
455+
* @param _logLevel the printed logs priority.
456+
*/
457+
+ (void)setAPMLogLevel:(NSString *)_logLevel;
458+
459+
/**
460+
* Enables and disables cold app launch tracking.
461+
* @param isEnabled isEnabled
462+
*/
463+
+ (void)setColdAppLaunchEnabled:(NSNumber *)isEnabled;
464+
465+
+ (void)startExecutionTrace:(NSString *)name id:(NSString *)id;
466+
467+
+ (void)setExecutionTraceAttribute:(NSString *)id key:(NSString *)key value:(NSString *)value;
468+
469+
+ (void)endExecutionTrace:(NSString *)id;
470+
471+
/**
472+
* Enables or disables auto UI tracing.
473+
* @param isEnabled boolean indicating enabled or disabled.
474+
*/
475+
+ (void)setAutoUITraceEnabled:(NSNumber *)isEnabled;
476+
477+
/**
478+
* Start UI trace.
479+
* @param name string holding the name of the trace.
480+
*/
481+
+ (void)startUITrace:(NSString *)name;
482+
483+
/**
484+
* Ends UI trace.
485+
*/
486+
+ (void)endUITrace;
487+
427488
@end

0 commit comments

Comments
 (0)