Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

* Datadog 지원 #56

Merged
merged 5 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public protocol APIBaseRequest {
}

public enum API {
public static var apiBaseURL: String {
public static var apiBaseHost: String {
guard let baseURL = Bundle.main.object(forInfoDictionaryKey: "BASE_URL") as? String else {
fatalError("url missing")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// APIClientURLSessionDelegate.swift
// APIClientInterface
//
// Created by devMinseok on 9/8/24.
// Copyright © 2024 PomoNyang. All rights reserved.
//

import Foundation

final public class APIClientURLSessionDelegate: NSObject, URLSessionDataDelegate {
}
30 changes: 17 additions & 13 deletions Projects/Core/APIClient/Sources/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,27 @@ import Dependencies

extension APIClient: DependencyKey {
public static let liveValue: APIClient = .live()

public static func live() -> Self {

actor Session {
nonisolated let tokenInterceptor: TokenInterceptor

let session: URLSession = {
let config = URLSessionConfiguration.default
return URLSession(configuration: config)
return URLSession(
configuration: config,
delegate: APIClientURLSessionDelegate(),
delegateQueue: nil
)
}()

let decoder: JSONDecoder = JSONDecoder()

init(tokenInterceptor: TokenInterceptor) {
self.tokenInterceptor = tokenInterceptor
}

func sendRequest(
_ request: APIBaseRequest,
isWithInterceptor: Bool,
Expand All @@ -40,21 +44,21 @@ extension APIClient: DependencyKey {
guard retryCnt < 3 else {
throw throwNetworkErr(.timeOutError, statusCode: -1)
}

var urlRequest = try await request.asURLRequest()
if isWithInterceptor {
urlRequest = try await tokenInterceptor.adapt(urlRequest)
}
Logger.shared.log(category: .network, urlRequest.asRequestLog())

let (data, response) = try await session.data(for: urlRequest)

guard let httpResponse = response as? HTTPURLResponse else {
let error = NetworkError.noResponseError
Logger.shared.log(level: .error, category: .network, "API Error:\n\(dump(error))")
throw error
}

switch httpResponse.statusCode {
case 200..<300:
Logger.shared.log(category: .network, urlRequest.asResponseLog(data, httpResponse))
Expand All @@ -76,10 +80,10 @@ extension APIClient: DependencyKey {
return error
}
}

let tokenInterceptor = TokenInterceptor()
let session = Session(tokenInterceptor: tokenInterceptor)

return .init(
apiRequest: { request, isWithInterceptor in
return try await session.sendRequest(request, isWithInterceptor: isWithInterceptor)
Expand Down
2 changes: 1 addition & 1 deletion Projects/Core/APIClient/Sources/TokenInterceptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct TokenInterceptor {
throw NetworkError.authorizationError
}

var urlRequest = URLRequest(url: URL(string: "https://" + API.apiBaseURL)!)
var urlRequest = URLRequest(url: URL(string: "https://" + API.apiBaseHost)!)
urlRequest.httpMethod = HTTPMethod.post.rawValue
urlRequest.setValue(
ContentType.json.rawValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public enum AuthAPIRequest {

extension AuthAPIRequest: APIBaseRequest {
public var baseURL: String {
return API.apiBaseURL
return API.apiBaseHost
}

public var path: String {
Expand Down
2 changes: 1 addition & 1 deletion Projects/Domain/CatService/Interface/API/CatAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public enum CatAPI {

extension CatAPI: APIBaseRequest {
public var baseURL: String {
return API.apiBaseURL
return API.apiBaseHost
}

public var path: String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public enum CategoryAPI {

extension CategoryAPI: APIBaseRequest {
public var baseURL: String {
return API.apiBaseURL
return API.apiBaseHost
}

public var path: String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public enum FocusTimeAPI {

extension FocusTimeAPI: APIBaseRequest {
public var baseURL: String {
return API.apiBaseURL
return API.apiBaseHost
}

public var path: String {
Expand Down
2 changes: 1 addition & 1 deletion Projects/Domain/UserService/Interface/API/UserAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public enum UserAPIrequest {

extension UserAPIrequest: APIBaseRequest {
public var baseURL: String {
return API.apiBaseURL
return API.apiBaseHost
}

public var path: String {
Expand Down
53 changes: 51 additions & 2 deletions Projects/Feature/Feature/Sources/AppDelegateCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ import UserNotificationClientInterface
import KeychainClientInterface
import DatabaseClientInterface
import AppService
import APIClientInterface

import ComposableArchitecture
import FirebaseCore
import FirebaseMessaging
import DatadogCore
import DatadogRUM

@Reducer
public struct AppDelegateCore {
Expand Down Expand Up @@ -48,11 +51,13 @@ public struct AppDelegateCore {
switch action {
case .didFinishLaunching:
UIApplication.shared.applicationIconBadgeNumber = 0
FirebaseApp.configure()
let userNotificationEventStream = userNotificationClient.delegate()
firebaseInitilize()
datadogInitilize()

Logger.shared.log("FCMToken: \(Messaging.messaging().fcmToken ?? "not generated")")

let userNotificationEventStream = userNotificationClient.delegate()

return .run { send in
await withThrowingTaskGroup(of: Void.self) { group in
group.addTask {
Expand Down Expand Up @@ -93,4 +98,48 @@ public struct AppDelegateCore {
return .none
}
}

private func firebaseInitilize() {
FirebaseApp.configure()
}

private func datadogInitilize() {
// TODO: - 환경 값 가져오는 부분 개선하기
guard let appID = Bundle.main.object(forInfoDictionaryKey: "DATADOG_APP_ID") as? String,
let clientToken = Bundle.main.object(forInfoDictionaryKey: "DATADOG_TOKEN") as? String
else { return }

#if DEV
let environment = "dev"
#else
let environment = "prod"
#endif

Datadog.initialize(
with: Datadog.Configuration(
clientToken: clientToken,
env: environment,
site: .us5
),
trackingConsent: .granted
)

RUM.enable(
with: RUM.Configuration(
applicationID: appID,
uiKitViewsPredicate: DefaultUIKitRUMViewsPredicate(),
uiKitActionsPredicate: DefaultUIKitRUMActionsPredicate(),
urlSessionTracking: RUM.Configuration.URLSessionTracking(
firstPartyHostsTracing: .trace(hosts: [API.apiBaseHost], sampleRate: 20)
)
)
)

URLSessionInstrumentation.enable(
with: URLSessionInstrumentation.Configuration(
delegateClass: APIClientURLSessionDelegate.self,
firstPartyHostsTracing: .trace(hosts: [API.apiBaseHost])
)
Comment on lines +139 to +143
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

urlsessiondatadelegate는 왜 따로 생성해서 붙여준거야 ? ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.datadoghq.com/ko/real_user_monitoring/mobile_and_tv_monitoring/setup/ios/?tab=swiftpackagemanagerspm#initialize-the-rum-monitor-and-enable-urlsessioninstrumentation
이 문서 보면 알겠지만 URLSessionDelegate를 통해 datadog sdk에서 네트워크 요청 트래킹을 가져오는거 같아

Copy link
Member Author

@devMinseok devMinseok Sep 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 보니까 스위즐링 해서 트래킹하는게 맞는거 같네!

URLSession 폴더에 스위즐링 하는 부분이 있어서 궁금하면 한번 봐도 좋을거 같아!

)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ extension InfoPlist {
public enum Mohanyang {
public static var app: InfoPlist {
return .dictionary([
// MARK: - Base URL
// MARK: - Environment Value

"BASE_URL": "$(BASE_URL)",
"DATADOG_APP_ID": "$(DATADOG_APP_ID)",
"DATADOG_TOKEN": "$(DATADOG_TOKEN)",


// MARK: - ThirdParty
Expand Down
4 changes: 1 addition & 3 deletions XCConfig/Project/Mohanyang.xcconfig
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#include "../Shared.xcconfig"
#include "../Env.xcconfig"

APP_NAME = 모하냥

BASE_URL_DEV =
BASE_URL_PROD =
BASE_URL = $(BASE_URL_$(CONFIGURATION))
MARKETING_VERSION = 0.1.2
CURRENT_PROJECT_VERSION = 12
DEVELOPMENT_TEAM = 9KL4XS83LC