API를 통해 업로드 크래시
중요
Visual Studio App Center는 2025년 3월 31일에 사용 중지될 예정입니다. Visual Studio App Center가 완전히 사용 중지될 때까지 계속 사용할 수 있지만 마이그레이션을 고려할 수 있는 몇 가지 권장 대안이 있습니다.
SDK를 사용하거나 사용자 지정 플랫폼용으로 개발하지 않으려면 크래시 보고서를 업로드할 수 있습니다. App Center에 크래시, 오류 또는 첨부 파일 로그를 업로드하고 App Center 진단 UI에서 세부 정보를 확인합니다. 다음 섹션에서는 크래시, 오류 및 첨부 파일을 업로드하는 방법을 설명합니다.
참고
App Center는 고유 앱당 분당 최대 60개의 크래시 및 처리된 오류만 허용합니다. 이 제한을 초과하는 충돌 또는 오류는 수집하지 않습니다.
보고서를 업로드하려면 다음 헤더를 사용하여 에서 https://in.appcenter.ms/logs?Api-Version=1.0.0
App Center 수집 엔드포인트를 호출합니다.
-
Content-Type
: 본문의 형식을 설명합니다. App Center는 현재 JSON 형식만 지원합니다. -
App-Secret
: 각 앱의 고유 식별자인 문자열입니다. 앱 설정에서 앱 비밀을 찾을 수 있습니다. -
Install-ID
: 개수를 추적하는 데 사용되는 GUID일 수 있는 문자열입니다.
로그 속성:
-
type
: 로그 형식의 필수 문자열 - Apple 충돌의 경우 "appleError", 다른 충돌의 경우 "managedError", 오류의 경우 "handledError", 오류 첨부 파일의 경우 "errorAttachment"입니다. -
timestamp
: 로그 타임스탬프 날짜-시간이 있는 선택적 문자열(예: "2017-03-13T18:05:42Z") - 설정된 경우 수집 시간 이후 최대 72시간이어야 합니다. -
appLaunchTimestamp
: 앱이 시작된 타임스탬프 날짜-시간을 지정하는 필수 문자열입니다(예: "2017-03-13T18:05:42Z"). -
device
: 디바이스 특성을 가진 필수 개체-
appVersion
: 애플리케이션 버전 이름을 가진 필수 문자열(예: "1.1.0") -
appBuild
: 애플리케이션 빌드 번호가 있는 필수 문자열(예: "42") -
sdkName
: SDK의 이름을 가진 필수 문자열입니다. SDK 및 플랫폼의 이름(예: Android의 경우 "appcenter.android", 사용자 지정 플랫폼의 경우 "appcenter.custom")으로 구성됩니다. -
sdkVersion
: 의미 체계 버전 관리 형식의 SDK 버전이 있는 필수 문자열(예: "1.2.0" 또는 "0.12.3-alpha.1") -
osName
: OS 이름을 가진 필수 문자열(예: "android") -
osVersion
: OS 버전이 있는 필수 문자열(예: "9.3.0") -
model
: 디바이스 모델이 있는 선택적 문자열(예: "iPad2") -
locale
: 언어 코드가 있는 필수 문자열(예: "en-US") -
timeZoneOffset
: 디바이스 표준 시간대에 대한 UTC(협정 세계시)의 선택적 오프셋(분)(-840~840)입니다. 일광 절약 시간(예: 120)을 포함합니다.
-
-
userId
: 로그를 사용자와 연결하기 위해 사용되는 선택적 문자열입니다. -
exception
: 예외 세부 정보가 있는 필수 개체-
type
: 예외 형식의 필수 문자열 -
frame
: 스택 프레임이 있는 선택적 배열 -
message
: 예외가 있는 선택적 문자열 -
stackTrace
: 원시 스택 추적이 있는 선택적 문자열 -
innerException
: 내부 예외가 있는 선택적 배열
-
아래에서 크래시 보고서, 오류 보고서 및 첨부 파일을 업로드하는 방법의 예를 찾을 수 있습니다. 더 많은 사양을 보려면 여기에서 전체 파일을 찾을 수 있습니다.
참고
보존 정책으로 인해 보고서는 timestamp
지난 25일 또는 향후 3일 이내여야 합니다.
크래시 보고서 업로드
크래시 보고서를 업로드하려면 다음 속성이 필요합니다.
-
processId
: 프로세스 식별자가 있는 필수 정수 -
id
: 예외 식별자를 사용하는 필수 문자열이며 이 보고서의 고유 ID여야 합니다. -
fatal
: 예외로 인해 크래시가 발생했는지 여부를 나타내는 필수 부울 -
processName
: 프로세스 이름을 가진 필수 문자열 -
appNamespace
: Android 앱에 필요하며, 사용되는 플랫폼에 따라 번들 식별자, 패키지 식별자 또는 네임스페이스가 있는 선택적 문자열이 필요합니다.
Apple 형식 이외의 크래시 보고서를 업로드하려면 로그 형식이 "managedError"로 설정되어 있는지 확인합니다.
curl -X POST \
'https://in.appcenter.ms/logs?Api-Version=1.0.0' \
-H 'Content-Type: application/json' \
-H 'app-secret: <app secret>' \
-H 'install-id: 00000000-0000-0000-0000-000000000001' \
-d '{
"logs": [
{
"type": "managedError",
"timestamp": "2019-10-08T04:22:23.516Z",
"appLaunchTimestamp": "2019-09-29T22:22:23.516Z",
"processId": "123",
"id": "bca65f46-46ee-451b-83bb-2e358c3f45bf",
"fatal": true,
"processName": "com.microsoft.appcenter.demo.project",
"device": {
"appVersion": "12.0",
"appBuild": "1",
"sdkName": "custom.android",
"sdkVersion": "1.0.0",
"osName": "android",
"osVersion": "9.3",
"model": "Pixel",
"locale": "en-US",
"appNamespace": "com.contoso.myapp"
},
"userId": "TestID",
"exception": {
"type": "java.lang.RuntimeException",
"frames": [
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2575,
"methodName": "performResumeActivity"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2603,
"methodName": "handleResumeActivity"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2089,
"methodName": "handleLaunchActivity"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 130,
"methodName": "access$600"
},
{
"className": "android.app.ActivityThread$H",
"fileName": "ActivityThread.java",
"lineNumber": 1195,
"methodName": "handleMessage"
},
{
"className": "android.os.Handler",
"fileName": "Handler.java",
"lineNumber": 99,
"methodName": "dispatchMessage"
},
{
"className": "android.os.Looper",
"fileName": "Looper.java",
"lineNumber": 137,
"methodName": "loop"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 4745,
"methodName": "main"
}
],
"innerExceptions": [
{
"type": "java.lang.RuntimeException",
"frames": [
{
"className": "android.app.Activity",
"fileName": "Activity.java",
"lineNumber": 5084,
"methodName": "performResume"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2565,
"methodName": "performResumeActivity"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2603,
"methodName": "handleResumeActivity"
}
]
}
]
}
}
]
}'
Apple 크래시 로그 업로드
Apple 크래시 로그를 업로드하려면 로그 유형이 "appleError"로 설정되어 있는지 확인합니다. 다음 속성도 필요합니다.
-
primaryArchitectureId
: CPU 기본 아키텍처를 사용하는 필수 정수 -
applicationPath
: 애플리케이션 경로가 있는 필수 문자열 -
osExceptionType
: OS 예외 형식의 필수 문자열 -
osExceptionCode
: OS 예외 코드가 있는 필수 문자열 -
osExceptionAddress
: OS 예외 주소가 있는 필수 문자열 -
binaries
: 오류에 연결된 이진 파일이 있는 필수 배열
예를 들면 다음과 같습니다.
curl -X POST \
'https://in.appcenter.ms/logs?Api-Version=1.0.0' \
-H 'Content-Type: application/json' \
-H 'app-secret: <app secret>' \
-H 'install-id: 00000000-0000-0000-0000-000000000001' \
-d '{
"logs":
[
{
"type": "appleError",
"timestamp": "2019-10-08T02:44:55.000Z",
"appLaunchTimestamp": "2019-09-29T22:22:23.516Z",
"id": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
"applicationPath": "iOS/salesforce",
"osExceptionType": "CustomerIssue (TestIssue)",
"osExceptionCode": "0",
"osExceptionAddress": "0x00",
"processName": "salesforce",
"fatal": true,
"isTestMessage": false,
"device": {
"appVersion": "10.0",
"appBuild": "1",
"sdkName": "custom.ios",
"sdkVersion": "1.0.0",
"osName": "iOS",
"osVersion": "9.3",
"model": "iPhone9,1",
"locale": "en-US"
},
"userId": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
"fatal": true,
"threads": [
{
"id": 0,
"frames": [
{
"address": "0x000000018ada4d70",
"code": "0x18ad87000 + 122224"
},
{
"address": "0x0000000104463884",
"code": "0x10445c000 + 30852"
},
{
"address": "0x000000010438f640",
"code": "0x104388000 + 30272"
},
{
"address": "0x00000001b859fb64",
"code": "0x1b8229000 + 3631972"
}
]
},
{
"id": 1,
"frames": [
{
"address": "0x000000018bb4fce0",
"code": "0x18baa2000 + 711904"
},
{
"address": "0x000000018bbf7078",
"code": "0x18baa2000 + 1396856"
},
{
"address": "0x000000018baa8258",
"code": "0x18baa2000 + 25176"
},
{
"address": "0x000000018bb1c49c",
"code": "0x18baa2000 + 500892"
}
]
},
{
"id": 3,
"frames": [
{
"address": "0x000000018b755b9c",
"code": "0x18b732000 + 146332"
},
{
"address": "0x000000018b7dcd00",
"code": "0x18b7ce000 + 60672"
}
]
}
],
"binaries": [
{
"id": "d449e33d-7e74-379d-8b79-15ee104ed1df",
"startAddress": "0x0000000104388000",
"endAddress": "0x0000000104413fff",
"name": "CrashProbeiOS",
"path": "/var/containers/Bundle/Application/023013EA-0D58-4F6D-8B98-49E1372F4044/CrashProbeiOS.app/CrashProbeiOS",
"primaryArchitectureId": 16777228,
"architectureVariantId": 0
},
{
"id": "5da23653-d126-39f0-bdcf-994b3019f92c",
"startAddress": "0x000000010445c000",
"endAddress": "0x0000000104467fff",
"name": "CrashLibiOS",
"path": "/private/var/containers/Bundle/Application/023013EA-0D58-4F6D-8B98-49E1372F4044/CrashProbeiOS.app/Frameworks/CrashLibiOS.framework/CrashLibiOS",
"primaryArchitectureId": 16777228,
"architectureVariantId": 0
}
]
}
]
}'
사용자 지정 크래시 로그 업로드
사용자 지정 플랫폼에 대한 크래시 를 업로드하려면 로그 형식이 "managedError"로 설정되고 sdkName이 "appcenter.custom"으로 설정되어 있는지 확인합니다. 예를 들면 다음과 같습니다.
curl -X POST \
'https://in.appcenter.ms/logs?Api-Version=1.0.0' \
-H 'Content-Type: application/json' \
-H 'app-secret: <app secret>' \
-H 'install-id: 00000000-0000-0000-0000-000000000001' \
-d '{
"logs": [
{
"type": "managedError",
"id": "a7bea41b-1e4d-4e42-ae76-1025f4fdfc4f",
"userId": "TestID",
"timestamp": "2019-11-26T02:00:04Z",
"appLaunchTimestamp": "2019-11-26T02:00:04Z",
"architecture": "armeabi-v7a",
"fatal": true,
"processId": 4871,
"processName": "com.microsoft.appcenter.sasquatch.project",
"sid": "bca65f46-46ee-451b-83bb-2e358c3f45bf",
"errorThreadId": 1,
"errorThreadName": "main",
"device": {
"appBuild": "1337",
"appVersion": "7.1.0",
"appNamespace": "com.microsoft.appcenter.sasquatch.project",
"carrierCountry": "us",
"locale": "en_US",
"model": "Galaxy Nexus",
"oemName": "samsung",
"osApiLevel": 16,
"osBuild": "JRO03O",
"osName": "Android",
"osVersion": "5.0.0",
"screenSize": "720x1184",
"sdkName": "appcenter.custom",
"sdkVersion": "1.9.1",
"timeZoneOffset": -480
},
"exception": {
"frames": [
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2575,
"methodName": "performResumeActivity"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2603,
"methodName": "handleResumeActivity"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2089,
"methodName": "handleLaunchActivity"
}
],
"innerExceptions": [
{
"frames": [
{
"className": "android.app.CustomActivity",
"fileName": "CustomActivity.java",
"lineNumber": 8673,
"methodName": "performCustomResume"
},
{
"className": "android.app.ActivityThread",
"fileName": "ActivityThread.java",
"lineNumber": 2565,
"methodName": "performResumeActivity"
}
],
"message": "Activity {com.microsoft.appcenter.sasquatch.project/com.microsoft.appcenter.sasquatch.activities.CrashSubActivity2} did not call through to super.onResume()",
"type": "android.app.CustomNotCalledException"
}
],
"message": "Unable to resume activity {com.microsoft.appcenter.sasquatch.project/com.microsoft.appcenter.sasquatch.activities.CrashSubActivity2}: android.app.SuperNotCalledException: Activity {com.microsoft.appcenter.sasquatch.project/com.microsoft.appcenter.sasquatch.activities.CrashSubActivity2} did not call through to super.onResume()",
"type": "java.lang.RuntimeException"
},
"threads": [
{
"frames": [
{
"className": "dalvik.system.NativeStart",
"fileName": "NativeStart.java",
"lineNumber": -2,
"methodName": "run"
}
],
"id": 369,
"name": "Binder_3"
},
{
"frames": [
{
"className": "dalvik.system.NativeStart",
"fileName": "NativeStart.java",
"lineNumber": -2,
"methodName": "run"
}
],
"id": 345,
"name": "Compiler"
}
]
}
]
}'
중단 패드 크래시 로그 및 미니덤프 업로드
Android 및 Windows용 사용자 지정 중단 패드 크래시 업로드할 수 있습니다. 예를 들면 다음과 같습니다.
curl -X POST \
'https://in.appcenter.ms/logs?Api-Version=1.0.0' \
-H 'Content-Type: application/json' \
-H 'app-secret: <app secret>' \
-H 'install-id: 00000000-0000-0000-0000-000000000001' \
-d '{
"logs":
[
{
"type": "managedError",
"id": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
"userId": "TestID",
"processId": 9448,
"processName": "Contoso.UWP.Puppet.exe",
"fatal": true,
"timestamp": "2019-10-08T06:22:23.530Z",
"architecture": "X64",
"timestamp": "2019-10-08T06:22:23.516Z",
"sid": "d4608adf-83b9-4f69-90ad-8bb0234080a7",
"device": {
"sdkName": "appcenter.custom",
"sdkVersion": "2.4.1-SNAPSHOT",
"model": "Parallels Virtual Platform",
"oemName": "Parallels Software International Inc.",
"osName": "WINDOWS",
"osVersion": "10.0.18363",
"osBuild": "10.0.18363.418",
"locale": "en-US",
"timeZoneOffset": -300,
"screenSize": "4608x2470",
"appVersion": "1.0",
"appBuild": "1.0",
"appNamespace": "10805zumoTestUser.AppCenter-Contoso.UWP.Puppet",
"carrierCountry": "us",
"wrapperSdkName": "custom.ndk"
},
"exception": {
"type": "minidump",
"wrapperSdkName": "custom.ndk"
}
},
{
"contentType": "application/octet-stream",
"errorId": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
"fileName": "minidump.dmp",
"id": "7b975468-5656-40a5-8242-c1907b26fc31",
"sid": "03693776-cdd4-46b8-bbda-12af457f1732",
"timestamp": "2019-10-08T06:22:23.516Z",
"type": "errorAttachment",
"device": {
"sdkName": "appcenter.custom",
"sdkVersion": "2.4.1-SNAPSHOT",
"model": "Parallels Virtual Platform",
"oemName": "Parallels Software International Inc.",
"osName": "WINDOWS",
"osVersion": "10.0.18363",
"osBuild": "10.0.18363.418",
"locale": "en-US",
"timeZoneOffset": -300,
"screenSize": "4608x2470",
"appVersion": "1.0",
"appBuild": "1.0",
"appNamespace": "10805zumoTestUser.AppCenter-Contoso.UWP.Puppet",
"carrierCountry": "us",
"wrapperSdkName": "custom.ndk"
},
"data": "<base64 encoded minidump>"
}
]
}'
제한 사항
중단 패드 충돌을 wrapperSdkName
업로드하려면 필드를 "custom.ndk"로 설정해야 하며 미니덤프 파일을 크래시 보고서에 첨부 파일로 첨부해야 합니다. 이 페이지의 첨부 파일 섹션에서 첨부 파일을 보내는 방법을 알아봅니다.
충돌을 심볼화하려면 API 문서에 따라 CLI 또는 API를 통해 기호를 업로드해야 합니다. Android에서 Breakpad를 사용하는 경우 Android NDK 문서에 지정된 두 옵션이 모두 지원됩니다. Windows에서 Breakpad를 사용하는 경우 옵션 2: "중단 패드 기호 업로드"만 지원됩니다.
참고
macOS에서 기호를 업로드하는 경우 불필요한 폴더의 기호를 클린 합니다(예: __MACOS 생성되고 이를 삭제하려면 를 사용할 zip -d <symbols.zip> __MACOSX/\*
수 있음).
오류 보고서 업로드
처리된 오류는 현재 Android, Xamarin, Unity, UWP, WPF 및 WinForms 앱에서만 지원됩니다. 오류 보고서를 업로드하려면 로그 형식이 "handledError"로 설정되어 있는지 확인합니다.
curl -X POST \
'https://in.appcenter.ms/logs?Api-Version=1.0.0' \
-H 'Content-Type: application/json' \
-H 'app-secret: <app secret>' \
-H 'install-id: 00000000-0000-0000-0000-000000000001' \
-d '{
"logs":
[
{
"type": "handledError",
"timestamp": "2019-10-08T06:22:23.516Z",
"appLaunchTimestamp": "2019-09-29T22:22:23.516Z",
"id": "118dee14-9193-4ac3-9ef0-f6c11b43f2c4",
"device": {
"appVersion": "11.0",
"appBuild": "1",
"sdkName": "custom.android",
"sdkVersion": "1.0.0",
"osName": "android",
"osVersion": "9.3",
"model": "Pixel",
"locale": "en-US"
},
"userId": "TestID",
"exception": {
"type": "System.IO.IOException",
"message": "Server did not respond",
"stackTrace": " at Contoso.Forms.Puppet.FakeService+<>c.<DoStuffInBackground>b__0_0 () [0x00000] in <7ad93f134a5d4c00a8db8be9aa9c0f76>:0 \n at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in <b38d4262627948c1b945a72f56ce6466>:0 \n at System.Threading.Tasks.Task.Execute () [0x00010] in <b38d4262627948c1b945a72f56ce6466>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <b38d4262627948c1b945a72f56ce6466>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <b38d4262627948c1b945a72f56ce6466>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <b38d4262627948c1b945a72f56ce6466>:0",
"innerExceptions": [
{
"type": "System.IO.IOException",
"message": "Network down",
"stackTrace": " at Contoso.Forms.Demo.CrashesContentPage.SendHttp () [0x00002] in <4fd9174f6e18457b9721bfba2cd78098>:0 ",
"wrapperSdkName": "appcenter.xamarin"
},
{
"type": "System.ArgumentException",
"message": "Invalid parameter",
"innerExceptions": [
{
"type": "System.ArgumentOutOfRangeException",
"message": "It is over 9000!",
"stackTrace": " at Contoso.Forms.Demo.CrashesContentPage.ValidateLength () [0x00002] in <4fd9174f6e18457b9721bfba2cd78098>:0 ",
}
],
}
],
}
}
]
}'
첨부 파일 업로드
모든 첨부 파일은 크래시 보고서와 연결되어야 합니다. 한 번의 호출 또는 두 번의 별도 호출에서 크래시 보고서를 사용하여 첨부 파일을 업로드할 수 있습니다.
첨부 파일 관련 속성:
-
contentType
: 콘텐츠 형식이 있는 필수 문자열(예: 텍스트의 경우 "text/plain")입니다. 여기에서 지원되는 형식의 예제를 찾을 수 있습니다. -
data
: 데이터가 base 64로 인코딩된 필수 문자열 -
errorId
: 첨부 파일의 연결된 오류 보고서의 고유 식별자를 포함하는 필수 문자열 -
fileName
: "minidump.dmp"로 설정된 NDK 크래시의 필수 문자열
참고
첨부 파일의 크기 제한은 현재 7MB입니다. 더 큰 첨부 파일을 보내려고 하면 오류가 트리거됩니다.
다음은 한 번의 호출로 크래시 보고서와 첨부 파일을 업로드하는 예제입니다.
curl -X POST \
'https://in.appcenter.ms/logs?Api-Version=1.0.0' \
-H 'Content-Type: application/json' \
-H 'app-secret: <app secret>' \
-H 'install-id: 00000000-0000-0000-0000-000000000001' \
-d '{
"logs": [
{
"type": "managedError",
"timestamp": "2019-10-01T02:22:23.516Z",
"appLaunchTimestamp": "2019-09-29T22:22:23.516Z",
"id": "bca65f46-46ee-451b-83bb-2e358c3f45bf",
"fatal": true,
"processName": "com.microsoft.appcenter.sasquatch.project",
"device": {
"appVersion": "13.0",
"appBuild": "1",
"sdkName": "appcenter.android",
"sdkVersion": "1.0.0",
"osName": "android",
"osVersion": "9.3",
"model": "Pixel",
"locale": "en-US"
},
"userId": "118dee14",
"fatal": true,
"exception": {
"type": "CustomerIssue",
"frames": []
}
},
{
"type": "errorAttachment",
"contentType": "text/plain",
"timestamp": "2019-10-01T02:22:23.516Z",
"data": "aGVsbG8=",
"errorId": "bca65f46-46ee-451b-83bb-2e358c3f45bf",
"id": "7caaea8e-dab1-4588-993c-95de2d9a4fd1",
"device": {
"appVersion": "13.0",
"appBuild": "1",
"sdkName": "appcenter.android",
"sdkVersion": "1.0.0",
"osName": "android",
"osVersion": "9.3",
"model": "Pixel",
"locale": "en-US"
}
}
]
}'