SourceMap 설정¶
SourceMap(소스 코드 맵)은 프로덕션 환경의 압축된 코드를 원본 소스 코드로 매핑하는 데 사용됩니다. RUM은 이러한 소스 코드 파일 정보 매핑을 지원하며, 해당 기호 테이블 파일을 ZIP으로 압축하여 업로드하면 보고된 error 메트릭 세트 데이터가 자동으로 변환됩니다.
ZIP 패키징 설명¶
webpack을 통해 난독화 및 압축된 JS 파일에서 생성된 .map 파일을 ZIP으로 압축합니다. 압축 해제된 파일 경로가 error_stack의 URL 경로와 일치해야 합니다. 다음과 같은 error_stack이 있다고 가정합니다.
ReferenceError
at a.hideDetail @ http://localhost:8080/static/js/app.7fb548e3d065d1f48f74.js:1:1037
at a.showDetail @ http://localhost:8080/static/js/app.7fb548e3d065d1f48f74.js:1:986
at <anonymous> @ http://localhost:8080/static/js/app.7fb548e3d065d1f48f74.js:1:1174
변환해야 할 경로는 /static/js/app.7fb548e3d065d1f48f74.js이며, 해당하는 sourcemap 경로는 /static/js/app.7fb548e3d065d1f48f74.js.map입니다. 압축 해제된 디렉터리 구조는 다음과 같습니다.
변환된 error_stack_source:
Web과 동일한 패키징 방식을 따릅니다.
Android에는 두 가지 유형의 sourcemap 파일이 있습니다. 하나는 Java 바이트코드가 R8/Proguard로 압축 및 난독화된 후 생성된 매핑 파일이고, 다른 하나는 C/C++ 네이티브 코드 컴파일 시 기호 테이블 및 디버그 정보가 제거되지 않은(stripping되지 않은) .so 파일입니다. Android 앱에 두 유형의 sourcemap 파일이 모두 포함된 경우, ZIP 패키지에 두 파일을 모두 포함해야 합니다. ZIP 압축 해제 후 디렉터리 구조는 다음과 같습니다.
sourcemap.zip
├── mapping.txt
├── armeabi-v7a/
│ ├── libgameengine.so
│ ├── libothercode.so
│ └── libvideocodec.so
├── arm64-v8a/
│ ├── libgameengine.so
│ ├── libothercode.so
│ └── libvideocodec.so
├── x86/
│ ├── libgameengine.so
│ ├── libothercode.so
│ └── libvideocodec.so
└── x86_64/
├── libgameengine.so
├── libothercode.so
└── libvideocodec.so
기본적으로 매핑 파일은 <프로젝트 폴더>/<Module>/build/outputs/mapping/<빌드 유형>/에 있습니다. .so 파일은 CMake로 프로젝트를 컴파일할 때는 <프로젝트 폴더>/<Module>/build/intermediates/cmake/debug/obj/에, NDK로 컴파일할 때는 <프로젝트 폴더>/<Module>/build/intermediates/ndk/debug/obj/(디버그 빌드) 또는 <프로젝트 폴더>/<Module>/build/intermediates/ndk/release/obj/(릴리스 빌드)에 있습니다.
변환 결과는 다음과 같습니다.
변환 전 error_stack:
java.lang.ArithmeticException: divide by zero
at prof.wang.activity.TeamInvitationActivity.o0(Unknown Source:1)
at prof.wang.activity.TeamInvitationActivity.k0(Unknown Source:0)
at j9.f7.run(Unknown Source:0)
at java.lang.Thread.run(Thread.java:1012)
변환 후 error_stack_source:
변환 전 error_stack:
backtrace:
#00 pc 00000000000057fc /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_4+12)
#01 pc 00000000000058a4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_3+8)
#02 pc 00000000000058b4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_2+12)
#03 pc 00000000000058c4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_1+12)
#04 pc 0000000000005938 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_crash+112)
...
변환 후 error_stack_source:
backtrace:
Abort message: 'abort message for ftNative internal testing'
#00 0x00000000000057fc /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_4+12)
xc_test_call_4
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:65:9
#01 0x00000000000058a4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_3+8)
xc_test_call_3
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:73:13
#02 0x00000000000058b4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_2+12)
xc_test_call_2
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:79:13
#03 0x00000000000058c4 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_call_1+12)
xc_test_call_1
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:85:13
#04 0x0000000000005938 /data/app/~~Taci3mQyw7W7iWT7Jxo-ag==/com.ft-Q8m2flQFG1MbGImPiuAZmQ==/lib/arm64/libft_native_exp_lib.so (xc_test_crash+112)
xc_test_crash
/Users/Brandon/Documents/workplace/working/StudioPlace/xCrash/xcrash_lib/src/main/cpp/xcrash/xc_test.c:126:9
...
iOS 플랫폼의 sourcemap 파일은 .dSYM 접미사가 있는 디버그 정보를 포함한 기호 테이블 파일입니다. 일반적으로 프로젝트 컴파일 후 .app 파일과 동일한 디렉터리에 있습니다.
$ ls -l Build/Products/Debug-iphonesimulator/
total 0
drwxr-xr-x 6 zy staff 192 8 9 15:27 Fishing.app
drwxr-xr-x 3 zy staff 96 8 9 14:02 Fishing.app.dSYM
drwxr-xr-x 15 zy staff 480 8 9 15:27 Fishing.doccarchive
drwxr-xr-x 6 zy staff 192 8 9 13:55 Fishing.swiftmodule
XCode Release 빌드는 기본적으로 .dSYM 파일을 생성하지만, Debug 빌드는 기본적으로 생성하지 않습니다. XCode에서 다음과 같이 설정해야 합니다.
Build Settings -> Code Generation -> Generate Debug Symbols -> Yes
Build Settings -> Build Option -> Debug Information Format -> DWARF with dSYM File
ZIP 패키지에 해당 .dSYM 파일을 포함시키기만 하면 됩니다. 프로젝트에 여러 .dSYM 파일이 있는 경우, 모두 ZIP 패키지에 포함해야 합니다. ZIP 압축 해제 후 디렉터리 구조는 다음과 같습니다(.dSYM 파일은 본질적으로 디렉터리이며, macOS의 실행 프로그램 .app 파일과 유사합니다).
React Native의 sourcemap은 네이티브 iOS, Android 및 JS 부분을 포함하여 총 세 가지 소스 맵으로 구성됩니다.
네이티브 iOS 및 Android의 sourcemap 획득 방법은 해당 패키징 설명을 참조하십시오.
JS 부분의 sourcemap 획득 방법은 다음과 같습니다.
Android 소스 맵은 기본적으로 활성화됩니다. 소스 맵 파일은 android/app/build/generated/sourcemaps/react/release/index.android.bundle.map에 있습니다.
iOS 소스 맵 생성을 활성화하려면 추가 구성이 필요합니다. Xcode를 열고 빌드 단계에서 "Bundle React Native code and images"를 편집합니다. 다른 내보내기 항목 위에 원하는 출력 경로가 있는 SOURCEMAP_FILE 항목을 추가합니다.
With Hermes, React Native <0.71
set -e
# output source maps
export SOURCEMAP_FILE="./main.jsbundle.map";
# React Native 0.70, you need to set USE_HERMES to true if Hermes is used, otherwise the source maps won't be generated.
export USE_HERMES=true
# keep the rest of the script unchanged
# When React Native (0.69, 0.71) and using Hermes
# add these lines to compose the packager and compiler source maps into one file
REACT_NATIVE_DIR=../node_modules/react-native
if [ -f "$REACT_NATIVE_DIR/scripts/find-node-for-xcode.sh" ]; then
source "$REACT_NATIVE_DIR/scripts/find-node-for-xcode.sh"
else
# Before RN 0.70, the script was named find-node.sh
source "$REACT_NATIVE_DIR/scripts/find-node.sh"
fi
source "$REACT_NATIVE_DIR/scripts/node-binary.sh"
"$NODE_BINARY" "$REACT_NATIVE_DIR/scripts/compose-source-maps.js" "$CONFIGURATION_BUILD_DIR/main.jsbundle.map" "$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/main.jsbundle.map" -o "../$SOURCEMAP_FILE"
JS sourcemap 파일을 획득한 후, 해당 빌드 플랫폼의 네이티브 sourcemap과 함께 다음 형식으로 ZIP 패키징합니다.
소스 맵 시각화 도구(source-map-visualization)를 사용하여 파일의 유효성을 확인할 수 있습니다.
업로드 방식¶
현재 다음 세 가지 SourceMap 업로드 방식을 지원합니다.
- 웹 UI 업로드: SourceMap 파일을 수동으로 업로드 및 삭제하는 데 적합합니다.
- 스크립트 업로드: 퍼블릭 네트워크 DataWay 시나리오에서 자동화된 업로드에 적합합니다.
- 빌드 단계 플러그인 업로드: Web 프로젝트가 패키징 단계에서 SourceMap을 자동으로 업로드하는 데 적합합니다.
웹 UI 업로드 및 삭제¶
패키징 구성이 완료되면 사용자는 웹 UI에서 [RUM] > [애플리케이션 목록] > [애플리케이션 오른쪽 상단 더 보기 아이콘 클릭] > [SourceMap]으로 이동하여 파일을 업로드 및 삭제할 수 있습니다. 현재 계정에 '편집' 이상의 권한이 있는지 확인하십시오.
🔍 검색창 아래에서 업로드된 파일 이름과 애플리케이션 유형을 확인할 수 있습니다. 파일 이름을 입력하여 검색하고 을 클릭하여 현재 파일을 삭제할 수 있습니다.
업로드 참고 사항:
- 파일 크기는 500MB를 초과할 수 없습니다.
- 파일 형식은
.zip이어야 합니다. - 압축 해제된 파일 경로가
error_stack의 URL 경로와 일치하는지 확인하십시오. - 여러 파일을 동시에 업로드할 수 없습니다.
- 동일한 이름의 파일을 업로드하면 덮어쓰기 경고가 표시되니 유의하십시오.
스크립트 업로드¶
현재 애플리케이션이 퍼블릭 네트워크 DataWay 방식을 사용하는 경우, 스크립트를 통해 OpenAPI로 패키징된 sourcemap.zip 파일을 업로드할 수도 있습니다.
자세한 내용은 스크립트 SourceMap 업로드를 참조하십시오.
빌드 단계 플러그인 업로드¶
Web 프로젝트의 경우, 웹 UI 업로드 및 스크립트 업로드 외에도 프로젝트 빌드 단계에서 플러그인을 통해 SourceMap 파일을 자동으로 업로드할 수 있습니다.
현재 지원되는 방식은 다음과 같습니다.
SourceMap 업로드가 완료되면 오류 스택 해석에 사용할 수 있습니다.

