설정

플랫폼별 앱 아이덴티티, 컬렉터 URL과 앱 키의 위치, iOS가 이를 결정하는 순서, initialize와 sdkConfig, sophonz-config.json, Expo 설정 플러그인의 모든 옵션을 설명합니다.

두 플랫폼은 설정하는 위치가 다릅니다. 그 아래의 네이티브 SDK가 그렇게 되어 있기 때문입니다. Android는 빌드 시점에 sophonz-config.json으로 설정하며 런타임에 넘기는 값은 없습니다. iOS는 시작 시점에 JavaScript, Sophonz-Info.plist, 네이티브 코드 중 하나로 설정합니다.

아이덴티티

기기가 보내는 모든 배치에는 컬렉터가 어느 앱의 데이터인지 알 수 있게 하는 리소스 속성이 붙습니다.

속성의미AndroidiOS
service.key포털이 발급한 앱 키(sk_...)sdk_config.ingest.service_keyappKey / AppKey
service.name앱이 등록된 이름패키지 이름appName / AppName, 기본값은 번들 식별자
service.namespace프로젝트sdk_config.ingest.service_namespaceproject / Project
deployment.environment.name환경sdk_config.ingest.deployment_environmentdeploymentEnvironment / DeploymentEnvironment, 기본값은 production
컬렉터텔레메트리를 보낼 곳sdk_config.ingest.collector_urlcollectorUrl / 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 항목이 없습니다.

