forked from github/CopilotForXcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGithubPanicErrorReporter.swift
More file actions
95 lines (86 loc) · 3.67 KB
/
GithubPanicErrorReporter.swift
File metadata and controls
95 lines (86 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import Foundation
import TelemetryServiceProvider
public class GitHubPanicErrorReporter {
private static let panicEndpoint = URL(string: "https://copilot-telemetry.githubusercontent.com/telemetry")!
private static let sessionId = UUID().uuidString
private static let standardChannelKey = Bundle.main
.object(forInfoDictionaryKey: "STANDARD_TELEMETRY_CHANNEL_KEY") as! String
// Helper: Format current time in ISO8601 style
private static func currentTime() -> String {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSX"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter.string(from: Date())
}
// Helper: Create failbot payload JSON string and update properties
private static func createFailbotPayload(
for request: TelemetryExceptionRequest,
properties: inout [String: Any]
) -> String? {
let payload: [String: Any] = [
"context": [:],
"app": "copilot-xcode",
"catalog_service": "CopilotXcode",
"release": "copilot-xcode@\(properties["common_extversion"] ?? "0.0.0")",
"rollup_id": "auto",
"platform": "macOS",
"exception_detail": request.exceptionDetail?.toDictionary() ?? []
]
guard let data = try? JSONSerialization.data(withJSONObject: payload, options: []) else {
return nil
}
return String(data: data, encoding: .utf8)
}
// Helper: Create payload with a channel input, but always using standard telemetry key.
private static func createPayload(
for request: TelemetryExceptionRequest,
properties: inout [String: Any]
) -> [String: Any] {
// Build and add failbot payload to properties
if let payloadString = createFailbotPayload(for: request, properties: &properties) {
properties["failbot_payload"] = payloadString
}
properties["common_vscodesessionid"] = sessionId
properties["client_sessionid"] = sessionId
let baseData: [String: Any] = [
"ver": 2,
"severityLevel": "Error",
"name": "agent/error.exception",
"properties": properties,
"exceptions": [],
"measurements": [:]
]
return [
"ver": 1,
"time": currentTime(),
"severityLevel": "Error",
"name": "Microsoft.ApplicationInsights.standard.Event",
"iKey": standardChannelKey,
"data": [
"baseData": baseData,
"baseType": "ExceptionData"
]
]
}
public static func report(_ request: TelemetryExceptionRequest) async {
do {
var properties: [String : Any] = request.properties ?? [:]
let payload = createPayload(
for: request,
properties: &properties
)
let jsonData = try JSONSerialization.data(withJSONObject: [payload], options: [])
var httpRequest = URLRequest(url: panicEndpoint)
httpRequest.httpMethod = "POST"
httpRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
httpRequest.httpBody = jsonData
let (_, response) = try await URLSession.shared.data(for: httpRequest)
guard let httpResp = response as? HTTPURLResponse, httpResp.statusCode == 200 else {
throw URLError(.badServerResponse)
}
} catch {
print("Fails to send to Panic Endpoint: \(error)")
}
}
}