diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingCategoryClient.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingCategoryClient.swift index 86a63bd956..18ed241524 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingCategoryClient.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingCategoryClient.swift @@ -5,12 +5,12 @@ // SPDX-License-Identifier: Apache-2.0 // -import AWSPluginsCore import Amplify +import AWSClientRuntime +import AWSCloudWatchLogs +import AWSPluginsCore import Combine import Foundation -import AWSCloudWatchLogs -import AWSClientRuntime import Network /// Concrete implementation of @@ -57,7 +57,7 @@ final class AWSCloudWatchLoggingCategoryClient { self.networkMonitor = networkMonitor self.networkMonitor.startMonitoring(using: DispatchQueue(label: "com.amazonaws.awscloudwatchlogging.networkmonitor")) self.automaticFlushLogMonitor = AWSCLoudWatchLoggingMonitor(flushIntervalInSeconds: TimeInterval(flushIntervalInSeconds), eventDelegate: self) - self.automaticFlushLogMonitor?.setAutomaticFlushIntervals() + automaticFlushLogMonitor?.setAutomaticFlushIntervals() self.authSubscription = Amplify.Hub.publisher(for: .auth).sink { [weak self] payload in self?.handle(payload: payload) } @@ -92,8 +92,8 @@ final class AWSCloudWatchLoggingCategoryClient { case HubPayload.EventName.Auth.signedIn, CognitoEventName.signInAPI.rawValue: takeUserIdentifierFromCurrentUser() case HubPayload.EventName.Auth.signedOut, CognitoEventName.signOutAPI.rawValue: - self.userIdentifier = nil - self.updateSessionControllers() + userIdentifier = nil + updateSessionControllers() default: break } @@ -135,7 +135,7 @@ extension AWSCloudWatchLoggingCategoryClient: LoggingCategoryClientBehavior { } var `default`: Logger { - return self.logger(forCategory: "Amplify") + return logger(forCategory: "Amplify") } func logger(forCategory category: String, namespace: String?, logLevel: Amplify.LogLevel) -> Logger { @@ -145,17 +145,19 @@ extension AWSCloudWatchLoggingCategoryClient: LoggingCategoryClientBehavior { return existing } - let controller = AWSCloudWatchLoggingSessionController(credentialsProvider: credentialsProvider, - authentication: authentication, - logFilter: self.logFilter, - category: category, - namespace: namespace, - logLevel: logLevel, - logGroupName: self.logGroupName, - region: self.region, - localStoreMaxSizeInMB: self.localStoreMaxSizeInMB, - userIdentifier: self.userIdentifier, - networkMonitor: self.networkMonitor) + let controller = AWSCloudWatchLoggingSessionController( + credentialsProvider: credentialsProvider, + authentication: authentication, + logFilter: self.logFilter, + category: category, + namespace: namespace, + logLevel: logLevel, + logGroupName: self.logGroupName, + region: self.region, + localStoreMaxSizeInMB: self.localStoreMaxSizeInMB, + userIdentifier: self.userIdentifier, + networkMonitor: self.networkMonitor + ) if enabled { controller.enable() } @@ -165,21 +167,21 @@ extension AWSCloudWatchLoggingCategoryClient: LoggingCategoryClientBehavior { } func logger(forCategory category: String, logLevel: LogLevel) -> Logger { - return self.logger(forCategory: category, namespace: nil, logLevel: logLevel) + return logger(forCategory: category, namespace: nil, logLevel: logLevel) } func logger(forCategory category: String) -> Logger { - let defaultLogLevel = logFilter.getDefaultLogLevel(forCategory: category, userIdentifier: self.userIdentifier) - return self.logger(forCategory: category, namespace: nil, logLevel: defaultLogLevel) + let defaultLogLevel = logFilter.getDefaultLogLevel(forCategory: category, userIdentifier: userIdentifier) + return logger(forCategory: category, namespace: nil, logLevel: defaultLogLevel) } func logger(forNamespace namespace: String) -> Logger { - self.logger(forCategory: namespace) + logger(forCategory: namespace) } func logger(forCategory category: String, forNamespace namespace: String) -> Logger { - let defaultLogLevel = logFilter.getDefaultLogLevel(forCategory: category, userIdentifier: self.userIdentifier) - return self.logger(forCategory: category, namespace: namespace, logLevel: defaultLogLevel) + let defaultLogLevel = logFilter.getDefaultLogLevel(forCategory: category, userIdentifier: userIdentifier) + return logger(forCategory: category, namespace: namespace, logLevel: defaultLogLevel) } func getInternalClient() -> CloudWatchLogsClientProtocol { diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingPlugin.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingPlugin.swift index 2271e877d8..059a6e32e9 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingPlugin.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingPlugin.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // +import Amplify import AWSCloudWatchLogs import AWSPluginsCore -import Amplify import Combine import Foundation @@ -54,7 +54,8 @@ public class AWSCloudWatchLoggingPlugin: LoggingCategoryPlugin { self.remoteLoggingConstraintsProvider = DefaultRemoteLoggingConstraintsProvider( endpoint: remoteConfig.endpoint, region: configuration.region, - refreshIntervalInSeconds: remoteConfig.refreshIntervalInSeconds) + refreshIntervalInSeconds: remoteConfig.refreshIntervalInSeconds + ) } } } @@ -114,18 +115,19 @@ public class AWSCloudWatchLoggingPlugin: LoggingCategoryPlugin { /// - Throws: /// - PluginError.pluginConfigurationError: If one of the configuration values is invalid or empty public func configure(using configuration: Any?) throws { - if self.loggingPluginConfiguration == nil, let configuration = try? AWSCloudWatchLoggingPluginConfiguration(bundle: Bundle.main) { - self.loggingPluginConfiguration = configuration + if loggingPluginConfiguration == nil, let configuration = try? AWSCloudWatchLoggingPluginConfiguration(bundle: Bundle.main) { + loggingPluginConfiguration = configuration let authService = AWSAuthService() - if let remoteConfig = configuration.defaultRemoteConfiguration, self.remoteLoggingConstraintsProvider == nil { - self.remoteLoggingConstraintsProvider = DefaultRemoteLoggingConstraintsProvider( + if let remoteConfig = configuration.defaultRemoteConfiguration, remoteLoggingConstraintsProvider == nil { + remoteLoggingConstraintsProvider = DefaultRemoteLoggingConstraintsProvider( endpoint: remoteConfig.endpoint, region: configuration.region, - refreshIntervalInSeconds: remoteConfig.refreshIntervalInSeconds) + refreshIntervalInSeconds: remoteConfig.refreshIntervalInSeconds + ) } - self.loggingClient = AWSCloudWatchLoggingCategoryClient( + loggingClient = AWSCloudWatchLoggingCategoryClient( enable: configuration.enable, credentialsProvider: authService.getCredentialsProvider(), authentication: Amplify.Auth, @@ -137,7 +139,7 @@ public class AWSCloudWatchLoggingPlugin: LoggingCategoryPlugin { ) } - if self.loggingPluginConfiguration == nil { + if loggingPluginConfiguration == nil { throw LoggingError.configuration( """ Missing configuration for AWSCloudWatchLoggingPlugin @@ -150,7 +152,7 @@ public class AWSCloudWatchLoggingPlugin: LoggingCategoryPlugin { ) } - if self.remoteLoggingConstraintsProvider == nil { + if remoteLoggingConstraintsProvider == nil { let localStore: LoggingConstraintsLocalStore = UserDefaults.standard localStore.reset() } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift index cfa0013092..434eddee7c 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift @@ -25,11 +25,13 @@ final class AWSCloudWatchLoggingSession { self.category = category self.namespace = namespace self.userIdentifier = userIdentifier - self.logger = try Self.createLogger(category: category, - namespace: namespace, - logLevel: logLevel, - userIdentifier: userIdentifier, - localStoreMaxSizeInMB: localStoreMaxSizeInMB) + self.logger = try Self.createLogger( + category: category, + namespace: namespace, + logLevel: logLevel, + userIdentifier: userIdentifier, + localStoreMaxSizeInMB: localStoreMaxSizeInMB + ) } private static func createLogger( @@ -43,12 +45,14 @@ final class AWSCloudWatchLoggingSession { let directory = try directory(for: category, userIdentifier: userIdentifier) try fileManager.createDirectory(at: directory, withIntermediateDirectories: true) try (directory as NSURL).setResourceValue(true, forKey: URLResourceKey.isExcludedFromBackupKey) - let cacheMaxSizeInBytes = localStoreMaxSizeInMB * 1048576 - return try RotatingLogger(directory: directory, - category: category, - namespace: namespace, - logLevel: logLevel, - fileSizeLimitInBytes: cacheMaxSizeInBytes) + let cacheMaxSizeInBytes = localStoreMaxSizeInMB * 1_048_576 + return try RotatingLogger( + directory: directory, + category: category, + namespace: namespace, + logLevel: logLevel, + fileSizeLimitInBytes: cacheMaxSizeInBytes + ) } private static func directory(for category: String, userIdentifier: String?, fileManager: FileManager = .default) throws -> URL { @@ -64,7 +68,7 @@ final class AWSCloudWatchLoggingSession { } private static func normalized(userIdentifier: String?) throws -> String { - guard let userIdentifier = userIdentifier else { + guard let userIdentifier else { return "guest" } @@ -85,5 +89,6 @@ extension AWSCloudWatchLoggingSession: LogBatchProducer { extension AWSCloudWatchLoggingError { static let sessionInternalErrorForUserId = AWSCloudWatchLoggingError( - errorDescription: "Internal error while attempting to interpret userId", recoverySuggestion: "") + errorDescription: "Internal error while attempting to interpret userId", recoverySuggestion: "" + ) } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSessionController.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSessionController.swift index de5fcd5c7e..7383dfe2d2 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSessionController.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSessionController.swift @@ -5,13 +5,13 @@ // SPDX-License-Identifier: Apache-2.0 // -import AWSPluginsCore -@_spi(PluginHTTPClientEngine) import InternalAmplifyCredentials import Amplify +import AWSClientRuntime +import AWSCloudWatchLogs +import AWSPluginsCore import Combine import Foundation -import AWSCloudWatchLogs -import AWSClientRuntime +@_spi(PluginHTTPClientEngine) import InternalAmplifyCredentials import Network /// Responsible for setting up and tearing-down log sessions for a given category/tag according to changes in @@ -54,22 +54,23 @@ final class AWSCloudWatchLoggingSessionController { var logLevel: LogLevel { didSet { - self.session?.logger.logLevel = logLevel + session?.logger.logLevel = logLevel } } /// - Tag: CloudWatchLogSessionController.init - init(credentialsProvider: CredentialsProviding, - authentication: AuthCategoryUserBehavior, - logFilter: AWSCloudWatchLoggingFilterBehavior, - category: String, - namespace: String?, - logLevel: LogLevel, - logGroupName: String, - region: String, - localStoreMaxSizeInMB: Int, - userIdentifier: String?, - networkMonitor: LoggingNetworkMonitor + init( + credentialsProvider: CredentialsProviding, + authentication: AuthCategoryUserBehavior, + logFilter: AWSCloudWatchLoggingFilterBehavior, + category: String, + namespace: String?, + logLevel: LogLevel, + logGroupName: String, + region: String, + localStoreMaxSizeInMB: Int, + userIdentifier: String?, + networkMonitor: LoggingNetworkMonitor ) { self.credentialsProvider = credentialsProvider self.authentication = authentication @@ -91,18 +92,18 @@ final class AWSCloudWatchLoggingSessionController { } func disable() { - self.batchSubscription = nil - self.authSubscription = nil - self.session = nil - self.consumer = nil + batchSubscription = nil + authSubscription = nil + session = nil + consumer = nil } private func updateConsumer() { - self.consumer = try? createConsumer() + consumer = try? createConsumer() } private func createConsumer() throws -> LogBatchConsumer? { - if self.client == nil { + if client == nil { let configuration = try CloudWatchLogsClient.CloudWatchLogsClientConfiguration( region: region, credentialsProvider: credentialsProvider @@ -110,26 +111,27 @@ final class AWSCloudWatchLoggingSessionController { configuration.httpClientEngine = .userAgentEngine(for: configuration) - self.client = CloudWatchLogsClient(config: configuration) + client = CloudWatchLogsClient(config: configuration) } guard let cloudWatchClient = client else { return nil } return CloudWatchLoggingConsumer( client: cloudWatchClient, - logGroupName: self.logGroupName, - userIdentifier: self.userIdentifier) + logGroupName: logGroupName, + userIdentifier: userIdentifier + ) } private func connectProducerAndConsumer() { - guard let consumer = consumer else { - self.batchSubscription = nil + guard let consumer else { + batchSubscription = nil return } guard let producer = session else { - self.batchSubscription = nil + batchSubscription = nil return } - self.batchSubscription = producer.logBatchPublisher.sink { [weak self] batch in + batchSubscription = producer.logBatchPublisher.sink { [weak self] batch in guard self?.networkMonitor.isOnline == true else { return } Task { do { @@ -153,19 +155,21 @@ final class AWSCloudWatchLoggingSessionController { private func updateSession() { do { - self.session = try AWSCloudWatchLoggingSession(category: self.category, - namespace: self.namespace, - logLevel: self.logLevel, - userIdentifier: self.userIdentifier, - localStoreMaxSizeInMB: self.localStoreMaxSizeInMB) + session = try AWSCloudWatchLoggingSession( + category: category, + namespace: namespace, + logLevel: logLevel, + userIdentifier: userIdentifier, + localStoreMaxSizeInMB: localStoreMaxSizeInMB + ) } catch { - self.session = nil + session = nil print(error) } } func setCurrentUser(identifier: String?) { - self.userIdentifier = identifier + userIdentifier = identifier } func flushLogs() async throws { @@ -200,32 +204,32 @@ final class AWSCloudWatchLoggingSessionController { extension AWSCloudWatchLoggingSessionController: Logger { func error(_ message: @autoclosure () -> String) { - guard self.logFilter.canLog(withCategory: self.category, logLevel: .error, userIdentifier: self.userIdentifier) else { return } + guard logFilter.canLog(withCategory: category, logLevel: .error, userIdentifier: userIdentifier) else { return } session?.logger.error(message()) } func error(error: Error) { - guard self.logFilter.canLog(withCategory: self.category, logLevel: .error, userIdentifier: self.userIdentifier) else { return } + guard logFilter.canLog(withCategory: category, logLevel: .error, userIdentifier: userIdentifier) else { return } session?.logger.error(error: error) } func warn(_ message: @autoclosure () -> String) { - guard self.logFilter.canLog(withCategory: self.category, logLevel: .warn, userIdentifier: self.userIdentifier) else { return } + guard logFilter.canLog(withCategory: category, logLevel: .warn, userIdentifier: userIdentifier) else { return } session?.logger.warn(message()) } func info(_ message: @autoclosure () -> String) { - guard self.logFilter.canLog(withCategory: self.category, logLevel: .info, userIdentifier: self.userIdentifier) else { return } + guard logFilter.canLog(withCategory: category, logLevel: .info, userIdentifier: userIdentifier) else { return } session?.logger.info(message()) } func debug(_ message: @autoclosure () -> String) { - guard self.logFilter.canLog(withCategory: self.category, logLevel: .debug, userIdentifier: self.userIdentifier) else { return } + guard logFilter.canLog(withCategory: category, logLevel: .debug, userIdentifier: userIdentifier) else { return } session?.logger.debug(message()) } func verbose(_ message: @autoclosure () -> String) { - guard self.logFilter.canLog(withCategory: self.category, logLevel: .verbose, userIdentifier: self.userIdentifier) else { return } + guard logFilter.canLog(withCategory: category, logLevel: .verbose, userIdentifier: userIdentifier) else { return } session?.logger.verbose(message()) } } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/AWSCloudWatchLoggingPluginConfiguration.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/AWSCloudWatchLoggingPluginConfiguration.swift index 5a9ad61361..1d913876e2 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/AWSCloudWatchLoggingPluginConfiguration.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/AWSCloudWatchLoggingPluginConfiguration.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation public struct AWSCloudWatchLoggingPluginConfiguration: Codable { public init( @@ -17,7 +17,7 @@ public struct AWSCloudWatchLoggingPluginConfiguration: Codable { flushIntervalInSeconds: Int = 60, defaultRemoteConfiguration: DefaultRemoteConfiguration? = nil, loggingConstraints: LoggingConstraints = LoggingConstraints() - ) { + ) { self.logGroupName = logGroupName self.region = region self.enable = enable diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/AmplifyConfigurationLogging.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/AmplifyConfigurationLogging.swift index 13dc95c8b2..339f7b9e2f 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/AmplifyConfigurationLogging.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/AmplifyConfigurationLogging.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation public struct AmplifyConfigurationLogging: Codable { public let awsCloudWatchLoggingPlugin: AWSCloudWatchLoggingPluginConfiguration diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/DefaultRemoteConfiguration.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/DefaultRemoteConfiguration.swift index 79ca6c14d3..f91eeca427 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/DefaultRemoteConfiguration.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/DefaultRemoteConfiguration.swift @@ -5,13 +5,13 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation public struct DefaultRemoteConfiguration: Codable { public init( endpoint: URL, - refreshIntervalInSeconds: Int = 1200 + refreshIntervalInSeconds: Int = 1_200 ) { self.endpoint = endpoint self.refreshIntervalInSeconds = refreshIntervalInSeconds diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/DefaultRemoteLoggingConstraintsProvider.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/DefaultRemoteLoggingConstraintsProvider.swift index 6a11ded903..1fd81808ca 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/DefaultRemoteLoggingConstraintsProvider.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/DefaultRemoteLoggingConstraintsProvider.swift @@ -5,12 +5,12 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify -import AWSPluginsCore -import InternalAmplifyCredentials import AWSClientRuntime +import AWSPluginsCore import ClientRuntime +import Foundation +import InternalAmplifyCredentials public class DefaultRemoteLoggingConstraintsProvider: RemoteLoggingConstraintsProvider { public let refreshIntervalInSeconds: Int @@ -30,10 +30,10 @@ public class DefaultRemoteLoggingConstraintsProvider: RemoteLoggingConstraintsPr } public init( - endpoint: URL, - region: String, - credentialProvider: CredentialsProviding? = nil, - refreshIntervalInSeconds: Int = 1200 + endpoint: URL, + region: String, + credentialProvider: CredentialsProviding? = nil, + refreshIntervalInSeconds: Int = 1_200 ) { self.endpoint = endpoint if credentialProvider == nil { @@ -43,7 +43,7 @@ public class DefaultRemoteLoggingConstraintsProvider: RemoteLoggingConstraintsPr } self.region = region self.refreshIntervalInSeconds = refreshIntervalInSeconds - self.setupAutomaticRefreshInterval() + setupAutomaticRefreshInterval() } public func fetchLoggingConstraints() async throws -> LoggingConstraints { @@ -101,7 +101,7 @@ public class DefaultRemoteLoggingConstraintsProvider: RemoteLoggingConstraintsPr .withHeaders(.init(request.allHTTPHeaderFields ?? [:])) .withBody(.data(request.httpBody)) - guard let credentialProvider = self.credentialProvider else { + guard let credentialProvider else { return request } @@ -139,16 +139,19 @@ public class DefaultRemoteLoggingConstraintsProvider: RemoteLoggingConstraintsPr } refreshTimer = Self.createRepeatingTimer( - timeInterval: TimeInterval(self.refreshIntervalInSeconds), + timeInterval: TimeInterval(refreshIntervalInSeconds), eventHandler: { [weak self] in - guard let self = self else { return } - self.refresh() - }) + guard let self else { return } + refresh() + } + ) refreshTimer?.resume() } - static func createRepeatingTimer(timeInterval: TimeInterval, - eventHandler: @escaping () -> Void) -> DispatchSourceTimer { + static func createRepeatingTimer( + timeInterval: TimeInterval, + eventHandler: @escaping () -> Void + ) -> DispatchSourceTimer { let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global(qos: .background)) timer.schedule(deadline: .now() + timeInterval, repeating: timeInterval) timer.setEventHandler(handler: eventHandler) diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/LoggingConstraints.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/LoggingConstraints.swift index 41feb1ef7f..debe4e3687 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/LoggingConstraints.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/LoggingConstraints.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation public struct LoggingConstraints: Codable { public init( diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/UserLogLevel.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/UserLogLevel.swift index dc35f4d9fb..5784de42c9 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/UserLogLevel.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Configuration/UserLogLevel.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation public struct UserLogLevel: Codable { public init( diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingConsumer.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingConsumer.swift index 3ff0d65068..1ccbc7056b 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingConsumer.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingConsumer.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -import AWSPluginsCore -import AWSCloudWatchLogs -import AWSClientRuntime import Amplify +import AWSClientRuntime +import AWSCloudWatchLogs +import AWSPluginsCore import Foundation class CloudWatchLoggingConsumer { @@ -77,12 +77,12 @@ extension CloudWatchLoggingConsumer: LogBatchConsumer { } if logStreamName == nil { - self.logStreamName = await formatter.formattedStreamName() + logStreamName = await formatter.formattedStreamName() } - - let stream = try? await self.client.describeLogStreams(input: DescribeLogStreamsInput( - logGroupName: self.logGroupName, - logStreamNamePrefix: self.logStreamName + + let stream = try? await client.describeLogStreams(input: DescribeLogStreamsInput( + logGroupName: logGroupName, + logStreamNamePrefix: logStreamName )).logStreams?.first(where: { stream in return stream.logStreamName == self.logStreamName }) @@ -90,27 +90,27 @@ extension CloudWatchLoggingConsumer: LogBatchConsumer { return } - _ = try? await self.client.createLogStream(input: CreateLogStreamInput( - logGroupName: self.logGroupName, - logStreamName: self.logStreamName + _ = try? await client.createLogStream(input: CreateLogStreamInput( + logGroupName: logGroupName, + logStreamName: logStreamName )) } private func sendLogEvents(_ entries: [LogEntry]) async throws { let events = convertToCloudWatchInputLogEvents(for: entries) - let response = try await self.client.putLogEvents(input: PutLogEventsInput( + let response = try await client.putLogEvents(input: PutLogEventsInput( logEvents: events, - logGroupName: self.logGroupName, - logStreamName: self.logStreamName, + logGroupName: logGroupName, + logStreamName: logStreamName, sequenceToken: nil )) let retriableEntries = retriable(entries: entries, in: response) if !retriableEntries.isEmpty { let retriableEvents = convertToCloudWatchInputLogEvents(for: retriableEntries) - _ = try await self.client.putLogEvents(input: PutLogEventsInput( + _ = try await client.putLogEvents(input: PutLogEventsInput( logEvents: retriableEvents, - logGroupName: self.logGroupName, - logStreamName: self.logStreamName, + logGroupName: logGroupName, + logStreamName: logStreamName, sequenceToken: nil )) } @@ -136,7 +136,7 @@ extension CloudWatchLoggingConsumer: LogBatchConsumer { } var retriableEntries: [LogEntry] = [] - for index in tooNewLogEventStartIndex.. String { - return "\(await deviceIdentifier ?? "").\(userIdentifier ?? "guest")" + return await "\(deviceIdentifier ?? "").\(userIdentifier ?? "guest")" } } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogEntry.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogEntry.swift index 9ea55337a2..76210d29cc 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogEntry.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogEntry.swift @@ -31,7 +31,7 @@ struct LogEntry: Codable, Hashable { /// The log level associated with the receiver. var logLevel: LogLevel { - if let result = LogLevel(rawValue: self.level) { + if let result = LogLevel(rawValue: level) { return result } return .error @@ -50,7 +50,7 @@ struct LogEntry: Codable, Hashable { } var millisecondsSince1970: Int { - Int((created.timeIntervalSince1970 * 1000.0).rounded()) + Int((created.timeIntervalSince1970 * 1_000.0).rounded()) } init(category: String, namespace: String?, level: LogLevel, message: String, created: Date = Date()) { diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogEntryCodec.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogEntryCodec.swift index 8f78e7959b..c973c23a10 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogEntryCodec.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogEntryCodec.swift @@ -7,10 +7,10 @@ import Foundation -/// Struct encode and decode LogEntry +/// Struct encode and decode LogEntry struct LogEntryCodec { - private static let lineDelimiter = Data([0x0A]) /* '\n' */ + private static let lineDelimiter = Data([0x0a]) /* '\n' */ enum DecodingError: Error { case stringNotUtf8(String) diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogFile.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogFile.swift index 03ee67607a..9e638c3ff9 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogFile.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogFile.swift @@ -32,7 +32,7 @@ final class LogFile { if #available(macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) { self.count = try self.handle.offset() } else { - self.count = self.handle.offsetInFile + self.count = handle.offsetInFile } } @@ -51,17 +51,17 @@ final class LogFile { /// Attempts to close the underlying log file. func close() throws { - try self.handle.close() + try handle.close() } /// Atempts to flush the receivers contents to disk. func synchronize() throws { - try self.handle.synchronize() + try handle.synchronize() } /// - Returns: true if writing to the underlying log file will keep its size below the limit. func hasSpace(for data: Data) -> Bool { - return UInt64(data.count) <= self.available + return UInt64(data.count) <= available } /// Writes the given **single line of text** represented as a @@ -70,9 +70,9 @@ final class LogFile { if #available(macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) { try self.handle.write(contentsOf: data) } else { - self.handle.write(data) + handle.write(data) } - try self.handle.synchronize() + try handle.synchronize() count = count + UInt64(data.count) // swiftlint:disable:this shorthand_operator } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift index 32552df26c..de98d3655b 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift @@ -16,7 +16,7 @@ final class LogRotation { case invalidFileSizeLimitInBytes(Int) } - static let minimumFileSizeLimitInBytes = 1024 /* 1KB */ + static let minimumFileSizeLimitInBytes = 1_024 /* 1KB */ /// The name pattern of files managed by `LogRotation`. private static let filePattern = #"amplify[.]([0-9])[.]log"# @@ -39,9 +39,11 @@ final class LogRotation { self.directory = directory.absoluteURL self.fileSizeLimitInBytes = UInt64(fileSizeLimitInBytes) - self.currentLogFile = try Self.selectNextLogFile(from: self.directory, - fileCountLimit: fileCountLimit, - fileSizeLimitInBytes: self.fileSizeLimitInBytes) + self.currentLogFile = try Self.selectNextLogFile( + from: self.directory, + fileCountLimit: fileCountLimit, + fileSizeLimitInBytes: self.fileSizeLimitInBytes + ) } /// Selects the most-available log file. @@ -54,9 +56,11 @@ final class LogRotation { /// 2. Any files containing less than half the limit are filtered, then the one with the oldest last modified date is selected. /// 3. If no files matching #1 are present, the file with the oldest last modified date is cleared and selected. func rotate() throws { - self.currentLogFile = try Self.selectNextLogFile(from: self.directory, - fileCountLimit: self.fileCountLimit, - fileSizeLimitInBytes: self.fileSizeLimitInBytes) + currentLogFile = try Self.selectNextLogFile( + from: directory, + fileCountLimit: fileCountLimit, + fileSizeLimitInBytes: fileSizeLimitInBytes + ) } func getAllLogs() throws -> [URL] { @@ -68,35 +72,49 @@ final class LogRotation { for file in existingFiles { try FileManager.default.removeItem(at: file) } - self.currentLogFile = try Self.createLogFile(in: directory, - index: 0, - fileSizeLimitInBytes: fileSizeLimitInBytes) + currentLogFile = try Self.createLogFile( + in: directory, + index: 0, + fileSizeLimitInBytes: fileSizeLimitInBytes + ) } - private static func selectNextLogFile(from directory: URL, - fileCountLimit: Int, - fileSizeLimitInBytes: UInt64) throws -> LogFile { + private static func selectNextLogFile( + from directory: URL, + fileCountLimit: Int, + fileSizeLimitInBytes: UInt64 + ) throws -> LogFile { let existingFiles = try Self.listLogFiles(in: directory) if let index = try Self.nextUnallocatedIndex(from: existingFiles, fileCountLimit: fileCountLimit) { - return try createLogFile(in: directory, - index: index, - fileSizeLimitInBytes: fileSizeLimitInBytes) + return try createLogFile( + in: directory, + index: index, + fileSizeLimitInBytes: fileSizeLimitInBytes + ) } - if let underutilized = try Self.oldestUnderutilizedFile(from: existingFiles, - sizeLimitInBytes: fileSizeLimitInBytes) { - return try LogFile(forAppending: underutilized, - sizeLimitInBytes: fileSizeLimitInBytes) + if let underutilized = try Self.oldestUnderutilizedFile( + from: existingFiles, + sizeLimitInBytes: fileSizeLimitInBytes + ) { + return try LogFile( + forAppending: underutilized, + sizeLimitInBytes: fileSizeLimitInBytes + ) } if let oldestFileURL = existingFiles.last { - return try LogFile(forWritingTo: oldestFileURL, - sizeLimitInBytes: fileSizeLimitInBytes) + return try LogFile( + forWritingTo: oldestFileURL, + sizeLimitInBytes: fileSizeLimitInBytes + ) } - return try createLogFile(in: directory, - index: 0, - fileSizeLimitInBytes: fileSizeLimitInBytes) + return try createLogFile( + in: directory, + index: 0, + fileSizeLimitInBytes: fileSizeLimitInBytes + ) } func ensureFileExists() throws { @@ -117,7 +135,7 @@ final class LogRotation { } typealias FileIndexRef = (URL, Int) let references = try existingFiles.compactMap { try LogRotation.index(of: $0) } - .filter { (0.. URL? { - let fileManager: FileManager = FileManager.default + let fileManager = FileManager.default let underutilizedFiles = try existingFiles.filter { url in let attributes = try fileManager.attributesOfItem(atPath: url.path) guard let size = attributes[.size] as? Int else { return false } @@ -141,7 +159,7 @@ final class LogRotation { /// file naming pattern ordered by last modified date descending /// (most-recently modified first). private static func listLogFiles(in directory: URL) throws -> [URL] { - let fileManager: FileManager = FileManager.default + let fileManager = FileManager.default let propertyKeys: [URLResourceKey] = [.contentModificationDateKey, .nameKey, .fileSizeKey] return try fileManager.contentsOfDirectory(at: directory, includingPropertiesForKeys: propertyKeys) .filter { try index(of: $0) != nil } @@ -178,14 +196,18 @@ final class LogRotation { /// - Returns: An empty LogFile within the given /// directory using the given index whose name matches the /// amplify..log name pattern. - private static func createLogFile(in directory: URL, - index: Int, - fileSizeLimitInBytes: UInt64) throws -> LogFile { - let fileManager: FileManager = FileManager.default + private static func createLogFile( + in directory: URL, + index: Int, + fileSizeLimitInBytes: UInt64 + ) throws -> LogFile { + let fileManager = FileManager.default let fileURL = directory.appendingPathComponent("amplify.\(index).log") - fileManager.createFile(atPath: fileURL.path, - contents: nil, - attributes: [FileAttributeKey: Any]()) + fileManager.createFile( + atPath: fileURL.path, + contents: nil, + attributes: [FileAttributeKey: Any]() + ) if #available(macOS 11.0, *) { let resourceValues: [URLResourceKey: Any] = [ URLResourceKey.fileProtectionKey: URLFileProtection.complete, diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Producer/RotatingLogger.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Producer/RotatingLogger.swift index 238dbfb7d5..0053b13e37 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Producer/RotatingLogger.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Producer/RotatingLogger.swift @@ -25,11 +25,12 @@ final class RotatingLogger { /// /// - Parameter directory: The URL of the directory to use for the log rotation. /// - Parameter logLevel: Amplify.LogLevel by which to filter any incomming log events. - init(directory: URL, - category: String, - namespace: String?, - logLevel: Amplify.LogLevel, - fileSizeLimitInBytes: Int + init( + directory: URL, + category: String, + namespace: String?, + logLevel: Amplify.LogLevel, + fileSizeLimitInBytes: Int ) throws { self.category = category self.namespace = namespace @@ -45,7 +46,7 @@ final class RotatingLogger { func getLogBatches() async throws -> [RotatingLogBatch] { let logs = try await actor.getLogs() - return logs.map({RotatingLogBatch(url: $0)}) + return logs.map {RotatingLogBatch(url: $0)} } func resetLogs() async throws { @@ -54,16 +55,16 @@ final class RotatingLogger { func record(level: LogLevel, message: @autoclosure () -> String) async throws { try await setupSubscription() - let entry = LogEntry(category: self.category, namespace: self.namespace, level: level, message: message()) - try await self.actor.record(entry) + let entry = LogEntry(category: category, namespace: namespace, level: level, message: message()) + try await actor.record(entry) } private func setupSubscription() async throws { if rotationSubscription == nil { - let rotationPublisher = await self.actor.rotationPublisher() + let rotationPublisher = await actor.rotationPublisher() rotationSubscription = rotationPublisher.sink { [weak self] url in - guard let self = self else { return } - self.batchSubject.send(RotatingLogBatch(url: url)) + guard let self else { return } + batchSubject.send(RotatingLogBatch(url: url)) } } } @@ -77,7 +78,8 @@ final class RotatingLogger { let payload = HubPayload( eventName: HubPayload.EventName.Logging.writeLogFailure, context: error.localizedDescription, - data: payload) + data: payload + ) Amplify.Hub.dispatch(to: HubChannel.logging, payload: payload) } } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingConstraintsResolver.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingConstraintsResolver.swift index 7dce65c2d2..95050ba6d6 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingConstraintsResolver.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingConstraintsResolver.swift @@ -5,17 +5,19 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify import AWSPluginsCore +import Foundation /// Provides resolver to return the active/valid log constraints to use for the logging plugin class AWSCloudWatchLoggingConstraintsResolver { let loggingPluginConfiguration: AWSCloudWatchLoggingPluginConfiguration let loggingConstraintsLocalStore: LoggingConstraintsLocalStore - init(loggingPluginConfiguration: AWSCloudWatchLoggingPluginConfiguration, - loggingConstraintsLocalStore: LoggingConstraintsLocalStore = UserDefaults.standard) { + init( + loggingPluginConfiguration: AWSCloudWatchLoggingPluginConfiguration, + loggingConstraintsLocalStore: LoggingConstraintsLocalStore = UserDefaults.standard + ) { self.loggingPluginConfiguration = loggingPluginConfiguration self.loggingConstraintsLocalStore = loggingConstraintsLocalStore } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingFilter.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingFilter.swift index 861e05367c..325b3f55f7 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingFilter.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingFilter.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify import AWSPluginsCore +import Foundation /// Provides the concrete implementation for the AWSCloudWatchLoggingFilterBehavior. class AWSCloudWatchLoggingFilter: AWSCloudWatchLoggingFilterBehavior { diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingFilterBehavior.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingFilterBehavior.swift index 0576661123..86c6ffc47b 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingFilterBehavior.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingFilterBehavior.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation /// Defines the default AWSCloudWatchLoggingFilterBehavior to conforms to protocol AWSCloudWatchLoggingFilterBehavior { diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingMonitor.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingMonitor.swift index df405bae0e..fbcf5ad06b 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingMonitor.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingMonitor.swift @@ -33,9 +33,10 @@ class AWSCLoudWatchLoggingMonitor { automaticFlushLogsTimer = createRepeatingTimer( timeInterval: automaticFlushLogsInterval, eventHandler: { [weak self] in - guard let self = self else { return } - self.eventDelegate?.handleAutomaticFlushIntervalEvent() - }) + guard let self else { return } + eventDelegate?.handleAutomaticFlushIntervalEvent() + } + ) automaticFlushLogsTimer?.resume() } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/AWSCloudWatchConstants.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/AWSCloudWatchConstants.swift index 295814e8c5..28bc0e5e8e 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/AWSCloudWatchConstants.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/AWSCloudWatchConstants.swift @@ -8,7 +8,7 @@ import Foundation /// Defines AWS CloudWatch SDK constants -struct AWSCloudWatchConstants { +enum AWSCloudWatchConstants { /// the max byte size of log events that can be sent is 1 MB static let maxBatchByteSize: Int64 = 1_000_000 diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/PluginConstants.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/PluginConstants.swift index 99be961402..57abbdfa9f 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/PluginConstants.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/PluginConstants.swift @@ -6,7 +6,8 @@ // import Foundation -struct PluginConstants { + +enum PluginConstants { static let awsCloudWatchLoggingPluginKey = "awsCloudWatchLoggingPlugin" static let awsCloudWatchLoggingPluginConfigurationKey = "awsCloudWatchLoggingPlugin" static let awsRemoteLoggingConstraintsTagKey = "com.amazonaws.amplify.logging.etag" diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/PluginErrorConstants.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/PluginErrorConstants.swift index bb2c0a4276..f4fb897ae9 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/PluginErrorConstants.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/PluginErrorConstants.swift @@ -5,45 +5,54 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation typealias PluginErrorString = (errorDescription: ErrorDescription, recoverySuggestion: RecoverySuggestion) -struct PluginErrorConstants { +enum PluginErrorConstants { static let decodeConfigurationError: PluginErrorString = ( "Unable to decode configuration", - "Make sure the plugin configuration is JSONValue") + "Make sure the plugin configuration is JSONValue" + ) static let configurationObjectExpected: PluginErrorString = ( "Configuration was not a dictionary literal", - "Make sure the value for the plugin is a dictionary literal with keys 'Bucket' and 'Region'") + "Make sure the value for the plugin is a dictionary literal with keys 'Bucket' and 'Region'" + ) static let missingRegion: PluginErrorString = ( "The 'Region' key is missing from the configuration", - "Make sure 'Region' is in the dictionary for the plugin configuration") + "Make sure 'Region' is in the dictionary for the plugin configuration" + ) static let emptyRegion: PluginErrorString = ( "The region value is empty", - "Add the region as the value to the 'Region' key in the plugin configuration") + "Add the region as the value to the 'Region' key in the plugin configuration" + ) static let invalidRegion: PluginErrorString = ( "The region is invalid", - "Make sure the region is of the AWS regions, like 'us-east-1', etc...") + "Make sure the region is of the AWS regions, like 'us-east-1', etc..." + ) static let missingLogGroupName: PluginErrorString = ( "The 'logGroupName' key is missing from the configuration", - "Make sure 'logGroupName' is in the dictionary for the plugin configuration") + "Make sure 'logGroupName' is in the dictionary for the plugin configuration" + ) static let invalidLogGroupName: PluginErrorString = ( "The logGroupName is invalid", - "Make sure the logGroupName is correct") + "Make sure the logGroupName is correct" + ) static let emptyLogGroupName: PluginErrorString = ( "The logGroupName value is empty", - "Add the group name as the value to the 'logGroupName' key in the plugin configuration") + "Add the group name as the value to the 'logGroupName' key in the plugin configuration" + ) static let serviceConfigurationInitializationError: PluginErrorString = ( "Could not initialize service configuration", - "This should not happen") + "This should not happen" + ) } diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/LoggingConstraintsLocalStore.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/LoggingConstraintsLocalStore.swift index b0e5b06b98..148b69e18c 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/LoggingConstraintsLocalStore.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/LoggingConstraintsLocalStore.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify import AWSPluginsCore +import Foundation protocol LoggingConstraintsLocalStore { func getLocalLoggingConstraints() -> LoggingConstraints? diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/AWSCloudWatchClientHelper.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/AWSCloudWatchClientHelper.swift index b8345288fc..baa18ef0f9 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/AWSCloudWatchClientHelper.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/AWSCloudWatchClientHelper.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import AWSCloudWatchLoggingPlugin import AWSCloudWatchLogs +import Foundation class AWSCloudWatchClientHelper { static func getFilterLogEventCount(client: CloudWatchLogsClientProtocol?, filterPattern: String?, startTime: Date?, endTime: Date?, logGroupName: String?) async throws -> [CloudWatchLogsClientTypes.FilteredLogEvent]? { @@ -19,6 +19,6 @@ class AWSCloudWatchClientHelper { extension Date { var epochMilliseconds: Int { - Int(self.timeIntervalSince1970 * 1_000) + Int(timeIntervalSince1970 * 1_000) } } diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/AWSCloudWatchLoggingPluginIntegrationTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/AWSCloudWatchLoggingPluginIntegrationTests.swift index b19a5cee97..9bd328b307 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/AWSCloudWatchLoggingPluginIntegrationTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/AWSCloudWatchLoggingPluginIntegrationTests.swift @@ -5,11 +5,11 @@ // SPDX-License-Identifier: Apache-2.0 // -import XCTest import AWSCloudWatchLogs +import XCTest @testable import Amplify -@testable import AWSCognitoAuthPlugin @testable import AWSCloudWatchLoggingPlugin +@testable import AWSCognitoAuthPlugin class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { let amplifyConfigurationFile = "testconfiguration/AWSCloudWatchLoggingPluginIntegrationTests-amplifyconfiguration" @@ -22,7 +22,7 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { var amplifyConfigurationLoggingFile = "testconfiguration/AWSCloudWatchLoggingPluginIntegrationTests-amplifyconfiguration_logging" #endif var loggingConfiguration: AWSCloudWatchLoggingPluginConfiguration? - + var useGen2Configuration: Bool { ProcessInfo.processInfo.arguments.contains("GEN2") } @@ -64,13 +64,14 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { let fileURLs = try FileManager.default.contentsOfDirectory( at: URL(string: directory)!, includingPropertiesForKeys: nil, - options: .skipsHiddenFiles) + options: .skipsHiddenFiles + ) for fileURL in fileURLs { try FileManager.default.removeItem(at: fileURL) } try FileManager.default.removeItem(atPath: directory) } - + /// - Given: a AWS CloudWatch Logging plugin /// - When: the escape hatch is requested /// - Then: the AWS CloudWatch client is returned @@ -83,7 +84,7 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { let cloudWatchClient = loggingPlugin.getEscapeHatch() XCTAssertNotNil(cloudWatchClient) } - + /// - Given: a AWS CloudWatch Logging plugin /// - When: log messages is logged and flushed /// - Then: the log messages are logged and sent to AWS CloudWatch @@ -104,16 +105,18 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { try await loggingPlugin.flushLogs() try await Task.sleep(seconds: 30) let cloudWatchClient = loggingPlugin.getEscapeHatch() - try await verifyMessagesSent(plugin: loggingPlugin, - client: cloudWatchClient, - logGroupName: loggingConfiguration?.logGroupName, - messageCount: 4, - message: message, - category: category, - namespace: namespace) + try await verifyMessagesSent( + plugin: loggingPlugin, + client: cloudWatchClient, + logGroupName: loggingConfiguration?.logGroupName, + messageCount: 4, + message: message, + category: category, + namespace: namespace + ) } - + /// - Given: a AWS CloudWatch Logging plugin with logging enabled /// - When: an error log message is logged and flushed /// - Then: the eror log message is logged and sent to AWS CloudWatch @@ -132,15 +135,17 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { try await loggingPlugin.flushLogs() try await Task.sleep(seconds: 30) let cloudWatchClient = loggingPlugin.getEscapeHatch() - try await verifyMessageSent(plugin: loggingPlugin, - client: cloudWatchClient, - logGroupName: loggingConfiguration?.logGroupName, - logLevel: "verbose", - message: message, - category: category, - namespace: namespace) + try await verifyMessageSent( + plugin: loggingPlugin, + client: cloudWatchClient, + logGroupName: loggingConfiguration?.logGroupName, + logLevel: "verbose", + message: message, + category: category, + namespace: namespace + ) } - + /// - Given: a AWS CloudWatch Logging plugin with logging disabled /// - When: an error log message is logged and flushed /// - Then: the eror log message is not logged and sent to AWS CloudWatch @@ -159,19 +164,23 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { try await loggingPlugin.flushLogs() try await Task.sleep(seconds: 30) let cloudWatchClient = loggingPlugin.getEscapeHatch() - try await verifyMessageNotSent(plugin: loggingPlugin, - client: cloudWatchClient, - logGroupName: loggingConfiguration?.logGroupName, - message: message) + try await verifyMessageNotSent( + plugin: loggingPlugin, + client: cloudWatchClient, + logGroupName: loggingConfiguration?.logGroupName, + message: message + ) } - - func verifyMessagesSent(plugin: AWSCloudWatchLoggingPlugin, - client: CloudWatchLogsClientProtocol?, - logGroupName: String?, - messageCount: Int, - message: String, - category: String, - namespace: String) async throws { + + func verifyMessagesSent( + plugin: AWSCloudWatchLoggingPlugin, + client: CloudWatchLogsClientProtocol?, + logGroupName: String?, + messageCount: Int, + message: String, + category: String, + namespace: String + ) async throws { let events = try await getLastMessageSent( plugin: plugin, @@ -179,7 +188,8 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { logGroupName: logGroupName, expectedMessageCount: messageCount, message: message, - requestAttempt: 0) + requestAttempt: 0 + ) XCTAssertEqual(events?.count, messageCount) guard let sentLogMessage = events?.first?.message else { XCTFail("Unable to verify last log message") @@ -189,14 +199,16 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { XCTAssertTrue(sentLogMessage.contains(category)) XCTAssertTrue(sentLogMessage.contains(namespace)) } - - func verifyMessageSent(plugin: AWSCloudWatchLoggingPlugin, - client: CloudWatchLogsClientProtocol?, - logGroupName: String?, - logLevel: String, - message: String, - category: String, - namespace: String) async throws { + + func verifyMessageSent( + plugin: AWSCloudWatchLoggingPlugin, + client: CloudWatchLogsClientProtocol?, + logGroupName: String?, + logLevel: String, + message: String, + category: String, + namespace: String + ) async throws { let events = try await getLastMessageSent( plugin: plugin, @@ -204,7 +216,8 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { logGroupName: logGroupName, expectedMessageCount: 1, message: message, - requestAttempt: 0) + requestAttempt: 0 + ) XCTAssertEqual(events?.count, 1) guard let sentLogMessage = events?.first?.message else { XCTFail("Unable to verify last log message") @@ -215,11 +228,13 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { XCTAssertTrue(sentLogMessage.contains(category)) XCTAssertTrue(sentLogMessage.contains(namespace)) } - - func verifyMessageNotSent(plugin: AWSCloudWatchLoggingPlugin, - client: CloudWatchLogsClientProtocol?, - logGroupName: String?, - message: String) async throws { + + func verifyMessageNotSent( + plugin: AWSCloudWatchLoggingPlugin, + client: CloudWatchLogsClientProtocol?, + logGroupName: String?, + message: String + ) async throws { let events = try await getLastMessageSent( plugin: plugin, @@ -227,21 +242,24 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { logGroupName: logGroupName, expectedMessageCount: 1, message: message, - requestAttempt: 0) + requestAttempt: 0 + ) XCTAssertEqual(events?.count, 0) } - - func getLastMessageSent(plugin: AWSCloudWatchLoggingPlugin, - client: CloudWatchLogsClientProtocol?, - logGroupName: String?, - expectedMessageCount: Int, - message: String, - requestAttempt: Int) async throws -> [CloudWatchLogsClientTypes.FilteredLogEvent]? { + + func getLastMessageSent( + plugin: AWSCloudWatchLoggingPlugin, + client: CloudWatchLogsClientProtocol?, + logGroupName: String?, + expectedMessageCount: Int, + message: String, + requestAttempt: Int + ) async throws -> [CloudWatchLogsClientTypes.FilteredLogEvent]? { let endTime = Date() - let durationInMinutes = requestAttempt+1 - let startTime = endTime.addingTimeInterval(TimeInterval(-durationInMinutes*60)) + let durationInMinutes = requestAttempt + 1 + let startTime = endTime.addingTimeInterval(TimeInterval(-durationInMinutes * 60)) var events = try await AWSCloudWatchClientHelper.getFilterLogEventCount(client: client, filterPattern: message, startTime: startTime, endTime: endTime, logGroupName: logGroupName) - + if events?.count != expectedMessageCount && requestAttempt <= 5 { try await plugin.flushLogs() try await Task.sleep(seconds: 30) @@ -252,9 +270,10 @@ class AWSCloudWatchLoggingPluginIntergrationTests: XCTestCase { logGroupName: logGroupName, expectedMessageCount: expectedMessageCount, message: message, - requestAttempt: attempted) + requestAttempt: attempted + ) } - + return events } } diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/TestConfigHelper.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/TestConfigHelper.swift index 71bc4096d0..be21631165 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/TestConfigHelper.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginHostApp/AWSCloudWatchLoggingPluginIntegrationTests/TestConfigHelper.swift @@ -35,7 +35,7 @@ class TestConfigHelper { let url = URL(fileURLWithPath: path) return try Data(contentsOf: url) } - + static func retrieveLoggingConfiguration(forResource: String) throws -> URL { guard let path = Bundle(for: self).path(forResource: forResource, ofType: "json") else { throw TestConfigError.bundlePathError("Could not retrieve logging configuration file: \(forResource)") diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingMonitorTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingMonitorTests.swift index 48f66b98b0..f574d3b594 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingMonitorTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingMonitorTests.swift @@ -12,20 +12,20 @@ import XCTest @testable import AWSCloudWatchLoggingPlugin final class AWSCloudWatchLoggingMonitorTests: XCTestCase { - + var monitor: AWSCLoudWatchLoggingMonitor! var invokedExpectation: XCTestExpectation! - + override func setUp() async throws { monitor = AWSCLoudWatchLoggingMonitor(flushIntervalInSeconds: 2, eventDelegate: self) invokedExpectation = expectation(description: "Delegate is invoked") } - + override func tearDown() async throws { monitor = nil invokedExpectation = nil } - + /// Given: the the logging monitor is configured with a 2 second interval /// When: the monitor is enabled /// Then: the delegate is autoamtically invoked diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingPluginConfigurationTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingPluginConfigurationTests.swift index 4732522eaf..261bd2c8da 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingPluginConfigurationTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingPluginConfigurationTests.swift @@ -5,33 +5,33 @@ // SPDX-License-Identifier: Apache-2.0 // -@testable import AWSCloudWatchLoggingPlugin import Amplify import XCTest +@testable import AWSCloudWatchLoggingPlugin final class AWSCloudWatchLoggingPluginConfigurationTests: XCTestCase { - + /// Given: a json file with the plugin configuration /// When: it is read from the bundle and decoded /// Then: AWSCloudWatchLoggingPluginConfiguration is created func testDecodeConfigurationFromJson() { let url = Bundle.module.url(forResource: "amplifyconfiguration_logging", withExtension: "json", subdirectory: "TestResources") - + guard let configUrl = url, let data = try? Data(contentsOf: configUrl) else { XCTFail("Unable to load test file") return } - + let jsonDecoder = JSONDecoder() guard let config = try? jsonDecoder.decode(AmplifyConfigurationLogging.self, from: data) else { XCTFail("Unable to deserialize object from json data") return } - + XCTAssertTrue(config.awsCloudWatchLoggingPlugin.enable) XCTAssertEqual(config.awsCloudWatchLoggingPlugin.defaultRemoteConfiguration?.endpoint.absoluteString, "http://www.amazon.com") - XCTAssertEqual(config.awsCloudWatchLoggingPlugin.defaultRemoteConfiguration?.refreshIntervalInSeconds, 1200) + XCTAssertEqual(config.awsCloudWatchLoggingPlugin.defaultRemoteConfiguration?.refreshIntervalInSeconds, 1_200) XCTAssertEqual(config.awsCloudWatchLoggingPlugin.flushIntervalInSeconds, 60) XCTAssertEqual(config.awsCloudWatchLoggingPlugin.localStoreMaxSizeInMB, 5) XCTAssertEqual(config.awsCloudWatchLoggingPlugin.logGroupName, "testLogGroup") @@ -47,7 +47,7 @@ final class AWSCloudWatchLoggingPluginConfigurationTests: XCTestCase { func testRemoteLoggingConstraintsDeserialization() { let url = Bundle.module.url(forResource: "remoteloggingconstraints", withExtension: "json", subdirectory: "TestResources") - + guard let configUrl = url, let data = try? Data(contentsOf: configUrl) else { XCTFail("Unable to load test file") return diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingPluginTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingPluginTests.swift index aa06c28514..144adb6c07 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingPluginTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingPluginTests.swift @@ -7,16 +7,16 @@ @testable import AWSCloudWatchLoggingPlugin -import XCTest import Amplify +import XCTest final class AWSCloudWatchLoggingPluginTests: XCTestCase { - + func testDefaultPluginConstructor() throws { let plugin = AWSCloudWatchLoggingPlugin() XCTAssertEqual(plugin.key, PluginConstants.awsCloudWatchLoggingPluginKey) } - + /// Given: a AWSCloudWatchLoggingPluginConfiguration /// When: AWSCloudWatchLoggingPlugin is constructed /// Then: the configuration can be specified as a parameter @@ -26,7 +26,7 @@ final class AWSCloudWatchLoggingPluginTests: XCTestCase { XCTAssertNotNil(plugin.loggingClient) XCTAssertEqual(plugin.key, PluginConstants.awsCloudWatchLoggingPluginKey) } - + /// Given: a AWSCloudWatchLoggingPlugin /// When: a logger is requested /// Then: loggers a returned @@ -45,7 +45,7 @@ final class AWSCloudWatchLoggingPluginTests: XCTestCase { let defaultLogger = plugin.logger(forNamespace: "test") XCTAssertEqual(defaultLogger.logLevel.rawValue, LogLevel.error.rawValue) } - + /// Given: a AWSCloudWatchLoggingPlugin /// When: a logger is requested with a namespace /// Then: the namespace is set in the logger session controller @@ -55,10 +55,10 @@ final class AWSCloudWatchLoggingPluginTests: XCTestCase { _ = plugin.logger(forCategory: "Category1") var sessionController = plugin.loggingClient.getLoggerSessionController(forCategory: "Category1", logLevel: .error) XCTAssertEqual(sessionController?.namespace, nil) - + _ = plugin.logger(forCategory: "Category2", forNamespace: "testNamespace") sessionController = plugin.loggingClient.getLoggerSessionController(forCategory: "Category2", logLevel: .error) XCTAssertEqual(sessionController?.namespace, "testNamespace") - + } } diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingSessionControllerTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingSessionControllerTests.swift index 9457644826..46c48b6b23 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingSessionControllerTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchLoggingSessionControllerTests.swift @@ -7,9 +7,9 @@ @testable import AWSCloudWatchLoggingPlugin -import XCTest import Amplify import Network +import XCTest @testable import AmplifyTestCommon final class AWSCloudWatchLoggingSessionControllerTests: XCTestCase { @@ -50,11 +50,13 @@ final class AWSCloudWatchLoggingSessionControllerTests: XCTestCase { } } - let bytes = (0..<1024).map { _ in UInt8.random(in: 0..<255) } + let bytes = (0 ..< 1_024).map { _ in UInt8.random(in: 0 ..< 255) } let fileURL = getLogFile() - FileManager.default.createFile(atPath: fileURL.path, - contents: Data(bytes), - attributes: [FileAttributeKey: Any]()) + FileManager.default.createFile( + atPath: fileURL.path, + contents: Data(bytes), + attributes: [FileAttributeKey: Any]() + ) systemUnderTest = AWSCloudWatchLoggingSessionController( credentialsProvider: mockCredentialProvider, authentication: mockAuth, @@ -66,7 +68,8 @@ final class AWSCloudWatchLoggingSessionControllerTests: XCTestCase { region: "us-east-1", localStoreMaxSizeInMB: 1, userIdentifier: nil, - networkMonitor: mockLoggingNetworkMonitor) + networkMonitor: mockLoggingNetworkMonitor + ) systemUnderTest.client = mockCloudWatchLogClient systemUnderTest.enable() try await systemUnderTest.flushLogs() diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchingLoggingFilterTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchingLoggingFilterTests.swift index bf47e2bf55..6e1d78c2a7 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchingLoggingFilterTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/AWSCloudWatchingLoggingFilterTests.swift @@ -14,26 +14,26 @@ final class AWSCloudWatchLoggingFilterTests: XCTestCase { var configuration: AWSCloudWatchLoggingPluginConfiguration! var filter: AWSCloudWatchLoggingFilter! var remoteLoggingConstraints: LoggingConstraints! - + override func setUp() async throws { let configUrl = Bundle.module.url(forResource: "amplifyconfiguration_logging", withExtension: "json", subdirectory: "TestResources") configuration = try AWSCloudWatchLoggingPluginConfiguration.loadConfiguration(from: configUrl!) - + let resolver = AWSCloudWatchLoggingConstraintsResolver(loggingPluginConfiguration: configuration!) filter = AWSCloudWatchLoggingFilter(loggingConstraintsResolver: resolver) - + let remoteUrl = Bundle.module.url(forResource: "remoteloggingconstraints", withExtension: "json", subdirectory: "TestResources") let data = try Data(contentsOf: remoteUrl!) remoteLoggingConstraints = try JSONDecoder().decode(LoggingConstraints.self, from: data) } - + override func tearDown() async throws { UserDefaults.standard.removeObject(forKey: PluginConstants.awsRemoteLoggingConstraintsKey) configuration = nil filter = nil remoteLoggingConstraints = nil } - + /// Given: the local logging constraints configuration that enables logging /// When: `canLog` is called from AWSCloudWatchLoggingFilter /// Then: canLog returns true @@ -41,17 +41,17 @@ final class AWSCloudWatchLoggingFilterTests: XCTestCase { XCTAssertTrue(filter.canLog(withCategory: "AUTH", logLevel: .error, userIdentifier: nil)) XCTAssertTrue(filter.canLog(withCategory: "API", logLevel: .error, userIdentifier: nil)) XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .error, userIdentifier: nil)) - + XCTAssertTrue(filter.canLog(withCategory: "API", logLevel: .warn, userIdentifier: nil)) XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .warn, userIdentifier: nil)) - + XCTAssertTrue(filter.canLog(withCategory: "API", logLevel: .info, userIdentifier: "cognitoSub1")) XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .info, userIdentifier: "cognitoSub1")) - + XCTAssertTrue(filter.canLog(withCategory: "API", logLevel: .warn, userIdentifier: "cognitoSub2")) XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .warn, userIdentifier: "cognitoSub2")) } - + /// Given: the local logging constraints configuration that disables logging /// When: `canLog` is called from AWSCloudWatchLoggingFilter /// Then: `canLog` returns false @@ -59,67 +59,67 @@ final class AWSCloudWatchLoggingFilterTests: XCTestCase { XCTAssertFalse(filter.canLog(withCategory: "AUTH", logLevel: .warn, userIdentifier: nil)) XCTAssertFalse(filter.canLog(withCategory: "API", logLevel: .info, userIdentifier: nil)) XCTAssertFalse(filter.canLog(withCategory: "STORAGE", logLevel: .info, userIdentifier: nil)) - + XCTAssertFalse(filter.canLog(withCategory: "AUTH", logLevel: .info, userIdentifier: "cognitoSub1")) XCTAssertFalse(filter.canLog(withCategory: "API", logLevel: .verbose, userIdentifier: "cognitoSub1")) XCTAssertFalse(filter.canLog(withCategory: "STORAGE", logLevel: .verbose, userIdentifier: "cognitoSub1")) - + XCTAssertFalse(filter.canLog(withCategory: "AUTH", logLevel: .warn, userIdentifier: "cognitoSub2")) XCTAssertFalse(filter.canLog(withCategory: "API", logLevel: .info, userIdentifier: "cognitoSub2")) XCTAssertFalse(filter.canLog(withCategory: "STORAGE", logLevel: .info, userIdentifier: "cognitoSub2")) } - + /// Given: the remote logging constraints configuration that enables logging /// When: `canLog` is called from AWSCloudWatchLoggingFilter /// Then: `canLog` returns true func testDefaultsToRemoteConfigurationCanLog() { let localStore = UserDefaults.standard - localStore.setLocalLoggingConstraints(loggingConstraints: self.remoteLoggingConstraints) - let resolver = AWSCloudWatchLoggingConstraintsResolver(loggingPluginConfiguration: self.configuration, loggingConstraintsLocalStore: localStore) + localStore.setLocalLoggingConstraints(loggingConstraints: remoteLoggingConstraints) + let resolver = AWSCloudWatchLoggingConstraintsResolver(loggingPluginConfiguration: configuration, loggingConstraintsLocalStore: localStore) filter = AWSCloudWatchLoggingFilter(loggingConstraintsResolver: resolver) - + XCTAssertTrue(filter.canLog(withCategory: "ANALYTICS", logLevel: .error, userIdentifier: nil)) - + XCTAssertTrue(filter.canLog(withCategory: "DATASTORE", logLevel: .warn, userIdentifier: "cognitoSub1")) XCTAssertTrue(filter.canLog(withCategory: "DATASTORE", logLevel: .info, userIdentifier: "cognitoSub1")) XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .warn, userIdentifier: "cognitoSub1")) XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .debug, userIdentifier: "cognitoSub1")) - + XCTAssertTrue(filter.canLog(withCategory: "AUTH", logLevel: .error, userIdentifier: "sub1")) XCTAssertTrue(filter.canLog(withCategory: "AUTH", logLevel: .warn, userIdentifier: "sub1")) XCTAssertTrue(filter.canLog(withCategory: "AUTH", logLevel: .info, userIdentifier: "sub1")) - + XCTAssertTrue(filter.canLog(withCategory: "AUTH", logLevel: .error, userIdentifier: "sub3")) XCTAssertTrue(filter.canLog(withCategory: "AUTH", logLevel: .warn, userIdentifier: "sub3")) XCTAssertTrue(filter.canLog(withCategory: "AUTH", logLevel: .info, userIdentifier: "sub3")) - + XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .error, userIdentifier: "sub3")) XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .warn, userIdentifier: "sub3")) XCTAssertTrue(filter.canLog(withCategory: "STORAGE", logLevel: .info, userIdentifier: "sub3")) - + } - + /// Given: the remote logging constraints configuration that disables logging /// When: `canLog` is called from AWSCloudWatchLoggingFilter /// Then: `canLog` returns false func testDefaultsToRemoteConfigurationCannotLog() { let localStore = UserDefaults.standard - localStore.setLocalLoggingConstraints(loggingConstraints: self.remoteLoggingConstraints) - let resolver = AWSCloudWatchLoggingConstraintsResolver(loggingPluginConfiguration: self.configuration, loggingConstraintsLocalStore: localStore) + localStore.setLocalLoggingConstraints(loggingConstraints: remoteLoggingConstraints) + let resolver = AWSCloudWatchLoggingConstraintsResolver(loggingPluginConfiguration: configuration, loggingConstraintsLocalStore: localStore) filter = AWSCloudWatchLoggingFilter(loggingConstraintsResolver: resolver) - - + + XCTAssertFalse(filter.canLog(withCategory: "ANALYTICS", logLevel: .warn, userIdentifier: nil)) XCTAssertFalse(filter.canLog(withCategory: "AUTH", logLevel: .verbose, userIdentifier: nil)) XCTAssertFalse(filter.canLog(withCategory: "API", logLevel: .warn, userIdentifier: nil)) - + XCTAssertFalse(filter.canLog(withCategory: "DATASTORE", logLevel: .verbose, userIdentifier: "cognitoSub1")) XCTAssertFalse(filter.canLog(withCategory: "STORAGE", logLevel: .verbose, userIdentifier: "cognitoSub1")) - + XCTAssertFalse(filter.canLog(withCategory: "AUTH", logLevel: .verbose, userIdentifier: "sub1")) XCTAssertFalse(filter.canLog(withCategory: "API", logLevel: .error, userIdentifier: "sub1")) XCTAssertFalse(filter.canLog(withCategory: "STORAGE", logLevel: .error, userIdentifier: "sub1")) - + XCTAssertFalse(filter.canLog(withCategory: "AUTH", logLevel: .verbose, userIdentifier: "sub3")) XCTAssertFalse(filter.canLog(withCategory: "API", logLevel: .error, userIdentifier: "sub3")) XCTAssertFalse(filter.canLog(withCategory: "STORAGE", logLevel: .verbose, userIdentifier: "sub3")) diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/BroadcastLoggerTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/BroadcastLoggerTests.swift index 00ed5be675..c0e4478098 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/BroadcastLoggerTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/BroadcastLoggerTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import Amplify final class BroadcastLoggerTests: XCTestCase { - + var systemUnderTest: BroadcastLogger! var mockLogger1: MockLogger! var mockLogger2: MockLogger! @@ -19,23 +19,23 @@ final class BroadcastLoggerTests: XCTestCase { mockLogger2 = MockLogger() systemUnderTest = BroadcastLogger(targets: [mockLogger1, mockLogger2]) } - + override func tearDown() async throws { mockLogger1 = nil mockLogger2 = nil systemUnderTest = nil } - + /// Given: broadcast logger /// When: an error message is logged /// Then: the same error message is broadcasted to all underlying loggers func testBroadcastErrorLog() { XCTAssertEqual(mockLogger1.entries.count, 0) XCTAssertEqual(mockLogger2.entries.count, 0) - + let message = "Error message" systemUnderTest.error(message) - + XCTAssertEqual(mockLogger1.entries.count, 1) XCTAssertEqual(mockLogger2.entries.count, 1) XCTAssertEqual(mockLogger1.entries[0].level, .error) @@ -43,17 +43,17 @@ final class BroadcastLoggerTests: XCTestCase { XCTAssertEqual(mockLogger1.entries[0].message, message) XCTAssertEqual(mockLogger2.entries[0].message, message) } - + /// Given: broadcast logger /// When: a warn message is logged /// Then: the same warn message is broadcasted to all underlying loggers func testBroadcastWarnLog() { XCTAssertEqual(mockLogger1.entries.count, 0) XCTAssertEqual(mockLogger2.entries.count, 0) - + let message = "Warn message" systemUnderTest.warn(message) - + XCTAssertEqual(mockLogger1.entries.count, 1) XCTAssertEqual(mockLogger2.entries.count, 1) XCTAssertEqual(mockLogger1.entries[0].level, .warn) @@ -61,17 +61,17 @@ final class BroadcastLoggerTests: XCTestCase { XCTAssertEqual(mockLogger1.entries[0].message, message) XCTAssertEqual(mockLogger2.entries[0].message, message) } - + /// Given: broadcast logger /// When: a debug message is logged /// Then: the same debug message is broadcasted to all underlying loggers func testBroadcastDebugLog() { XCTAssertEqual(mockLogger1.entries.count, 0) XCTAssertEqual(mockLogger2.entries.count, 0) - + let message = "Debug message" systemUnderTest.debug(message) - + XCTAssertEqual(mockLogger1.entries.count, 1) XCTAssertEqual(mockLogger2.entries.count, 1) XCTAssertEqual(mockLogger1.entries[0].level, .debug) @@ -79,17 +79,17 @@ final class BroadcastLoggerTests: XCTestCase { XCTAssertEqual(mockLogger1.entries[0].message, message) XCTAssertEqual(mockLogger2.entries[0].message, message) } - + /// Given: broadcast logger /// When: an info message is logged /// Then: the same info message is broadcasted to all underlying loggers func testBroadcastInfoLog() { XCTAssertEqual(mockLogger1.entries.count, 0) XCTAssertEqual(mockLogger2.entries.count, 0) - + let message = "Info message" systemUnderTest.info(message) - + XCTAssertEqual(mockLogger1.entries.count, 1) XCTAssertEqual(mockLogger2.entries.count, 1) XCTAssertEqual(mockLogger1.entries[0].level, .info) @@ -97,17 +97,17 @@ final class BroadcastLoggerTests: XCTestCase { XCTAssertEqual(mockLogger1.entries[0].message, message) XCTAssertEqual(mockLogger2.entries[0].message, message) } - + /// Given: broadcast logger /// When: a verbose message is logged /// Then: the same verbose message is broadcasted to all underlying loggers func testBroadcastVerboseLog() { XCTAssertEqual(mockLogger1.entries.count, 0) XCTAssertEqual(mockLogger2.entries.count, 0) - + let message = "Verbose message" systemUnderTest.verbose(message) - + XCTAssertEqual(mockLogger1.entries.count, 1) XCTAssertEqual(mockLogger2.entries.count, 1) XCTAssertEqual(mockLogger1.entries[0].level, .verbose) @@ -115,7 +115,7 @@ final class BroadcastLoggerTests: XCTestCase { XCTAssertEqual(mockLogger1.entries[0].message, message) XCTAssertEqual(mockLogger2.entries[0].message, message) } - + /// Given: a broadcast logger /// When: log level is modified /// Then: all underlying logger log levels are modified diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/CloudWatchLogConsumerTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/CloudWatchLogConsumerTests.swift index 7fdfa20757..2f26cc9c74 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/CloudWatchLogConsumerTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/CloudWatchLogConsumerTests.swift @@ -5,22 +5,22 @@ // SPDX-License-Identifier: Apache-2.0 // -import AWSCloudWatchLogs import Amplify +import AWSCloudWatchLogs import Foundation import XCTest @testable import AWSCloudWatchLoggingPlugin final class CloudWatchLogConsumerTests: XCTestCase { - + var systemUnderTest: CloudWatchLoggingConsumer! var client: MockCloudWatchLogsClient! var logGroupName: String! var logStreamName: String! var entries: [LogEntry]! var interactions: [String]! - + override func setUp() async throws { entries = [] interactions = [] @@ -29,7 +29,7 @@ final class CloudWatchLogConsumerTests: XCTestCase { logStreamName = UUID().uuidString systemUnderTest = await CloudWatchLoggingConsumer(client: client, logGroupName: logGroupName, userIdentifier: "guest") } - + override func tearDown() async throws { entries = nil interactions = nil @@ -38,12 +38,12 @@ final class CloudWatchLogConsumerTests: XCTestCase { logStreamName = nil systemUnderTest = nil } - + /// - Given: a single log entry /// - When: CloudWatchLoggingConsumer consumes a log batch /// - Then: the batch is read and completed func testConsumerProcessValidLogBatch() async throws { - self.entries = [LogEntry(category: "CloudWatchLogConsumerTests", namespace:nil, level: .error, message: "")] + entries = [LogEntry(category: "CloudWatchLogConsumerTests", namespace: nil, level: .error, message: "")] try await systemUnderTest.consume(batch: self) XCTAssertEqual(client.interactions, [ "describeLogStreams(input:)", @@ -55,14 +55,14 @@ final class CloudWatchLogConsumerTests: XCTestCase { "complete()" ]) } - + /// - Given: a list of log entries /// - When: CloudWatchLoggingConsumer consumes a log batch /// - Then: the batch is read and completed func testConsumerProcessValidLargeBatch() async throws { let batchSize = 32 - for _ in 0.. Bool { - if (lhs.created == rhs.created) { + if lhs.created == rhs.created { let formatter = CloudWatchLoggingEntryFormatter() return formatter.format(entry: lhs) < formatter.format(entry: rhs) } diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/LogEntryTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/LogEntryTests.swift index 9438899a7e..6fb671d914 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/LogEntryTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/LogEntryTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import AWSCloudWatchLoggingPlugin final class LogEntryTests: XCTestCase { - + let levels = [ LogLevel.error, LogLevel.warn, @@ -19,7 +19,7 @@ final class LogEntryTests: XCTestCase { LogLevel.debug, LogLevel.verbose ] - + /// Given: a Log Entry /// When: attributes are acccessed /// Then: attributes are set correctly @@ -32,7 +32,7 @@ final class LogEntryTests: XCTestCase { XCTAssertEqual(sut.logLevel, level) } } - + /// Given: a Log Entry /// When: encoding and decoding occurs /// Then: the log entry is endoded and decoded @@ -49,7 +49,7 @@ final class LogEntryTests: XCTestCase { XCTAssertEqual(decoded.logLevel, level) } } - + /// Given: a Log Entry json with invalid log level that is below 0 /// When: decoding occurs /// Then: the log level defaults to Error diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/LogFileTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/LogFileTests.swift index 7de2cb37d9..5c81e92a05 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/LogFileTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/LogFileTests.swift @@ -11,68 +11,68 @@ import XCTest @testable import AWSCloudWatchLoggingPlugin final class LogFileTests: XCTestCase { - + var systemUnderTest: LogFile! var fileURL: URL! var sizeLimitInBytes: UInt64! - + override func setUp() async throws { let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString) guard FileManager.default.createFile(atPath: url.path, contents: nil) else { throw NSError() } - - sizeLimitInBytes = 1024 + + sizeLimitInBytes = 1_024 fileURL = url systemUnderTest = try LogFile(forWritingTo: fileURL, sizeLimitInBytes: sizeLimitInBytes) } - + override func tearDown() async throws { systemUnderTest = nil - + try FileManager.default.removeItem(at: fileURL) fileURL = nil sizeLimitInBytes = nil } - + /// Given: a data /// When: Log file writes to file /// Then: the log file writes to disk if there is enough space func testLogFileWriteToSpaceLimit() throws { - let bytes = (0.. String) { entries.append(Entry(level: .error, message: message())) } - + func error(error: Error) { entries.append(Entry(level: .error, message: String(describing: error))) } - + func warn(_ message: @autoclosure () -> String) { entries.append(Entry(level: .warn, message: message())) } - + func info(_ message: @autoclosure () -> String) { entries.append(Entry(level: .info, message: message())) } - + func debug(_ message: @autoclosure () -> String) { entries.append(Entry(level: .debug, message: message())) } - + func verbose(_ message: @autoclosure () -> String) { entries.append(Entry(level: .verbose, message: message())) } diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/RotatingLogBatchTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/RotatingLogBatchTests.swift index 39d4e44633..283d33f6fb 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/RotatingLogBatchTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/RotatingLogBatchTests.swift @@ -1,41 +1,41 @@ -//// +// // Copyright Amazon.com Inc. or its affiliates. // All Rights Reserved. // // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation import XCTest @testable import AWSCloudWatchLoggingPlugin final class RotatingLogBatchTests: XCTestCase { var fileURL: URL! - + override func setUp() async throws { let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString) guard FileManager.default.createFile(atPath: url.path, contents: nil) else { throw NSError() } - + fileURL = url - let logFile = try LogFile(forWritingTo: fileURL, sizeLimitInBytes: 1024) + let logFile = try LogFile(forWritingTo: fileURL, sizeLimitInBytes: 1_024) let entry = LogEntry(category: "Auth", namespace: "namespace", level: .error, message: "error message") let data = try LogEntryCodec().encode(entry: entry) try logFile.write(data: data) } - + override func tearDown() async throws { do { try FileManager.default.removeItem(at: fileURL) fileURL = nil } catch { - + } } - + /// Given: a rotating log batch /// When: entries a read /// Then: Log Entries are created from log file @@ -48,7 +48,7 @@ final class RotatingLogBatchTests: XCTestCase { XCTAssertEqual(entries![0].message, "error message") XCTAssertEqual(entries![0].namespace, "namespace") } - + /// Given: a rotating log batch /// When: batch is completed /// Then: the log file is removed from disk diff --git a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/RotatingLoggerTests.swift b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/RotatingLoggerTests.swift index e82a93bd91..08f076c931 100644 --- a/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/RotatingLoggerTests.swift +++ b/AmplifyPlugins/Logging/Tests/AWSCloudWatchLoggingPluginTests/RotatingLoggerTests.swift @@ -12,27 +12,29 @@ import XCTest @testable import AWSCloudWatchLoggingPlugin final class RotatingLoggerTests: XCTestCase { - + var systemUnderTest: RotatingLogger! var directory: URL! var fileCountLimit = 5 - var fileSizeLimitInBytes = 1024 + var fileSizeLimitInBytes = 1_024 var subscription: Combine.Cancellable! { willSet { subscription?.cancel()} } var batches: [any LogBatch]! - + override func setUp() async throws { directory = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString) try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true) - - systemUnderTest = try RotatingLogger(directory: directory, - category: "RotatingLoggerTests", - namespace: nil, - logLevel: .verbose, - fileSizeLimitInBytes: fileSizeLimitInBytes) + + systemUnderTest = try RotatingLogger( + directory: directory, + category: "RotatingLoggerTests", + namespace: nil, + logLevel: .verbose, + fileSizeLimitInBytes: fileSizeLimitInBytes + ) batches = [] subscription = systemUnderTest.logBatchPublisher.sink(receiveValue: { [weak self] in self?.batches.append($0) }) } - + override func tearDown() async throws { systemUnderTest = nil subscription = nil @@ -40,14 +42,14 @@ final class RotatingLoggerTests: XCTestCase { try FileManager.default.removeItem(at: directory) directory = nil } - + /// Given: a rotating logger /// When: a record is written /// Then: a log file is created func testRotatingLogRecordsToLogFile() async throws { let minimalSizeOfEachRecord = try LogEntry.minimumSizeForLogEntry(level: .error) let recordsPerFile = Int(fileSizeLimitInBytes) / minimalSizeOfEachRecord - for _ in 0..<(recordsPerFile + 1) { + for _ in 0 ..< (recordsPerFile + 1) { try await systemUnderTest.record(level: .error, message: "") } try await systemUnderTest.synchronize() @@ -72,7 +74,7 @@ final class RotatingLoggerTests: XCTestCase { try await Task.sleep(seconds: 0.100) try assertSingleEntryWith(level: .error, message: error.message) } - + /// Given: a rotating logger /// When: error message is recorded /// Then: the log level and message is written @@ -82,7 +84,7 @@ final class RotatingLoggerTests: XCTestCase { try await logWith(level: level, message: message) try assertSingleEntryWith(level: level, message: message) } - + /// Given: a rotating logger /// When: verbose message is recorded /// Then: the log level and message is written @@ -92,7 +94,7 @@ final class RotatingLoggerTests: XCTestCase { try await logWith(level: level, message: message) try assertSingleEntryWith(level: level, message: message) } - + /// Given: a rotating logger /// When: warn message is recorded /// Then: the log level and message is written @@ -102,7 +104,7 @@ final class RotatingLoggerTests: XCTestCase { try await logWith(level: level, message: message) try assertSingleEntryWith(level: level, message: message) } - + /// Given: a rotating logger /// When: info message is recorded /// Then: the log level and message is written @@ -112,7 +114,7 @@ final class RotatingLoggerTests: XCTestCase { try await logWith(level: level, message: message) try assertSingleEntryWith(level: level, message: message) } - + /// Given: a rotating logger /// When: debug message is recorded /// Then: the log level and message is written @@ -122,7 +124,7 @@ final class RotatingLoggerTests: XCTestCase { try await logWith(level: level, message: message) try assertSingleEntryWith(level: level, message: message) } - + /// Given: a rotating logger with 1 existing log batch /// When: get log batch is called after writing and rotating to new log file /// Then: a list of log batches with a count of 2 is returned @@ -130,15 +132,15 @@ final class RotatingLoggerTests: XCTestCase { var logBatches = try await systemUnderTest.getLogBatches() XCTAssertEqual(logBatches.count, 1) let size = try LogEntry.minimumSizeForLogEntry(level: .error) - let recordsPerFile = (fileSizeLimitInBytes/size) - for _ in 0..