Skip to content

Commit

Permalink
feat: adds ability to provide a OSLog instance via the Config.logger …
Browse files Browse the repository at this point in the history
…property
  • Loading branch information
tanderson-ld committed May 30, 2024
1 parent 23560ce commit c10ec29
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 26 deletions.
29 changes: 25 additions & 4 deletions Source/LDSwiftEventSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import Foundation
import FoundationNetworking
#endif

#if canImport(os)
// os_log is not supported on some platforms, but we want to use it for most of our customer's
// use cases that use Apple OSs
import os.log
#endif

/**
Provides an EventSource client for consuming Server-Sent Events.

Expand Down Expand Up @@ -51,12 +57,18 @@ public class EventSource {
public var method: String = "GET"
/// Optional HTTP body to be included in the API request.
public var body: Data?
/// An initial value for the last-event-id header to be sent on the initial request
public var lastEventId: String = ""
/// Additional HTTP headers to be set on the request
public var headers: [String: String] = [:]
/// Transform function to allow dynamically configuring the headers on each API request.
public var headerTransform: HeaderTransform = { $0 }
/// An initial value for the last-event-id header to be sent on the initial request
public var lastEventId: String = ""

#if canImport(os)
/// Configure the logger that will be used.
public var logger: OSLog = OSLog(subsystem: "com.launchdarkly.swift-eventsource", category: "LDEventSource")
#endif

/// The minimum amount of time to wait before reconnecting after a failure
public var reconnectTime: TimeInterval = 1.0
/// The maximum amount of time to wait before reconnecting after a failure
Expand Down Expand Up @@ -152,8 +164,9 @@ class ReconnectionTimer {
// MARK: EventSourceDelegate
class EventSourceDelegate: NSObject, URLSessionDataDelegate {
private let delegateQueue: DispatchQueue = DispatchQueue(label: "ESDelegateQueue")
private let logger = Logs()


public var logger: InternalLogging

private let config: EventSource.Config

private var readyState: ReadyState = .raw {
Expand All @@ -170,6 +183,14 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {

init(config: EventSource.Config) {
self.config = config

#if canImport(os)
self.logger = OSLogAdapter(osLog: config.logger)
#else
self.logger = NoOpLogging()
#endif


self.eventParser = EventParser(handler: config.handler,
initialEventId: config.lastEventId,
initialRetry: config.reconnectTime)
Expand Down
58 changes: 36 additions & 22 deletions Source/Logs.swift
Original file line number Diff line number Diff line change
@@ -1,38 +1,52 @@
import Foundation

#if !os(Linux) && !os(Windows)
#if canImport(os)
import os.log
#endif

class Logs {
enum Level {
case debug, info, warn, error
protocol InternalLogging {
func log(_ level: Level, _ staticMsg: StaticString)
func log(_ level: Level, _ staticMsg: StaticString, _ arg: CVarArg)
func log(_ level: Level, _ staticMsg: StaticString, _ arg1: CVarArg, _ arg2: CVarArg)
}

#if !os(Linux) && !os(Windows)
private static let osLogTypes = [ Level.debug: OSLogType.debug,
Level.info: OSLogType.info,
Level.warn: OSLogType.default,
Level.error: OSLogType.error]
var osLogType: OSLogType { Level.osLogTypes[self]! }
#endif
}
enum Level {
case debug, info, warn, error

#if !os(Linux) && !os(Windows)
private let logger: OSLog = OSLog(subsystem: "com.launchdarkly.swift-eventsource", category: "LDEventSource")
#if canImport(os)
private static let osLogTypes = [ Level.debug: OSLogType.debug,
Level.info: OSLogType.info,
Level.warn: OSLogType.default,
Level.error: OSLogType.error]
var osLogType: OSLogType { Level.osLogTypes[self]! }
#endif
}

#if canImport(os)
class OSLogAdapter: InternalLogging {

private let osLog: OSLog

init(osLog: OSLog) {
self.osLog = osLog
}

func log(_ level: Level, _ staticMsg: StaticString) {
os_log(staticMsg, log: logger, type: level.osLogType)
os_log(staticMsg, log: self.osLog, type: level.osLogType)
}

func log(_ level: Level, _ staticMsg: StaticString, _ arg: CVarArg) {
os_log(staticMsg, log: logger, type: level.osLogType, arg)
os_log(staticMsg, log: self.osLog, type: level.osLogType, arg)
}

func log(_ level: Level, _ staticMsg: StaticString, _ arg1: CVarArg, _ arg2: CVarArg) {
os_log(staticMsg, log: logger, type: level.osLogType, arg1, arg2)
os_log(staticMsg, log: self.osLog, type: level.osLogType, arg1, arg2)
}
#else
// We use Any over CVarArg here, because on Linux prior to Swift 5.4 String does not conform to CVarArg
func log(_ level: Level, _ staticMsg: StaticString, _ args: Any...) { }
}
#endif

class NoOpLogging: InternalLogging {
func log(_ level: Level, _ staticMsg: StaticString) {}
func log(_ level: Level, _ staticMsg: StaticString, _ arg: CVarArg) {}
func log(_ level: Level, _ staticMsg: StaticString, _ arg1: CVarArg, _ arg2: CVarArg) {}
}

0 comments on commit c10ec29

Please sign in to comment.