android/app/src/main/sophonz-config.json
{
  "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_namespaceservice.namespace
ingest.deployment_environmentdeployment.environment.name
app_frameworkReact Native 앱은 react_native로 설정합니다

service_key와 collector_url은 빌드 시점의 SOPHONZ_SERVICE_KEY, SOPHONZ_COLLECTOR_URL 환경 변수로도 지정할 수 있으므로 키를 커밋하지 않아도 됩니다. 둘 다 있으면 파일의 값이 우선합니다.

React Native 앱에서 특히 중요한 키

나머지 옵션은 네이티브 앱과 같으며 Android 설정에 정리되어 있습니다. 파서가 모르는 키가 있으면 빌드가 실패합니다.

키기본값React Native에서 중요한 이유
sdk_config.networking.enable_traceparent_injectionfalsefetch로 보내는 요청에 traceparent를 붙입니다. 네트워크 참고
sdk_config.networking.traceparent_only_allow_domains없음traceparent를 받을 호스트를 제한합니다
sdk_config.networking.enable_network_span_forwardingfalse수집한 요청 스팬과 수동으로 기록한 요청 스팬에 spz.w3c_traceparent를 붙입니다
sdk_config.networking.disabled_url_patterns[]수집하지 않을 URL의 정규식. 두 번째 OTLP 백엔드 같은 곳
sdk_config.view_config.enable_automatic_activity_capturetrueReact Native 앱은 보통 Activity가 하나뿐입니다. 내비게이션 패키지로 화면을 기록한다면 끄세요
ndk_enabledtrue네이티브 크래시 수집. Hermes 등 C++ 라이브러리 안의 크래시도 여기에 해당합니다
api_token, app_id없음텔레메트리가 아니라 빌드 시점 업로드용 인증 정보입니다. 설정하기 전에 릴리스 빌드를 읽으세요

iOS: 아이덴티티를 정하는 순서

JavaScript가 SDK를 시작할 때 네이티브 모듈은 다음 중 먼저 사용할 수 있는 것을 고릅니다.

  1. sdkConfig.ios.collectorUrl 와 sdkConfig.ios.appKey
  2. 앱 번들 안의 Sophonz-Info.plist(최소한 CollectorURL과 AppKey가 있을 것)
  3. @sophonz/react-native-otlp의 OTLP 익스포터만(Sophonz 컬렉터 없음)
  4. 아무것도 없음: 시작이 실패하고 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를 빼세요.

ios/MyApp/Sophonz-Info.plist
<?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>
인자타입기본값설명
sdkConfigSDKConfig{}아래의 시작 옵션
patchstring없음JavaScript 패치 번호로 기록됩니다. 네이티브 버전이 바뀌지 않는 OTA 업데이트에 쓰세요
logLevel"info", "warn", "error""info"JavaScript 계층의 콘솔 출력. 에러는 항상 출력됩니다

useSophonz(sdkConfig, patch?, logLevel?)는 같은 값을 순서대로 받습니다.

sdkConfig 레퍼런스

옵션타입플랫폼기본값설명
ios.collectorUrlstringiOS—컬렉터 기본 URL. /v1/...는 넣지 않습니다
ios.appKeystringiOS—앱 키, service.key
ios.appNamestringiOS번들 식별자service.name
ios.projectstringiOS—service.namespace
ios.deploymentEnvironmentstringiOSproductiondeployment.environment.name
ios.disableCrashReporterbooleaniOSfalse크래시 리포터를 설치하지 않습니다
ios.disableAutomaticViewCapturebooleaniOSfalseUIViewController 화면을 수집하지 않습니다
ios.disableNetworkSpanForwardingbooleaniOSfalse어떤 요청에도 traceparent를 붙이지 않고, 수동으로 기록한 요청에 spz.w3c_traceparent도 붙이지 않습니다
ios.disabledUrlPatternsstring[]iOS[]URL에 이 문자열 중 하나가 들어 있는 요청은 수집하지 않습니다
exportersOTLPExporterConfig양쪽—추가 OTLP 익스포터. @sophonz/react-native-otlp 필요. OpenTelemetry와 OTLP 참고
trackUnhandledRejectionsboolean양쪽false처리되지 않은 Promise 거부를 기록합니다

SDKConfig 타입에는 logLevel 필드도 선언되어 있지만 initialize는 이 값을 읽지 않습니다. logLevel은 sdkConfig 옆에 넘기세요.

네이티브 시작 후에도 적용되는 것

MainApplication이나 SophonzInitializer가 SDK를 이미 시작했다면 initialize는 자체 시작을 건너뜁니다. 이때 ios 옵션과 exporters는 경고 없이 무시됩니다. 다음은 여전히 적용됩니다.

  • trackUnhandledRejections
  • patch
  • 전역 JS 에러 핸들러, React Native와 SDK 버전
  • iOS 릴리스 빌드의 JS 번들 식별자

시작 설정은 네이티브 코드에 두세요. Android는 sophonz-config.json, iOS는 Sophonz.Options나 Sophonz-Info.plist입니다.

익스포터 필드

요약만 적습니다. 자세한 설명은 OpenTelemetry와 OTLP에 있습니다.

필드타입설명
traceExporter.endpoint, logExporter.endpointstring/v1/traces 또는 /v1/logs까지 포함한 전체 URL
headers{key, token}[]모든 전송에 붙는 헤더
timeoutnumber초 단위

Tracer provider 옵션

useSophonzNativeTracerProvider(config?, enabled?)와 new SophonzNativeTracerProvider(config?)는 다음 옵션을 받습니다.

옵션타입기본값설명
spanContextSyncBehaviour"return_empty" 또는 "throw""return_empty"네이티브 쪽 응답 전에 span.spanContext()를 호출했을 때의 동작
setGlobalContextManagerbooleanconfig를 넘기지 않으면 true, 넘기면 falseprovider의 컨텍스트 매니저를 @opentelemetry/api에 등록합니다

{}를 넘기면 전역 컨텍스트 매니저가 꺼집니다. OpenTelemetry와 OTLP를 참고하세요.

Expo 설정 플러그인

속성필수설명
androidAppKey예sdk_config.ingest.service_key에 기록됩니다
iOSAppKey예SophonzInitializer.swift의 Sophonz.Options.withCollector(appKey:)에 전달됩니다
collectorUrl두 플랫폼 공통. 기본값은 https://in.sophonz.ai
iOSAppNameiOS service.name
project두 플랫폼의 service.namespace
deploymentEnvironment두 플랫폼의 deployment.environment.name
androidSDKConfigsdk_config에 병합할 추가 키. 예를 들어 networking이나 view_config. 여기에 ingest 객체를 넣으면 생성된 값을 대체합니다
productModuleNameiOS PRODUCT_MODULE_NAME이 프로젝트 이름과 다를 때 지정합니다. Objective-C AppDelegate가 올바른 Swift 헤더를 import하게 됩니다
iOSUseSPMtrue면 Apple SDK를 Swift Package Manager에서 가져옵니다. expo-build-properties의 ios.useFrameworks: "dynamic"이 필요합니다

androidAppKey나 iOSAppKey가 없거나 iOSUseSPM이 boolean이 아니면 prebuild가 실패합니다. 그 밖에 플러그인이 만나는 문제는 경고로만 보고되고 prebuild는 계속됩니다.

app.json
{
  "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 install

Expo에서는 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) => {
    // 자체 진단 도구로 전달
  },
});
옵션기본값설명
enabledfalseSDK 호출 실패를 보고합니다
allowLogToConsolefalseconsole.error로 출력합니다
customHandler없음메서드 이름과 에러를 받아 호출됩니다