Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -8,13 +8,16 @@ public enum ShopifyAcceleratedCheckouts {

/// The logging level for Accelerated Checkouts operations
/// Default: .error - which will emit "error" and "fault" logs
public static var logLevel: LogLevel = .error {
didSet {
logger.logLevel = logLevel
public static var logLevel: LogLevel {
get {
logger.logLevel
}
set {
logger.logLevel = newValue
}
}

/// Shared logger for ShopifyAcceleratedCheckouts
/// To modify the logLevel
internal static var logger = OSLogger(prefix: name, logLevel: logLevel)
internal static let logger = OSLogger(prefix: name, logLevel: .error)
}
57 changes: 45 additions & 12 deletions platforms/swift/Sources/ShopifyCheckoutKit/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,48 @@ public enum LogLevel: String, CaseIterable, Sendable {
case none
}

public class OSLogger {
public final class OSLogger: Sendable {
private let logger = OSLog(subsystem: subsystem, category: OSLog.Category.pointsOfInterest)
private var prefix: String
package var logLevel: LogLevel
private let prefix: String
private let lockedLogLevel: LockedValue<LogLevel>
private let sendToOSLogHandler: (@Sendable (String, OSLogType) -> Void)?

public static var shared = OSLogger()
package var logLevel: LogLevel {
get {
lockedLogLevel.get()
}
set {
lockedLogLevel.set(newValue)
}
}

private static let lockedSharedLogger = LockedValue(OSLogger())

public static var shared: OSLogger {
get {
lockedSharedLogger.get()
}
set {
lockedSharedLogger.set(newValue)
}
}

public convenience init() {
self.init(prefix: "ShopifyCheckoutKit", logLevel: ShopifyCheckoutKit.configuration.logLevel)
}

public init() {
prefix = "ShopifyCheckoutKit"
logLevel = ShopifyCheckoutKit.configuration.logLevel
public convenience init(prefix: String, logLevel: LogLevel) {
self.init(prefix: prefix, logLevel: logLevel, sendToOSLogHandler: nil)
}

public init(prefix: String, logLevel: LogLevel) {
init(
prefix: String,
logLevel: LogLevel,
sendToOSLogHandler: (@Sendable (String, OSLogType) -> Void)?
) {
self.prefix = prefix
self.logLevel = logLevel
lockedLogLevel = LockedValue(logLevel)
self.sendToOSLogHandler = sendToOSLogHandler
}

public func debug(_ message: String) {
Expand Down Expand Up @@ -54,15 +81,21 @@ public class OSLogger {
/// Capturing `os_log` output is not possible
/// This indirection lets us capture messages in `LoggerTests.swift`
internal func sendToOSLog(_ message: String, type: OSLogType) {
os_log("%@", log: logger, type: type, message)
if let sendToOSLogHandler {
sendToOSLogHandler(message, type)
} else {
os_log("%@", log: logger, type: type, message)
}
}

private func shouldEmit(_ choice: LogLevel) -> Bool {
if logLevel == .none {
let currentLogLevel = logLevel

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

capturing the loglevel to avoid accessing the lock multiple times or the value changing between accesses


if currentLogLevel == .none {
return false
}

return logLevel == .all || logLevel == choice
return currentLogLevel == .all || currentLogLevel == choice
}
}

Expand Down
63 changes: 50 additions & 13 deletions platforms/swift/Tests/ShopifyCheckoutKitTests/LoggerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,44 @@ import os.log
@testable import ShopifyCheckoutKit
import XCTest

class TestableOSLogger: OSLogger {
private(set) var capturedMessages: [(message: String, type: OSLogType)] = []
private let testPrefix: String
override init() {
testPrefix = "ShopifyCheckoutKit"
super.init()
final class TestableOSLogger: Sendable {
private let capturedMessagesStorage = LockedValue([(message: String, type: OSLogType)]())
private let logger: OSLogger

var capturedMessages: [(message: String, type: OSLogType)] {
capturedMessagesStorage.get()
}

override init(prefix: String, logLevel: LogLevel) {
testPrefix = prefix
super.init(prefix: prefix, logLevel: logLevel)
convenience init() {
self.init(prefix: "ShopifyCheckoutKit", logLevel: ShopifyCheckoutKit.configuration.logLevel)
}

override func sendToOSLog(_ message: String, type: OSLogType) {
capturedMessages.append((message: message, type: type))
init(prefix: String, logLevel: LogLevel) {
logger = OSLogger(
prefix: prefix,
logLevel: logLevel,
sendToOSLogHandler: { [capturedMessagesStorage] message, type in
capturedMessagesStorage.update {
$0.append((message: message, type: type))
}
}
)
}

func info(_ message: String) {
logger.info(message)
}

func debug(_ message: String) {
logger.debug(message)
}

func error(_ message: String) {
logger.error(message)
}

func fault(_ message: String) {
logger.fault(message)
}
}

Expand All @@ -37,9 +60,23 @@ final class OSLoggerTests: XCTestCase {
XCTAssertNotNil(OSLogger.shared)
}

func test_defaultInitializer_withNoParameters_shouldMaintainBackwardsCompatibility() {
func test_defaultInitializer_withNoParameters_shouldUseConfigurationLogLevel() {
ShopifyCheckoutKit.configure { $0.logLevel = .debug }

let logger = OSLogger()
XCTAssertNotNil(logger)

XCTAssertEqual(logger.logLevel, .debug)
}

func test_sharedLogger_canBeReplaced() {
let originalLogger = OSLogger.shared
defer { OSLogger.shared = originalLogger }

let replacementLogger = OSLogger(prefix: "Replacement", logLevel: .debug)

OSLogger.shared = replacementLogger

XCTAssertTrue(OSLogger.shared === replacementLogger)
}

func test_logLevelNone_withAllLogCalls_shouldBlockAllLogging() {
Expand Down
7 changes: 0 additions & 7 deletions platforms/swift/api/ShopifyAcceleratedCheckouts.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,6 @@
"mangledName": "$s27ShopifyAcceleratedCheckoutsAAO8logLevel0A11CheckoutKit03LogE0OvpZ",
"moduleName": "ShopifyAcceleratedCheckouts",
"static": true,
"declAttributes": [
"HasInitialValue",
"HasStorage"
],
"hasStorage": true,
"accessors": [
{
"kind": "Accessor",
Expand All @@ -154,7 +149,6 @@
"mangledName": "$s27ShopifyAcceleratedCheckoutsAAO8logLevel0A11CheckoutKit03LogE0OvgZ",
"moduleName": "ShopifyAcceleratedCheckouts",
"static": true,
"implicit": true,
"accessorKind": "get"
},
{
Expand All @@ -179,7 +173,6 @@
"mangledName": "$s27ShopifyAcceleratedCheckoutsAAO8logLevel0A11CheckoutKit03LogE0OvsZ",
"moduleName": "ShopifyAcceleratedCheckouts",
"static": true,
"implicit": true,
"accessorKind": "set"
}
]
Expand Down
56 changes: 38 additions & 18 deletions platforms/swift/api/ShopifyCheckoutKit.json
Original file line number Diff line number Diff line change
Expand Up @@ -4602,9 +4602,8 @@
"moduleName": "ShopifyCheckoutKit",
"isInternal": true,
"declAttributes": [
"HasStorage"
"Final"
],
"hasStorage": true,
"accessors": [
{
"kind": "Accessor",
Expand All @@ -4622,10 +4621,9 @@
"usr": "s:18ShopifyCheckoutKit8OSLoggerC8logLevelAA03LogF0Ovg",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC8logLevelAA03LogF0Ovg",
"moduleName": "ShopifyCheckoutKit",
"implicit": true,
"isInternal": true,
"declAttributes": [
"Transparent"
"Final"
],
"accessorKind": "get"
},
Expand All @@ -4650,10 +4648,9 @@
"usr": "s:18ShopifyCheckoutKit8OSLoggerC8logLevelAA03LogF0Ovs",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC8logLevelAA03LogF0Ovs",
"moduleName": "ShopifyCheckoutKit",
"implicit": true,
"isInternal": true,
"declAttributes": [
"Transparent"
"Final"
],
"accessorKind": "set"
}
Expand All @@ -4677,11 +4674,8 @@
"moduleName": "ShopifyCheckoutKit",
"static": true,
"declAttributes": [
"HasInitialValue",
"Final",
"HasStorage"
"Final"
],
"hasStorage": true,
"accessors": [
{
"kind": "Accessor",
Expand All @@ -4700,10 +4694,8 @@
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC6sharedACvgZ",
"moduleName": "ShopifyCheckoutKit",
"static": true,
"implicit": true,
"declAttributes": [
"Final",
"Transparent"
"Final"
],
"accessorKind": "get"
},
Expand All @@ -4729,10 +4721,8 @@
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC6sharedACvsZ",
"moduleName": "ShopifyCheckoutKit",
"static": true,
"implicit": true,
"declAttributes": [
"Final",
"Transparent"
"Final"
],
"accessorKind": "set"
}
Expand All @@ -4754,7 +4744,7 @@
"usr": "s:18ShopifyCheckoutKit8OSLoggerCACycfc",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerCACycfc",
"moduleName": "ShopifyCheckoutKit",
"init_kind": "Designated"
"init_kind": "Convenience"
},
{
"kind": "Constructor",
Expand Down Expand Up @@ -4784,7 +4774,7 @@
"usr": "s:18ShopifyCheckoutKit8OSLoggerC6prefix8logLevelACSS_AA03LogG0Otcfc",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC6prefix8logLevelACSS_AA03LogG0Otcfc",
"moduleName": "ShopifyCheckoutKit",
"init_kind": "Designated"
"init_kind": "Convenience"
},
{
"kind": "Function",
Expand All @@ -4807,6 +4797,9 @@
"usr": "s:18ShopifyCheckoutKit8OSLoggerC5debugyySSF",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC5debugyySSF",
"moduleName": "ShopifyCheckoutKit",
"declAttributes": [
"Final"
],
"funcSelfKind": "NonMutating"
},
{
Expand All @@ -4830,6 +4823,9 @@
"usr": "s:18ShopifyCheckoutKit8OSLoggerC4infoyySSF",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC4infoyySSF",
"moduleName": "ShopifyCheckoutKit",
"declAttributes": [
"Final"
],
"funcSelfKind": "NonMutating"
},
{
Expand All @@ -4853,6 +4849,9 @@
"usr": "s:18ShopifyCheckoutKit8OSLoggerC5erroryySSF",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC5erroryySSF",
"moduleName": "ShopifyCheckoutKit",
"declAttributes": [
"Final"
],
"funcSelfKind": "NonMutating"
},
{
Expand All @@ -4876,14 +4875,35 @@
"usr": "s:18ShopifyCheckoutKit8OSLoggerC5faultyySSF",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC5faultyySSF",
"moduleName": "ShopifyCheckoutKit",
"declAttributes": [
"Final"
],
"funcSelfKind": "NonMutating"
}
],
"declKind": "Class",
"usr": "s:18ShopifyCheckoutKit8OSLoggerC",
"mangledName": "$s18ShopifyCheckoutKit8OSLoggerC",
"moduleName": "ShopifyCheckoutKit",
"declAttributes": [
"Final"
],
"hasMissingDesignatedInitializers": true,
"conformances": [
{
"kind": "Conformance",
"name": "Sendable",
"printedName": "Sendable",
"usr": "s:s8SendableP",
"mangledName": "$ss8SendableP"
},
{
"kind": "Conformance",
"name": "SendableMetatype",
"printedName": "SendableMetatype",
"usr": "s:s16SendableMetatypeP",
"mangledName": "$ss16SendableMetatypeP"
},
{
"kind": "Conformance",
"name": "Copyable",
Expand Down
Loading