Skip to content

Commit 205546c

Browse files
thisisabhashharsh62
andcommitted
chore(logging): move shared code to internal module (#4206)
* feat(logging): add v3 cloudwatch @SPI definitions * add privacyinfo * chore(logging): move shared code to internal module * fix unit tests --------- Co-authored-by: Harsh <6162866+harsh62@users.noreply.github.com>
1 parent 66eb972 commit 205546c

29 files changed

Lines changed: 142 additions & 113 deletions

AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Consumer/CloudWatchLoggingStreamNameFormatter.swift renamed to AmplifyPlugins/Internal/Sources/InternalCloudWatchLogging/Consumer/CloudWatchLoggingStreamNameFormatter.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ import AppKit
2020
#endif
2121

2222
/// Responsible for creating pre-formatted CloudWatch stream names.
23-
struct CloudWatchLoggingStreamNameFormatter {
23+
package struct CloudWatchLoggingStreamNameFormatter {
2424

25-
let userIdentifier: String?
26-
var deviceIdentifier: String? {
25+
package let userIdentifier: String?
26+
package var deviceIdentifier: String? {
2727
get async {
2828
#if canImport(WatchKit)
2929
await WKInterfaceDevice.current().identifierForVendor?.uuidString
@@ -37,11 +37,11 @@ struct CloudWatchLoggingStreamNameFormatter {
3737
}
3838
}
3939

40-
init(userIdentifier: String? = nil) {
40+
package init(userIdentifier: String? = nil) {
4141
self.userIdentifier = userIdentifier
4242
}
4343

44-
func formattedStreamName() async -> String {
44+
package func formattedStreamName() async -> String {
4545
return await "\(deviceIdentifier ?? "").\(userIdentifier ?? "guest")"
4646
}
4747

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
10+
/// Represents a batch of log entries to produce/consume.
11+
package protocol LogBatch {
12+
/// Read the log entries for this log batch.
13+
func readEntries() throws -> [LogEntryRepresentable]
14+
15+
/// Log batch has completed, complete the batch by removing from file system.
16+
func complete() throws
17+
}

AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Domain/LogBatchConsumer.swift renamed to AmplifyPlugins/Internal/Sources/InternalCloudWatchLogging/Domain/LogBatchConsumer.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@
77

88
import Foundation
99

10-
/// Represents a general consumer for contents of a
11-
/// [LogFile](x-source-tag://LogFile)
12-
///
13-
protocol LogBatchConsumer {
10+
package protocol LogBatchConsumer {
1411

1512
/// Processes the given [LogBatch](x-source-tag://LogBatch) and ensures to call
1613
/// [LogBatch.complete](x-source-tag://LogBatch.complete) on the given `batch` when
1714
/// done.
1815
func consume(batch: LogBatch) async throws
19-
}
16+
}

AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Domain/LogBatchProducer.swift renamed to AmplifyPlugins/Internal/Sources/InternalCloudWatchLogging/Domain/LogBatchProducer.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import Combine
99

10-
protocol LogBatchProducer {
10+
/// Protocol for a producer of log batches via Combine.
11+
package protocol LogBatchProducer {
1112
var logBatchPublisher: AnyPublisher<LogBatch, Never> { get }
1213
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
10+
/// Protocol that abstracts a log entry for use in shared logging infrastructure.
11+
/// Each consuming target provides its own concrete `LogEntry` type.
12+
package protocol LogEntryRepresentable {
13+
var created: Date { get }
14+
var message: String { get }
15+
var millisecondsSince1970: Int { get }
16+
}

AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogActor.swift renamed to AmplifyPlugins/Internal/Sources/InternalCloudWatchLogging/Persistence/LogActor.swift

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,23 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
import Amplify
98
import Combine
109
import Foundation
1110

12-
/// Wrapper around a LogRotation to ensure
13-
/// thread-safe usage.
14-
actor LogActor {
11+
/// Wrapper around a LogRotation to ensure thread-safe usage.
12+
package actor LogActor {
1513

1614
private let rotation: LogRotation
1715
private let rotationSubject: PassthroughSubject<URL, Never>
1816

1917
/// Initialized the actor with the given directory and fileCountLimit.
20-
init(directory: URL, fileSizeLimitInBytes: Int) throws {
18+
package init(directory: URL, fileSizeLimitInBytes: Int) throws {
2119
self.rotation = try LogRotation(directory: directory, fileSizeLimitInBytes: fileSizeLimitInBytes)
2220
self.rotationSubject = PassthroughSubject()
2321
}
2422

2523
/// Attempts to persist the given log entry.
26-
func record(_ entry: LogEntry) throws {
27-
let data = try LogEntryCodec().encode(entry: entry)
24+
package func record(_ data: Data) throws {
2825
try write(data)
2926
}
3027

@@ -40,22 +37,20 @@ actor LogActor {
4037
}
4138
}
4239

43-
func rotationPublisher() -> AnyPublisher<URL, Never> {
40+
package func rotationPublisher() -> AnyPublisher<URL, Never> {
4441
return rotationSubject.eraseToAnyPublisher()
4542
}
4643

4744
/// Ensures the contents of the underlying file are flushed to disk.
48-
///
49-
/// - Tag: LogActor.record
50-
func synchronize() throws {
45+
package func synchronize() throws {
5146
try rotation.currentLogFile.synchronize()
5247
}
5348

54-
func getLogs() throws -> [URL] {
49+
package func getLogs() throws -> [URL] {
5550
return try rotation.getAllLogs()
5651
}
5752

58-
func deleteLogs() throws {
53+
package func deleteLogs() throws {
5954
try rotation.reset()
6055
try synchronize()
6156
}

AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogFile.swift renamed to AmplifyPlugins/Internal/Sources/InternalCloudWatchLogging/Persistence/LogFile.swift

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,24 @@
77

88
import Foundation
99

10-
/// Represents an individual log file on disk used as part of a
11-
/// LogRotation
12-
final class LogFile {
13-
let fileURL: URL
14-
let sizeLimitInBytes: UInt64
10+
/// Represents an individual log file on disk used as part of a LogRotation.
11+
package final class LogFile {
12+
package let fileURL: URL
13+
package let sizeLimitInBytes: UInt64
1514

1615
private let handle: FileHandle
1716
private var count: UInt64
1817

1918
/// Creates a new file with the given URL and sets its attributes accordingly.
20-
init(forWritingTo fileURL: URL, sizeLimitInBytes: UInt64) throws {
19+
package init(forWritingTo fileURL: URL, sizeLimitInBytes: UInt64) throws {
2120
self.fileURL = fileURL
2221
self.sizeLimitInBytes = sizeLimitInBytes
2322
self.handle = try FileHandle(forWritingTo: fileURL)
2423
self.count = 0
2524
}
2625

2726
/// Opens a file for updating with the given URL and sets its attributes accordingly.
28-
init(forAppending fileURL: URL, sizeLimitInBytes: UInt64) throws {
27+
package init(forAppending fileURL: URL, sizeLimitInBytes: UInt64) throws {
2928
self.fileURL = fileURL
3029
self.sizeLimitInBytes = sizeLimitInBytes
3130
self.handle = try FileHandle(forUpdating: fileURL)
@@ -41,7 +40,7 @@ final class LogFile {
4140
}
4241

4342
/// Returns the number of bytes available in the underlying file.
44-
var available: UInt64 {
43+
package var available: UInt64 {
4544
if sizeLimitInBytes > count {
4645
return sizeLimitInBytes - count
4746
} else {
@@ -50,23 +49,22 @@ final class LogFile {
5049
}
5150

5251
/// Attempts to close the underlying log file.
53-
func close() throws {
52+
package func close() throws {
5453
try handle.close()
5554
}
5655

57-
/// Atempts to flush the receivers contents to disk.
58-
func synchronize() throws {
56+
/// Attempts to flush the receivers contents to disk.
57+
package func synchronize() throws {
5958
try handle.synchronize()
6059
}
6160

6261
/// - Returns: true if writing to the underlying log file will keep its size below the limit.
63-
func hasSpace(for data: Data) -> Bool {
62+
package func hasSpace(for data: Data) -> Bool {
6463
return UInt64(data.count) <= available
6564
}
6665

67-
/// Writes the given **single line of text** represented as a
68-
/// Data to the underlying log file.
69-
func write(data: Data) throws {
66+
/// Writes the given data to the underlying log file.
67+
package func write(data: Data) throws {
7068
if #available(macOS 12.0, iOS 13.4, watchOS 6.2, tvOS 13.4, *) {
7169
try handle.write(contentsOf: data)
7270
} else {
@@ -75,5 +73,4 @@ final class LogFile {
7573
try handle.synchronize()
7674
count = count + UInt64(data.count) // swiftlint:disable:this shorthand_operator
7775
}
78-
7976
}

AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Persistence/LogRotation.swift renamed to AmplifyPlugins/Internal/Sources/InternalCloudWatchLogging/Persistence/LogRotation.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,32 @@
88
import Foundation
99

1010
/// Represents a directory that contains a set of log files that are part of a LogRotation.
11-
final class LogRotation {
11+
package final class LogRotation {
1212

13-
enum LogRotationError: Error {
13+
package enum LogRotationError: Error {
1414
/// Represents the scenario when a caller attempts to initialize a
1515
/// `LogRotation` with an invalid file size limit (minimum is 1KB).
1616
case invalidFileSizeLimitInBytes(Int)
1717
}
1818

19-
static let minimumFileSizeLimitInBytes = 1_024 /* 1KB */
20-
static let fileCountLimit: Int = 5
19+
package static let minimumFileSizeLimitInBytes = 1_024 /* 1KB */
20+
package static let fileCountLimit: Int = 5
2121

2222
/// The name pattern of files managed by `LogRotation`.
2323
private static let filePattern = #"amplify[.]([0-9])[.]log"#
2424

25-
let directory: URL
25+
package let directory: URL
2626

27-
let fileSizeLimitInBytes: UInt64
27+
package let fileSizeLimitInBytes: UInt64
2828

29-
private(set) var currentLogFile: LogFile {
29+
package private(set) var currentLogFile: LogFile {
3030
willSet {
3131
try? currentLogFile.synchronize()
3232
try? currentLogFile.close()
3333
}
3434
}
3535

36-
init(directory: URL, fileSizeLimitInBytes: Int) throws {
36+
package init(directory: URL, fileSizeLimitInBytes: Int) throws {
3737
if fileSizeLimitInBytes < LogRotation.minimumFileSizeLimitInBytes {
3838
throw LogRotationError.invalidFileSizeLimitInBytes(fileSizeLimitInBytes)
3939
}
@@ -56,19 +56,19 @@ final class LogRotation {
5656
/// has not been created, it is created and selected.
5757
/// 2. Any files containing less than half the limit are filtered, then the one with the oldest last modified date is selected.
5858
/// 3. If no files matching #1 are present, the file with the oldest last modified date is cleared and selected.
59-
func rotate() throws {
59+
package func rotate() throws {
6060
currentLogFile = try Self.selectNextLogFile(
6161
from: directory,
6262
fileCountLimit: Self.fileCountLimit,
6363
fileSizeLimitInBytes: fileSizeLimitInBytes
6464
)
6565
}
6666

67-
func getAllLogs() throws -> [URL] {
67+
package func getAllLogs() throws -> [URL] {
6868
return try Self.listLogFiles(in: directory)
6969
}
7070

71-
func reset() throws {
71+
package func reset() throws {
7272
let existingFiles = try Self.listLogFiles(in: directory)
7373
for file in existingFiles {
7474
try FileManager.default.removeItem(at: file)
@@ -118,7 +118,7 @@ final class LogRotation {
118118
)
119119
}
120120

121-
func ensureFileExists() throws {
121+
package func ensureFileExists() throws {
122122
if !FileManager.default.fileExists(atPath: currentLogFile.fileURL.relativePath) {
123123
try rotate()
124124
}

AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/Constants/AWSCloudWatchConstants.swift renamed to AmplifyPlugins/Internal/Sources/InternalCloudWatchLogging/Support/CloudWatchConstants.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
import Foundation
99

1010
/// Defines AWS CloudWatch SDK constants
11-
enum AWSCloudWatchConstants {
11+
package enum CloudWatchConstants {
1212

1313
/// the max byte size of log events that can be sent is 1 MB
14-
static let maxBatchByteSize: Int64 = 1_000_000
14+
package static let maxBatchByteSize: Int64 = 1_000_000
1515

1616
/// the max number of log events that can be sent is 10,000
17-
static let maxLogEvents = 10_000
17+
package static let maxLogEvents = 10_000
1818
}

AmplifyPlugins/Logging/Sources/AWSCloudWatchLoggingPlugin/Support/AWSCloudWatchLoggingMonitor.swift renamed to AmplifyPlugins/Internal/Sources/InternalCloudWatchLogging/Support/CloudWatchLoggingMonitor.swift

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,23 @@
77

88
import Foundation
99

10-
/// Provides a monitor to automatically flush the log at a specific TimeInterval
11-
class AWSCLoudWatchLoggingMonitor {
10+
/// Provides a monitor to automatically flush the log at a specific TimeInterval.
11+
package class CloudWatchLoggingMonitor {
1212
private let automaticFlushLogsInterval: TimeInterval
1313
private var automaticFlushLogsTimer: DispatchSourceTimer? {
1414
willSet {
1515
automaticFlushLogsTimer?.cancel()
1616
}
1717
}
1818

19-
private weak var eventDelegate: AWSCloudWatchLoggingMonitorDelegate?
19+
private weak var eventDelegate: CloudWatchLoggingMonitorDelegate?
2020

21-
init(flushIntervalInSeconds: TimeInterval, eventDelegate: AWSCloudWatchLoggingMonitorDelegate?) {
21+
package init(flushIntervalInSeconds: TimeInterval, eventDelegate: CloudWatchLoggingMonitorDelegate?) {
2222
self.automaticFlushLogsInterval = flushIntervalInSeconds
2323
self.eventDelegate = eventDelegate
2424
}
2525

26-
/// enable the automatic flushing of logs at a specific time interval by calling the monitor delegate
27-
func setAutomaticFlushIntervals() {
26+
package func setAutomaticFlushIntervals() {
2827
guard automaticFlushLogsInterval != .zero else {
2928
automaticFlushLogsTimer = nil
3029
return
@@ -35,7 +34,7 @@ class AWSCLoudWatchLoggingMonitor {
3534
eventHandler: { [weak self] in
3635
guard let self else { return }
3736
eventDelegate?.handleAutomaticFlushIntervalEvent()
38-
}
37+
}
3938
)
4039
automaticFlushLogsTimer?.resume()
4140
}
@@ -48,6 +47,6 @@ class AWSCLoudWatchLoggingMonitor {
4847
}
4948
}
5049

51-
public protocol AWSCloudWatchLoggingMonitorDelegate: AnyObject {
50+
package protocol CloudWatchLoggingMonitorDelegate: AnyObject {
5251
func handleAutomaticFlushIntervalEvent()
5352
}

0 commit comments

Comments
 (0)