Data Collection Custom Rules¶
View¶
Activity¶
- First, enable it via
FTRUMConfig.setEnableTraceUserView(true).
FTSdk.initRUMWithConfig(new FTRUMConfig()
.setViewActivityTrackingHandler(new FTViewActivityTrackingHandler() {
@Override
public HandlerView resolveHandlerView(Activity activity) {
String activityName = activity.getClass().getSimpleName();
// Customize the view name based on the Activity name.
if (activityName.startsWith("Main")) {
return new HandlerView("Custom Main Page");
} else if (activityName.startsWith("Detail")) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("extra_key", "extra_value");
return new HandlerView("Custom Detail Page", properties);
}
// Return null to skip tracking.
return null;
}
})
);
FTSdk.initRUMWithConfig(
FTRUMConfig()
.setViewActivityTrackingHandler(object : FTViewActivityTrackingHandler {
override fun resolveHandlerView(activity: Activity): HandlerView? {
val activityName = activity.javaClass.simpleName
return when {
activityName.startsWith("Main") ->
HandlerView("Custom Main Page")
activityName.startsWith("Detail") -> {
val properties = hashMapOf<String, Any>("extra_key" to "extra_value")
HandlerView("Custom Detail Page", properties)
}
else -> null // Skip tracking.
}
}
})
)
Fragment¶
- Requires enabling both
FTRUMConfig.setEnableTraceUserView(true)andFTRUMConfig.setEnableTraceUserViewInFragment(true).
FTSdk.initRUMWithConfig(new FTRUMConfig()
.setViewFragmentTrackingHandler(new FTViewFragmentTrackingHandler() {
@Override
public HandlerView resolveHandlerView(FragmentWrapper fragment) {
String fragmentName = fragment.getSimpleClassName();
// Customize the view name based on the Fragment name.
if (fragmentName.equals("HomeFragment")) {
return new HandlerView("Custom Home Fragment");
} else if (fragmentName.startsWith("Detail")) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("extra_key", "extra_value");
return new HandlerView("Custom Detail Fragment", properties);
}
// Return null to skip tracking.
return null;
}
})
);
FTSdk.initRUMWithConfig(
FTRUMConfig()
.setViewFragmentTrackingHandler(object : FTViewFragmentTrackingHandler {
override fun resolveHandlerView(fragment: FragmentWrapper): HandlerView? {
val fragmentName = fragment.simpleClassName
return when {
fragmentName == "HomeFragment" ->
HandlerView("Custom Home Fragment")
fragmentName.startsWith("Detail") -> {
val properties = hashMapOf<String, Any>("extra_key" to "extra_value")
HandlerView("Custom Detail Fragment", properties)
}
else -> null // Skip tracking.
}
}
})
)
Action¶
- Requires
FTRUMConfig.setEnableTraceUserAction(true)to be enabled.
FTSdk.initRUMWithConfig(new FTRUMConfig()
.setActionTrackingHandler(new FTActionTrackingHandler() {
@Override
public HandlerAction resolveHandlerAction(ActionEventWrapper actionEventWrapper) {
// Get the action type.
ActionSourceType actionType = actionEventWrapper.getSourceType();
// Customize tracking based on the action type.
if (actionType == ActionSourceType.CLICK_VIEW) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("extra_key", "extra_value");
return new HandlerAction("Custom Button Click", properties);
} else if (actionType == ActionSourceType.CLICK_LIST_ITEM) {
return new HandlerAction("Custom List Item Click");
}
// Return null to skip tracking.
return null;
}
})
);
FTSdk.initRUMWithConfig(
FTRUMConfig()
.setActionTrackingHandler(object : FTActionTrackingHandler {
override fun resolveHandlerAction(actionEventWrapper: ActionEventWrapper): HandlerAction? {
return when (actionEventWrapper.sourceType) {
ActionSourceType.CLICK_VIEW -> {
val properties = hashMapOf<String, Any>("extra_key" to "extra_value")
HandlerAction("Custom Button Click", properties)
}
ActionSourceType.CLICK_LIST_ITEM ->
HandlerAction("Custom List Item Click")
else -> null // Skip tracking.
}
}
})
)
Resource¶
- Requires
FTRUMConfig.setEnableTraceUserResource(true)to be enabled.
Filter Collection Based on URL¶
Add Custom Attributes¶
Can be set via FTRUMConfig.setOkHttpResourceContentHandler(FTResourceInterceptor.ContentHandlerHelperEx).
new FTResourceInterceptor.ContentHandlerHelperEx() {
@Override
public void onRequest(Request request, HashMap<String, Object> extraData) {
extraData.put("df_custom_key","custom_value");
}
@Override
public void onResponse(Response response, HashMap<String, Object> extraData) throws IOException {
extraData.put("df_custom_key","custom_value");
}
@Override
public boolean onExceptionWithFilter(Exception e, HashMap<String, Object> extraData) {
extraData.put("df_custom_key","custom_value");
return false;
}
}
object : FTResourceInterceptor.ContentHandlerHelperEx() {
override fun onRequest(
request: Request,
extraData: HashMap<String, Any>
) {
extraData["df_custom_key"] = "custom_value"
}
override fun onResponse(
response: Response,
extraData: HashMap<String, Any>
) {
extraData["df_custom_key"] = "custom_value"
}
override fun onExceptionWithFilter(
e: Exception,
extraData: HashMap<String, Any>
): Boolean {
extraData["df_custom_key"] = "custom_value"
return false
}
}
Filter Network Errors¶
You can filter local network IOException errors. Can be set via FTRUMConfig.setOkHttpResourceContentHandler(FTResourceInterceptor.ContentHandlerHelperEx), or Custom Resource.
new FTResourceInterceptor.ContentHandlerHelperEx() {
//...
/**
* Returns exceptions during network connection.
*
* @param e IOException data from the request.
* @param extraData Additional data.
* @return Whether to filter local network errors of type `network_error`. true means filter and do not collect.
*/
@Override
public boolean onExceptionWithFilter(Exception e, HashMap<String, Object> extraData) {
if (e instanceof SocketTimeoutException) { // Network timeout.
return true;
}
return super.onExceptionWithFilter(e, extraData);
}
}
object : FTResourceInterceptor.ContentHandlerHelperEx() {
//...
/**
* Returns exceptions during network connection.
*
* @param e IOException data from the request.
* @param extraData Additional data.
* @return Whether to filter local network errors of type `network_error`. true means override and do not collect.
*/
override fun onExceptionWithFilter(e: Exception, extraData: HashMap<String, Any>): Boolean {
return if (e is SocketTimeoutException) {
true
} else {
super.onExceptionWithFilter(e, extraData)
}
}
}
Custom TraceHeader¶
Can be set via FTTraceConfig.setOkHttpTraceHeaderHandler(FTTraceInterceptor.HeaderHandler), or Custom Trace. The following example uses w3c-traceContext.
new FTTraceInterceptor.HeaderHandler() {
private String[] splits;
@Override
public HashMap<String, String> getTraceHeader(Request request) {
HashMap<String, String> map = new HashMap<>();
// Get custom trace_id from header.
String replaceTrace = request.header(CUSTOM_TRACE_HEADER);
String headerString = FTTraceManager.get().
getTraceHeader(request.url().toString())
// Get propagation header from header.
.get(FTTraceHandler.W3C_TRACEPARENT_KEY);
splits = headerString.split("-");
String originTraceId = splits[1];
splits[1] = replaceTrace;
map.put(FTTraceHandler.W3C_TRACEPARENT_KEY, headerString.replace(originTraceId, replaceTrace));
return map;
}
@Override
public String getSpanID() {
if (splits != null) {
return splits[2];
}
return null;
}
@Override
public String getTraceID() {
if (splits != null) {
return splits[1];
}
return null;
}
};
object : FTTraceInterceptor.HeaderHandler() {
private var splits: List<String>? = null
override fun getTraceHeader(request: Request): HashMap<String, String> {
val map = HashMap<String, String>()
// Get custom trace_id from header.
val replaceTrace = request.header(CUSTOM_TRACE_HEADER)
val headerString = FTTraceManager.get()
.getTraceHeader(request.url().toString())
.get(FTTraceHandler.W3C_TRACEPARENT_KEY)
splits = headerString?.split("-")
val originTraceId = splits?.getOrNull(1)
if (headerString != null && originTraceId != null && replaceTrace != null) {
map[FTTraceHandler.W3C_TRACEPARENT_KEY] =
headerString.replace(originTraceId, replaceTrace)
}
return map
}
override fun getSpanID(): String? {
return splits?.getOrNull(2)
}
override fun getTraceID(): String? {
return splits?.getOrNull(1)
}
}