데이터 수집 사용자 정의 규칙¶
View¶
Activity¶
FTRUMConfig.setEnableTraceUserView(true)를 먼저 활성화해야 합니다
FTSdk.initRUMWithConfig(new FTRUMConfig()
.setViewActivityTrackingHandler(new FTViewActivityTrackingHandler() {
@Override
public HandlerView resolveHandlerView(Activity activity) {
String activityName = activity.getClass().getSimpleName();
// Activity 이름에 따라 뷰 이름 사용자 정의
if (activityName.startsWith("Main")) {
return new HandlerView("사용자 정의 메인 페이지");
} else if (activityName.startsWith("Detail")) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("extra_key", "extra_value");
return new HandlerView("사용자 정의 상세 페이지", properties);
}
// null을 반환하면 추적을 건너뜁니다
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("사용자 정의 메인 페이지")
activityName.startsWith("Detail") -> {
val properties = hashMapOf<String, Any>("extra_key" to "extra_value")
HandlerView("사용자 정의 상세 페이지", properties)
}
else -> null // 추적 건너뛰기
}
}
})
)
Fragment¶
FTRUMConfig.setEnableTraceUserView(true)와FTRUMConfig.setEnableTraceUserViewInFragment(true)를 모두 활성화해야 합니다
FTSdk.initRUMWithConfig(new FTRUMConfig()
.setViewFragmentTrackingHandler(new FTViewFragmentTrackingHandler() {
@Override
public HandlerView resolveHandlerView(FragmentWrapper fragment) {
String fragmentName = fragment.getSimpleClassName();
// Fragment 이름에 따라 뷰 이름 사용자 정의
if (fragmentName.equals("HomeFragment")) {
return new HandlerView("사용자 정의 홈 프래그먼트");
} else if (fragmentName.startsWith("Detail")) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("extra_key", "extra_value");
return new HandlerView("사용자 정의 상세 프래그먼트", properties);
}
// null을 반환하면 추적을 건너뜁니다
return null;
}
})
);
FTSdk.initRUMWithConfig(
FTRUMConfig()
.setViewFragmentTrackingHandler(object : FTViewFragmentTrackingHandler {
override fun resolveHandlerView(fragment: FragmentWrapper): HandlerView? {
val fragmentName = fragment.simpleClassName
return when {
fragmentName == "HomeFragment" ->
HandlerView("사용자 정의 홈 프래그먼트")
fragmentName.startsWith("Detail") -> {
val properties = hashMapOf<String, Any>("extra_key" to "extra_value")
HandlerView("사용자 정의 상세 프래그먼트", properties)
}
else -> null // 추적 건너뛰기
}
}
})
)
Action¶
FTRUMConfig.setEnableTraceUserAction(true)가 활성화되어 있어야 합니다- 용도: Action 이름 및 속성 사용자 정의, 또는 특정 View에 따라 Action 수집 필터링
FTSdk.initRUMWithConfig(new FTRUMConfig()
.setActionTrackingHandler(new FTActionTrackingHandler() {
@Override
public HandlerAction resolveHandlerAction(ActionEventWrapper actionEventWrapper) {
// 작업 유형 가져오기
ActionSourceType actionType = actionEventWrapper.getSourceType();
Object source = actionEventWrapper.getSource();
// 지정된 View의 Action 필터링
if (source instanceof View) {
View view = (View) source;
if (view.getId() == R.id.ignore_action_view) {
return null;
}
}
// 작업 유형에 따라 추적 사용자 정의
if (actionType == ActionSourceType.CLICK_VIEW) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("extra_key", "extra_value");
return new HandlerAction("사용자 정의 버튼 클릭", properties);
} else if (actionType == ActionSourceType.CLICK_LIST_ITEM) {
return new HandlerAction("사용자 정의 목록 항목 클릭");
}
// null을 반환하면 추적을 건너뜁니다
return null;
}
})
);
FTSdk.initRUMWithConfig(
FTRUMConfig()
.setActionTrackingHandler(object : FTActionTrackingHandler {
override fun resolveHandlerAction(actionEventWrapper: ActionEventWrapper): HandlerAction? {
val source = actionEventWrapper.source
// 지정된 View의 Action 필터링
if (source is View && source.id == R.id.ignore_action_view) {
return null
}
return when (actionEventWrapper.sourceType) {
ActionSourceType.CLICK_VIEW -> {
val properties = hashMapOf<String, Any>("extra_key" to "extra_value")
HandlerAction("사용자 정의 버튼 클릭", properties)
}
ActionSourceType.CLICK_LIST_ITEM ->
HandlerAction("사용자 정의 목록 항목 클릭")
else -> null // 추적 건너뛰기
}
}
})
)
주의
ActionEventWrapper.getSource()를 통해 현재 작업의 소스 객체를 가져올 수 있습니다. 일반 클릭, 목록 항목 클릭, 탭 클릭 등 View에 의해 트리거된 Action의 경우 source는 일반적으로 해당 View입니다. setActionTrackingHandler를 설정하면 SDK는 해당 핸들러의 반환 결과를 Action 수집 기준으로 사용합니다. null을 반환하는 Action은 건너뜁니다. 계속 수집해야 하는 Action은 HandlerAction을 반환해야 합니다.
Resource¶
FTRUMConfig.setEnableTraceUserResource(true)가 활성화되어 있어야 합니다
URL에 따른 수집 필터링¶
사용자 정의 속성 추가¶
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
}
}
네트워크 오류 필터링¶
로컬 네트워크 IOException 오류를 필터링할 수 있습니다. FTRUMConfig.setOkHttpResourceContentHandler(FTResourceInterceptor.ContentHandlerHelperEx)를 통해 설정하거나 Resource 사용자 정의를 참조하세요.
new FTResourceInterceptor.ContentHandlerHelperEx() {
//...
/**
* 네트워크 연결 과정에서 발생한 예외를 반환
*
* @param e 요청에서 발생한 IOException 데이터
* @param extraData 추가 데이터
* @return 로컬 네트워크 network_error 유형의 오류를 필터링할지 여부. true이면 필터링하여 수집하지 않음
*/
@Override
public boolean onExceptionWithFilter(Exception e, HashMap<String, Object> extraData) {
if (e instanceof SocketTimeoutException) { //네트워크 타임아웃
return true;
}
return super.onExceptionWithFilter(e, extraData);
}
}
object : FTResourceInterceptor.ContentHandlerHelperEx() {
//...
/**
* 네트워크 연결 과정에서 발생한 예외를 반환
*
* @param e 요청에서 발생한 IOException 데이터
* @param extraData 추가 데이터
* @return 로컬 네트워크 network_error 유형의 오류를 필터링할지 여부. true이면 덮어쓰고 수집하지 않음
*/
override fun onExceptionWithFilter(e: Exception, extraData: HashMap<String, Any>): Boolean {
return if (e is SocketTimeoutException) {
true
} else {
super.onExceptionWithFilter(e, extraData)
}
}
}
사용자 정의 TraceHeader¶
FTTraceConfig.setOkHttpTraceHeaderHandler(FTTraceInterceptor.HeaderHandler)를 통해 설정하거나 Trace 사용자 정의를 참조하세요. 다음은 w3c-traceContext를 예시로 합니다.
new FTTraceInterceptor.HeaderHandler() {
private String[] splits;
@Override
public HashMap<String, String> getTraceHeader(Request request) {
HashMap<String, String> map = new HashMap<>();
// header에서 사용자 정의 trace_id 가져오기
String replaceTrace = request.header(CUSTOM_TRACE_HEADER);
String headerString = FTTraceManager.get().
getTraceHeader(request.url().toString())
// header에서 propagation 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>()
// header에서 사용자 정의 trace_id 가져오기
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)
}
}
사용자 정의 trace_id를 사용하여 RUM Resource 연결¶
애플리케이션 측에 이미 사용자 정의 trace_id가 있는 경우(예: 요청 헤더 키가 custom_trace_id인 경우), SDK가 생성한 traceparent를 기반으로 trace_id를 업데이트하고 TraceContext.Simple을 통해 RUM Resource 연결에 사용할 trace_id를 지정할 수 있습니다.
new FTTraceInterceptor.HeaderHandler() {
@Override
public TraceContext getTraceContext(Request request) {
HashMap<String, String> headers = FTTraceManager.get()
.getTraceHeader(request.url().toString());
// 요청 header에서 사용자 정의 trace_id 가져오기(예: custom_trace_id)
String customTraceId = request.header(CUSTOM_TRACE_HEADER);
TraceContext.Simple sdkContext = TraceContext.Simple.fromTraceType(headers);
if (customTraceId == null
|| customTraceId.length() == 0
|| sdkContext == null
|| sdkContext.getTraceId() == null) {
return sdkContext;
}
String traceparent = headers.get(FTTraceHandler.W3C_TRACEPARENT_KEY);
if (traceparent == null) {
return sdkContext;
}
String newTraceparent = traceparent.replace(
sdkContext.getTraceId(),
customTraceId
);
// 요청에 주입할 W3C trace header 업데이트
headers.put(FTTraceHandler.W3C_TRACEPARENT_KEY, newTraceparent);
// 선택 사항: 사용자 정의 비즈니스 header 유지
headers.put(CUSTOM_TRACE_HEADER, customTraceId);
// RUM Resource 연결 시 customTraceId 사용, spanId는 계속 SDK에서 생성한 spanId 사용
return new TraceContext.Simple(headers, customTraceId, sdkContext.getSpanId());
}
};
object : FTTraceInterceptor.HeaderHandler() {
override fun getTraceContext(request: Request): TraceContext? {
val headers = FTTraceManager.get()
.getTraceHeader(request.url().toString())
// 요청 header에서 사용자 정의 trace_id 가져오기
val customTraceId = request.header(CUSTOM_TRACE_HEADER)
val sdkContext = TraceContext.Simple.fromTraceType(headers)
val sdkTraceId = sdkContext?.traceId
val sdkSpanId = sdkContext?.spanId
if (customTraceId.isNullOrEmpty() || sdkTraceId.isNullOrEmpty()) {
return sdkContext
}
val traceparent = headers[FTTraceHandler.W3C_TRACEPARENT_KEY] ?: return sdkContext
val newTraceparent = traceparent.replace(sdkTraceId, customTraceId)
// 요청에 주입할 W3C trace header 업데이트
headers[FTTraceHandler.W3C_TRACEPARENT_KEY] = newTraceparent
// 선택 사항: 사용자 정의 비즈니스 header 유지
headers[CUSTOM_TRACE_HEADER] = customTraceId
// RUM Resource 연결 시 customTraceId 사용, spanId는 계속 SDK에서 생성한 spanId 사용
return TraceContext.Simple(headers, customTraceId, sdkSpanId)
}
}
참고: W3C trace_id는 32자리 16진수 문자열이어야 하며, 모두 0이 될 수 없습니다.