Sources/CrashReporter2/CrashReporterOTel.swift (99 lines of code) (raw):

// // Copyright 2023 aliyun-sls Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import Foundation import OpenTelemetryApi import OpenTelemetrySdk import AliyunLogOtlpExporter //import AliyunLogCore #if canImport(UIKit) import UIKit #elseif canImport(AppKit) import AppKit #endif import AliyunLogOTelCommon internal class CrashReporterOTel { static let VERSION: String = "0.1.0" static let SCOPE: String = "uem" static var tracerProvider: TracerProviderSdk? public init() { } func initOtel() { let scope = CrashReporterOTel.SCOPE let workspace = ConfigurationManager.shared.workspaceProvider?(scope) let accessKey = ConfigurationManager.shared.accessKeyProvider?(scope) let environment = ConfigurationManager.shared.environmentProvider?(scope) let otlpSLSExporter = OtlpSLSSpanExporter.builder(scope) .setEndpoint(workspace?.endpoint ?? "") .setProject(workspace?.project ?? "") .setLogstore("\(workspace?.instanceId ?? "")-uem-mobile-raw") .setPersistentFlush(true) .setAccessKey( accessKeyId: accessKey?.accessKeyId, accessKeySecret: accessKey?.accessKeySecret, accessKeyToken: accessKey?.accessKeySecuritToken ) .build() let spanExporters = MultiSpanExporter(spanExporters: [otlpSLSExporter]) let spanProcessor = BatchSpanProcessor(spanExporter: spanExporters) var appName: String? = "" var appVersion: String? = "" var appVersionCode: String? = "" if let infoDictionary = Bundle.main.infoDictionary { appName = infoDictionary["CFBundleDisplayName"] as? String ?? infoDictionary["CFBundleName"] as? String appVersion = infoDictionary["CFBundleShortVersionString"] as? String appVersionCode = infoDictionary["CFBundleVersion"] as? String } #if os(iOS) let osName = "iOS" #elseif os(macOS) let osName = "macOS" #elseif os(tvOS) let osName = "tvOS" #elseif os(watchOS) let osName = "watchOS" #else let osName = "unknown" #endif let utdid = environment?.utdid ?? Utdid.getUtdid() #if canImport(UIKit) let systemVersion = AttributeValue.string(UIDevice.current.systemVersion) #elseif canImport(AppKit) let version = ProcessInfo.processInfo.operatingSystemVersion let systemVersion = AttributeValue.string("\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)") #else let systemVersion = "unknown" #endif CrashReporterOTel.tracerProvider = TracerProviderBuilder() .add(spanProcessor: spanProcessor) .with(resource: Resource() .merging(other: Resource(attributes: [ ResourceAttributes.serviceName.rawValue: AttributeValue.string("sls-cocoa"), ResourceAttributes.deviceId.rawValue: AttributeValue.string(utdid), ResourceAttributes.deviceManufacturer.rawValue: AttributeValue.string("Apple"), ResourceAttributes.deviceModelName.rawValue: AttributeValue.string(DeviceUtils.getDeviceModel()), ResourceAttributes.deviceModelIdentifier.rawValue: AttributeValue.string(DeviceUtils.getDeviceModelIdentifier()), "device.screen": AttributeValue.string(DeviceUtils.getResolution()), "app.version": AttributeValue.string(appVersion ?? ""), "app.versionCode": AttributeValue.string(appVersionCode ?? ""), "app.name": AttributeValue.string(appName ?? ""), ResourceAttributes.osName.rawValue: AttributeValue.string(osName), ResourceAttributes.osType.rawValue: AttributeValue.string("darwin"), ResourceAttributes.osVersion.rawValue: systemVersion, ResourceAttributes.osDescription.rawValue: AttributeValue.string("Apple Darwin"), ResourceAttributes.hostName.rawValue: AttributeValue.string(ProcessInfo.processInfo.hostName), ResourceAttributes.hostArch.rawValue: AttributeValue.string(DeviceUtils.getCPUArch()), "uem.data.type": AttributeValue.string(osName), "uem.sdk.version": AttributeValue.string(CrashReporterOTel.VERSION), "workspace": AttributeValue.string(workspace?.instanceId ?? ""), "deployment.environment": AttributeValue.string(environment?.env ?? "default"), "deployment.channel": AttributeValue.string(environment?.channel ?? "default") ])) ) .build() } static func spanBuilder(_ spanName: String) -> SpanBuilder? { CrashReporterOTel.tracerProvider? .get(instrumentationName: "CrashReporter", instrumentationVersion: CrashReporterOTel.VERSION) .spanBuilder(spanName: spanName) } static func forceFlush() { CrashReporterOTel.tracerProvider?.forceFlush() } }