설정
플랫폼별 앱 아이덴티티, 컬렉터 URL과 앱 키의 위치, iOS가 이를 결정하는 순서, initialize와 sdkConfig, sophonz-config.json, Expo 설정 플러그인의 모든 옵션을 설명합니다.
두 플랫폼은 설정하는 위치가 다릅니다. 그 아래의 네이티브 SDK가 그렇게 되어 있기 때문입니다. Android는 빌드 시점에 sophonz-config.json으로 설정하며 런타임에 넘기는 값은 없습니다. iOS는 시작 시점에 JavaScript, Sophonz-Info.plist, 네이티브 코드 중 하나로 설정합니다.
아이덴티티
기기가 보내는 모든 배치에는 컬렉터가 어느 앱의 데이터인지 알 수 있게 하는 리소스 속성이 붙습니다.
| 속성 | 의미 | Android | iOS |
|---|---|---|---|
service.key | 포털이 발급한 앱 키(sk_...) | sdk_config.ingest.service_key | appKey / AppKey |
service.name | 앱이 등록된 이름 | 패키지 이름 | appName / AppName, 기본값은 번들 식별자 |
service.namespace | 프로젝트 | sdk_config.ingest.service_namespace | project / Project |
deployment.environment.name | 환경 | sdk_config.ingest.deployment_environment | deploymentEnvironment / DeploymentEnvironment, 기본값은 production |
| 컬렉터 | 텔레메트리를 보낼 곳 | sdk_config.ingest.collector_url | collectorUrl / CollectorURL |
| 읽는 곳 | 빌드 시점의 android/app/src/main/sophonz-config.json | 시작 시점의 JS sdkConfig.ios, Sophonz-Info.plist, Sophonz.Options |
포털에서 플랫폼마다 별도의 앱으로 등록하고 각자의 sk_ 키를 받습니다. 두 플랫폼이 키 하나를 같이 쓰지 마세요.
CAUTION — 키가 틀려도 조용히 실패합니다
컬렉터는 테넌트를 찾을 수 없는 키의 텔레메트리를 버리고, SDK가 보고할 수 있는 오류도 돌려주지 않습니다. 임시 값이나 오타가 있는 키로 빌드한 앱도 시작하고, 수집하고, 업로드하지만 결과는 아무것도 남지 않으며 initialize도 true로 resolve됩니다. 세션이 보이지 않으면 무엇보다 먼저 키를 확인하세요.
AppName은 조인 키입니다
포털은 service.name으로 텔레메트리와 등록된 앱을 연결합니다. iOS에서는 기본값이 번들 식별자이므로, 앱을 다른 이름으로 등록했다면 appName을 지정하세요. 나중에 이 값을 바꾸면 앱이 포털 항목에서 떨어져 나갑니다. 컬렉터는 계속 데이터를 받지만 앱 페이지가 비어서 전송이 멈춘 것처럼 보입니다.
Android: sophonz-config.json
Gradle 플러그인이 이 파일을 앱에 컴파일해 넣습니다. 런타임에는 값을 바꿀 수 없고, JavaScript의 sdkConfig에는 Android 항목이 없습니다.
{
"sdk_config": {
"app_framework": "react_native",
"ingest": {
"collector_url": "https://in.sophonz.ai",
"service_key": "sk_android_replace_me",
"service_namespace": "my-project",
"deployment_environment": "production"
}
}
}| 키 | 효과 |
|---|---|
ingest.collector_url | 컬렉터 기본 URL. 기본값은 https://in.sophonz.ai. /v1/traces는 넣지 않습니다 |
ingest.service_key | 앱 키. service.key로 전송됩니다 |
ingest.service_namespace | service.namespace |
ingest.deployment_environment | deployment.environment.name |
app_framework | React Native 앱은 react_native로 설정합니다 |
service_key와 collector_url은 빌드 시점의 SOPHONZ_SERVICE_KEY, SOPHONZ_COLLECTOR_URL 환경 변수로도 지정할 수 있으므로 키를 커밋하지 않아도 됩니다. 둘 다 있으면 파일의 값이 우선합니다.
React Native 앱에서 특히 중요한 키
나머지 옵션은 네이티브 앱과 같으며 Android 설정에 정리되어 있습니다. 파서가 모르는 키가 있으면 빌드가 실패합니다.
| 키 | 기본값 | React Native에서 중요한 이유 |
|---|---|---|
sdk_config.networking.enable_traceparent_injection | false | fetch로 보내는 요청에 traceparent를 붙입니다. 네트워크 참고 |
sdk_config.networking.traceparent_only_allow_domains | 없음 | traceparent를 받을 호스트를 제한합니다 |
sdk_config.networking.enable_network_span_forwarding | false | 수집한 요청 스팬과 수동으로 기록한 요청 스팬에 spz.w3c_traceparent를 붙입니다 |
sdk_config.networking.disabled_url_patterns | [] | 수집하지 않을 URL의 정규식. 두 번째 OTLP 백엔드 같은 곳 |
sdk_config.view_config.enable_automatic_activity_capture | true | React Native 앱은 보통 Activity가 하나뿐입니다. 내비게이션 패키지로 화면을 기록한다면 끄세요 |
ndk_enabled | true | 네이티브 크래시 수집. Hermes 등 C++ 라이브러리 안의 크래시도 여기에 해당합니다 |
api_token, app_id | 없음 | 텔레메트리가 아니라 빌드 시점 업로드용 인증 정보입니다. 설정하기 전에 릴리스 빌드를 읽으세요 |
iOS: 아이덴티티를 정하는 순서
JavaScript가 SDK를 시작할 때 네이티브 모듈은 다음 중 먼저 사용할 수 있는 것을 고릅니다.
sdkConfig.ios.collectorUrl와sdkConfig.ios.appKey- 앱 번들 안의
Sophonz-Info.plist(최소한CollectorURL과AppKey가 있을 것) @sophonz/react-native-otlp의 OTLP 익스포터만(Sophonz 컬렉터 없음)- 아무것도 없음: 시작이 실패하고
initialize는false로 resolve됩니다
모든 단계에서 빈 문자열은 없는 것으로 취급합니다. SDK를 네이티브에서 시작하면 이 순서는 적용되지 않고, SophonzInitializer.swift에 적은 옵션이 그대로 쓰입니다.
JavaScript에서
import {initialize} from "@sophonz/react-native";
await initialize({
sdkConfig: {
ios: {
collectorUrl: "https://in.sophonz.ai",
appKey: "sk_ios_replace_me",
appName: "my-ios-app",
project: "my-project",
deploymentEnvironment: "production",
disabledUrlPatterns: ["analytics.example.com"],
},
trackUnhandledRejections: true,
},
logLevel: "warn",
});Sophonz-Info.plist에서
앱의 Info.plist 옆에 정확히 Sophonz-Info.plist라는 이름으로 파일을 만들고, Copy Bundle Resources에 포함되도록 앱 타깃에 추가한 뒤, sdkConfig에서는 collectorUrl과 appKey를 빼세요.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CollectorURL</key>
<string>https://in.sophonz.ai</string>
<key>AppKey</key>
<string>sk_ios_replace_me</string>
<key>AppName</key>
<string>my-ios-app</string>
<key>Project</key>
<string>my-project</string>
<key>DeploymentEnvironment</key>
<string>production</string>
</dict>
</plist>이렇게 하면 키가 JavaScript 번들에 들어가지 않고, ios 블록 없는 initialize 호출 하나로 두 플랫폼을 처리할 수 있습니다.
CAUTION — 이 파일에서는 빌드 설정이 치환되지 않습니다
Xcode는 $(SETTING) 참조를 타깃 자신의 Info.plist에서만 치환합니다. Sophonz-Info.plist에 $(SOPHONZ_APP_KEY) 같은 값을 넣으면 글자 그대로 남고, SDK는 이를 없는 값으로 취급합니다. 실제 값을 넣거나 빌드 단계에서 파일을 생성하세요.
네이티브 코드에서
Expo 플러그인과 설치 마법사가 만드는 SophonzInitializer.swift는 Sophonz.start(options:)를 호출합니다. iOS 설정에 나오는 캡처 서비스 옵션, traceparent 허용 목록, 행 감지, 크래시 리포터 선택은 모두 여기서만 설정할 수 있습니다. 옵션에는 platform: .reactNative를 유지하세요.
initialize
initialize({sdkConfig?, patch?, logLevel?}): Promise<boolean>| 인자 | 타입 | 기본값 | 설명 |
|---|---|---|---|
sdkConfig | SDKConfig | {} | 아래의 시작 옵션 |
patch | string | 없음 | JavaScript 패치 번호로 기록됩니다. 네이티브 버전이 바뀌지 않는 OTA 업데이트에 쓰세요 |
logLevel | "info", "warn", "error" | "info" | JavaScript 계층의 콘솔 출력. 에러는 항상 출력됩니다 |
useSophonz(sdkConfig, patch?, logLevel?)는 같은 값을 순서대로 받습니다.
sdkConfig 레퍼런스
| 옵션 | 타입 | 플랫폼 | 기본값 | 설명 |
|---|---|---|---|---|
ios.collectorUrl | string | iOS | — | 컬렉터 기본 URL. /v1/...는 넣지 않습니다 |
ios.appKey | string | iOS | — | 앱 키, service.key |
ios.appName | string | iOS | 번들 식별자 | service.name |
ios.project | string | iOS | — | service.namespace |
ios.deploymentEnvironment | string | iOS | production | deployment.environment.name |
ios.disableCrashReporter | boolean | iOS | false | 크래시 리포터를 설치하지 않습니다 |
ios.disableAutomaticViewCapture | boolean | iOS | false | UIViewController 화면을 수집하지 않습니다 |
ios.disableNetworkSpanForwarding | boolean | iOS | false | 어떤 요청에도 traceparent를 붙이지 않고, 수동으로 기록한 요청에 spz.w3c_traceparent도 붙이지 않습니다 |
ios.disabledUrlPatterns | string[] | iOS | [] | URL에 이 문자열 중 하나가 들어 있는 요청은 수집하지 않습니다 |
exporters | OTLPExporterConfig | 양쪽 | — | 추가 OTLP 익스포터. @sophonz/react-native-otlp 필요. OpenTelemetry와 OTLP 참고 |
trackUnhandledRejections | boolean | 양쪽 | false | 처리되지 않은 Promise 거부를 기록합니다 |
SDKConfig 타입에는 logLevel 필드도 선언되어 있지만 initialize는 이 값을 읽지 않습니다. logLevel은 sdkConfig 옆에 넘기세요.
네이티브 시작 후에도 적용되는 것
MainApplication이나 SophonzInitializer가 SDK를 이미 시작했다면 initialize는 자체 시작을 건너뜁니다. 이때 ios 옵션과 exporters는 경고 없이 무시됩니다. 다음은 여전히 적용됩니다.
trackUnhandledRejectionspatch- 전역 JS 에러 핸들러, React Native와 SDK 버전
- iOS 릴리스 빌드의 JS 번들 식별자
시작 설정은 네이티브 코드에 두세요. Android는 sophonz-config.json, iOS는 Sophonz.Options나 Sophonz-Info.plist입니다.
익스포터 필드
요약만 적습니다. 자세한 설명은 OpenTelemetry와 OTLP에 있습니다.
| 필드 | 타입 | 설명 |
|---|---|---|
traceExporter.endpoint, logExporter.endpoint | string | /v1/traces 또는 /v1/logs까지 포함한 전체 URL |
headers | {key, token}[] | 모든 전송에 붙는 헤더 |
timeout | number | 초 단위 |
Tracer provider 옵션
useSophonzNativeTracerProvider(config?, enabled?)와 new SophonzNativeTracerProvider(config?)는 다음 옵션을 받습니다.
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
spanContextSyncBehaviour | "return_empty" 또는 "throw" | "return_empty" | 네이티브 쪽 응답 전에 span.spanContext()를 호출했을 때의 동작 |
setGlobalContextManager | boolean | config를 넘기지 않으면 true, 넘기면 false | provider의 컨텍스트 매니저를 @opentelemetry/api에 등록합니다 |
{}를 넘기면 전역 컨텍스트 매니저가 꺼집니다. OpenTelemetry와 OTLP를 참고하세요.
Expo 설정 플러그인
| 속성 | 필수 | 설명 |
|---|---|---|
androidAppKey | 예 | sdk_config.ingest.service_key에 기록됩니다 |
iOSAppKey | 예 | SophonzInitializer.swift의 Sophonz.Options.withCollector(appKey:)에 전달됩니다 |
collectorUrl | 두 플랫폼 공통. 기본값은 https://in.sophonz.ai | |
iOSAppName | iOS service.name | |
project | 두 플랫폼의 service.namespace | |
deploymentEnvironment | 두 플랫폼의 deployment.environment.name | |
androidSDKConfig | sdk_config에 병합할 추가 키. 예를 들어 networking이나 view_config. 여기에 ingest 객체를 넣으면 생성된 값을 대체합니다 | |
productModuleName | iOS PRODUCT_MODULE_NAME이 프로젝트 이름과 다를 때 지정합니다. Objective-C AppDelegate가 올바른 Swift 헤더를 import하게 됩니다 | |
iOSUseSPM | true면 Apple SDK를 Swift Package Manager에서 가져옵니다. expo-build-properties의 ios.useFrameworks: "dynamic"이 필요합니다 |
androidAppKey나 iOSAppKey가 없거나 iOSUseSPM이 boolean이 아니면 prebuild가 실패합니다. 그 밖에 플러그인이 만나는 문제는 경고로만 보고되고 prebuild는 계속됩니다.
{
"expo": {
"plugins": [
[
"@sophonz/react-native",
{
"androidAppKey": "sk_android_replace_me",
"iOSAppKey": "sk_ios_replace_me",
"androidSDKConfig": {
"networking": {
"enable_traceparent_injection": true,
"traceparent_only_allow_domains": ["api.example.com"]
}
}
}
]
]
}
}플러그인이 두 플랫폼 모두에서 SDK를 네이티브로 시작하므로, 플러그인을 쓰는 Expo 앱에서 initialize에 넘긴 sdkConfig는 무시됩니다. 속성으로 제공되지 않는 iOS 수집 옵션은 생성된 SophonzInitializer.swift를 직접 고쳐야 하며, 이후 prebuild는 --clean 없이는 이 파일을 건드리지 않습니다.
iOS에서 Swift Package Manager 사용
기본값은 CocoaPods입니다. Apple SDK를 SPM에서 가져오려면(React Native 0.75 이상, 동적 프레임워크) 다음처럼 설치합니다.
cd ios
SOPHONZ_USE_SPM=1 USE_FRAMEWORKS=dynamic pod installExpo에서는 iOSUseSPM: true를 지정하세요. 플러그인이 Podfile 맨 위에 ENV['SOPHONZ_USE_SPM'] ||= '1'을 넣으므로 셸 환경에 따라 결과가 달라지지 않습니다.
Podfile의 sophonz_post_install(installer) 훅은 SophonzIO 패키지를 앱 타깃에 추가해 임베드와 서명이 되게 합니다. 이 훅이 없으면 Release 빌드가 실행 즉시 Library not loaded로 크래시합니다. 어느 쪽을 쓰든 훅은 Podfile에 남겨 두세요. SOPHONZ_USE_SPM이 없으면 이전 SPM 설치가 추가한 항목을 제거합니다.
SDK 에러 로깅
모든 API 호출은 reject하지 않고 기본값으로 resolve됩니다. 개발 중에 호출이 왜 실패했는지 보려면 다음을 설정합니다.
import {configureSDKErrorLogging} from "@sophonz/react-native";
configureSDKErrorLogging({
enabled: __DEV__,
allowLogToConsole: true,
customHandler: (method, error) => {
// 자체 진단 도구로 전달
},
});| 옵션 | 기본값 | 설명 |
|---|---|---|
enabled | false | SDK 호출 실패를 보고합니다 |
allowLogToConsole | false | console.error로 출력합니다 |
customHandler | 없음 | 메서드 이름과 에러를 받아 호출됩니다 |