From e08411ab6193282826b828a41b02ba2f969f5990 Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <6162866+harsh62@users.noreply.github.com> Date: Thu, 19 Jun 2025 21:40:13 -0400 Subject: [PATCH 1/2] fix(logging): crash on release builds in rotation logger --- .../AWSCloudWatchLoggingSession.swift | 10 ++++++++-- .../CloudWatchLoggingStreamNameFormatter.swift | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift index cfa0013092..ed1d227589 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift @@ -43,12 +43,18 @@ 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 + + // Calculate appropriate file size limit (individual file, not total cache) + // Use a reasonable file size limit that's a fraction of the total cache size + // Ensure it meets the minimum requirement of 1KB + let totalCacheSizeInBytes = localStoreMaxSizeInMB * 1048576 + let fileSizeLimitInBytes = max(LogRotation.minimumFileSizeLimitInBytes, totalCacheSizeInBytes / 5) + return try RotatingLogger(directory: directory, category: category, namespace: namespace, logLevel: logLevel, - fileSizeLimitInBytes: cacheMaxSizeInBytes) + fileSizeLimitInBytes: fileSizeLimitInBytes) } private static func directory(for category: String, userIdentifier: String?, fileManager: FileManager = .default) throws -> URL { diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingStreamNameFormatter.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingStreamNameFormatter.swift index 94fb9850ba..08031decbd 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingStreamNameFormatter.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingStreamNameFormatter.swift @@ -44,4 +44,11 @@ struct CloudWatchLoggingStreamNameFormatter { func formattedStreamName() async -> String { return "\(await deviceIdentifier ?? "").\(userIdentifier ?? "guest")" } + + // Add the missing deviceIdentifierFromBundle static method + private static func deviceIdentifierFromBundle() -> String? { + // Use bundle identifier as a fallback device identifier + // This provides a consistent identifier per app installation + return Bundle.main.bundleIdentifier + } } From 0e7d11e8d537c4bc04be2b856f7dc2fb604ba81d Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <6162866+harsh62@users.noreply.github.com> Date: Tue, 24 Jun 2025 12:40:52 -0400 Subject: [PATCH 2/2] worked on review comment --- .../AWSCloudWatchLoggingSession.swift | 7 +++++-- .../Persistence/LogRotation.swift | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift index ed1d227589..7e470dd935 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/AWSCloudWatchLoggingSession.swift @@ -48,8 +48,11 @@ final class AWSCloudWatchLoggingSession { // Use a reasonable file size limit that's a fraction of the total cache size // Ensure it meets the minimum requirement of 1KB let totalCacheSizeInBytes = localStoreMaxSizeInMB * 1048576 - let fileSizeLimitInBytes = max(LogRotation.minimumFileSizeLimitInBytes, totalCacheSizeInBytes / 5) - + let fileSizeLimitInBytes = max( + LogRotation.minimumFileSizeLimitInBytes, + totalCacheSizeInBytes / LogRotation.fileCountLimit + ) + return try RotatingLogger(directory: directory, category: category, namespace: namespace, diff --git a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift index 32552df26c..cd5fdca853 100644 --- a/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift +++ b/AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift @@ -17,12 +17,13 @@ final class LogRotation { } static let minimumFileSizeLimitInBytes = 1024 /* 1KB */ + static let fileCountLimit: Int = 5 /// The name pattern of files managed by `LogRotation`. private static let filePattern = #"amplify[.]([0-9])[.]log"# let directory: URL - let fileCountLimit: Int = 5 + let fileSizeLimitInBytes: UInt64 private(set) var currentLogFile: LogFile { @@ -40,7 +41,7 @@ final class LogRotation { self.directory = directory.absoluteURL self.fileSizeLimitInBytes = UInt64(fileSizeLimitInBytes) self.currentLogFile = try Self.selectNextLogFile(from: self.directory, - fileCountLimit: fileCountLimit, + fileCountLimit: Self.fileCountLimit, fileSizeLimitInBytes: self.fileSizeLimitInBytes) } @@ -55,7 +56,7 @@ final class LogRotation { /// 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, + fileCountLimit: Self.fileCountLimit, fileSizeLimitInBytes: self.fileSizeLimitInBytes) }