Skip to content

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) and FTRUMConfig.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

FTSdk.initRUMWithConfig(new FTRUMConfig()
    .setResourceUrlHandler(new FTInTakeUrlHandler() {
        @Override
        public boolean isInTakeUrl(String url) {
            // Return true to exclude from collection; return false to include.
            return url.startsWith("https://url.rule");
        }
    })
);
FTSdk.initRUMWithConfig(
    FTRUMConfig()
        .setResourceUrlHandler(object : FTInTakeUrlHandler {
            override fun isInTakeUrl(url: String): Boolean {
                // Return true to exclude from collection; return false to include.
                return url.startsWith("https://url.rule")
            }
        })
)

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)
    }
}