Skip to content

Commit ede6a6d

Browse files
committed
Minor cleanup
1 parent fe45ca1 commit ede6a6d

File tree

7 files changed

+91
-15
lines changed

7 files changed

+91
-15
lines changed

Package.resolved

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,23 @@ Then add `Logger` as a dependency for your targets:
120120
- Add support for oslog in the framework. We currently support it in the ad-hoc callback. Add this to unit test as well as instructions on Console.app usage and limitations.
121121
- Consider adding another log type called "important"
122122
- Add usage gif exploring system console, google-analytics, xcode consol
123-
- Add problem / solution to readme
123+
- Add problem / solution to readme
124+
- Add a note about apples OS.Logger. And its limitations.
125+
- Add protocol oriented design:
126+
127+
```swift
128+
protocol LoggerProtocol {
129+
func log(message: String, level: LogLevel, tag: LogTag)
130+
}
131+
132+
// Implementations
133+
class ConsoleLogger: LoggerProtocol {
134+
func log(message: String, level: LogLevel, tag: LogTag) {
135+
Swift.print(message)
136+
}
137+
}
138+
139+
class FileLogger: LoggerProtocol {
140+
// File logging implementation...
141+
}
142+
```

Sources/Logger/Logger+Command.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ extension Logger {
6262
* - tag: Type of logging, e.g., payment, network, database, etc.
6363
*/
6464
fileprivate static func log(_ msg: String, level: LogLevel, tag: LogTag) {
65+
// fixme after using set, do guard mode.level.contains(level) else { return }
6566
guard mode.level.contains(where: { $0 == level }) else { return } // Filter level
67+
// fixme after using set, do guard mode.level.contains(level) else { return }
6668
guard mode.tag.contains(where: { $0 == tag }) else { return } // Filter tag
6769
let text: String = text(msg, level: level, tag: tag) // Get formatted print output
6870
type.log(msg: text, level: level, tag: tag) // Log to console or file

Sources/Logger/helper/Trace.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ extension String {
4949
}
5050
/**
5151
* removePrefix function removes the specified prefix from the string.
52+
* fixme: rename trimmingPrefix
5253
*/
5354
fileprivate func removePrefix(prefix: String) -> String {
5455
guard self.hasPrefix(prefix) else { return self } // Check if the trace message has the specified prefix
5556
return "\(self.dropFirst(prefix.count))" // Remove the prefix from the trace message and return the result
5657
}
5758
/**
5859
* removeSuffix function removes the specified suffix from the string.
60+
* fixme: rename trimmingSuffix
5961
*/
6062
fileprivate func removeSuffix(suffix: String) -> String {
6163
guard self.hasSuffix(suffix) else { return self } // Check if the trace message has the specified suffix

Sources/Logger/util/LogConfig.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ extension LogConfig {
3131
* ss: The second of the minute with two digits (00-59).
3232
*/
3333
public static let defaultDateFormat: String = "yyyy-MM-dd' 'HH:mm:ss"
34+
// fixme add doc
35+
// Creating a new DateFormatter every time a date is formatted can be expensive. Caching the DateFormatter instance using a lazy property improves performance.
36+
private static var cachedDateFormatter: DateFormatter?
3437
/**
3538
* DateFormatter is used to format the date in the log.
3639
* - Descriptino: It uses the dateFormat specified in the LogConfig, sets the timezone to UTC, and sets the locale to "en_US_POSIX".
@@ -40,11 +43,16 @@ extension LogConfig {
4043
* - Note: In the context of the LogConfig struct, the en_US_POSIX locale is used to ensure that the date and time formatting is consistent regardless of the user's locale settings
4144
*/
4245
var dateFormatter: DateFormatter {
43-
let format: DateFormatter = .init() // Create a new DateFormatter instance
44-
format.dateFormat = dateFormat // Set the date format to the specified format
45-
format.timeZone = TimeZone(identifier: "UTC") // Set the time zone to UTC
46-
format.locale = Locale(identifier: "en_US_POSIX") // Set the locale to US English
47-
return format // Return the DateFormatter instance
46+
if let formatter = Self.cachedDateFormatter {
47+
return formatter
48+
} else {
49+
let format = DateFormatter()
50+
format.dateFormat = dateFormat
51+
format.timeZone = TimeZone(identifier: "UTC")
52+
format.locale = Locale(identifier: "en_US_POSIX")
53+
Self.cachedDateFormatter = format
54+
return format
55+
}
4856
}
4957
}
5058
// Extension of LogConfig for predefined configurations.

Sources/Logger/util/LogMode.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ extension LogMode {
5050
* It is used to specify the types of logs to be displayed.
5151
* ## Examples:
5252
* LogTag.allCases.filter { $0 != .net && $0 != .db && $0 != .security }
53+
* fixme: use set
5354
*/
5455
public typealias TagFilter = [LogTag] // [.db, .net, .file, .ui, .security, .other]
5556
/**
5657
* `LevelFilter` is a type alias for an array of `LogLevel`.
5758
* It is used to specify the severity of logs to be displayed.
5859
* ## Examples:
5960
* LogLevel.allCases.filter({ $0 != .info })
61+
* fixme: use set
6062
*/
6163
public typealias LevelFilter = [LogLevel] // [.error, .warning, .info, .critical]

Sources/Logger/util/LogType.swift

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,44 @@ extension LogType {
8585
* - filePath: Destination file path, usually temp folder path etc
8686
*/
8787
public static func writeToFile(string: String, filePath: String) {
88-
var content: String = ""
89-
if !FileAsserter.exists(path: filePath) { // Assert if filePath doesn't exist
90-
FileModifier.write(filePath, content: "New file created" + "\n") // Create new file if non exists
88+
let queue = DispatchQueue(label: "com.logger.fileWriteQueue", attributes: .concurrent)
89+
queue.async(flags: .barrier) {
90+
do {
91+
if !FileManager.default.fileExists(atPath: filePath) {
92+
try "New file created\n".write(toFile: filePath, atomically: true, encoding: .utf8)
93+
}
94+
if isNewLogSession == false {
95+
try "New session started\n".appendLineToURL(fileURL: URL(fileURLWithPath: filePath))
96+
isNewLogSession = true
97+
}
98+
try (string + "\n").appendLineToURL(fileURL: URL(fileURLWithPath: filePath))
99+
} catch {
100+
print("Failed to write to log file: \(error.localizedDescription)")
101+
}
91102
}
92-
if isNewLogSession == false { // Indicates new app session
93-
content += "New session started" + "\n"
94-
isNewLogSession = true // only trigger once per app session
95-
}
96-
content += string + "\n" // Add string
97-
FileModifier.append(filePath, text: content) // Append content to end of file
98103
}
99104
}
105+
106+
// Helper extension
107+
extension String {
108+
func appendLineToURL(fileURL: URL) throws {
109+
try self.appendToURL(fileURL: fileURL)
110+
}
111+
112+
func appendToURL(fileURL: URL) throws {
113+
let data = self.data(using: .utf8)!
114+
try data.append(fileURL: fileURL)
115+
}
116+
}
117+
118+
extension Data {
119+
func append(fileURL: URL) throws {
120+
if let fileHandle = try? FileHandle(forWritingTo: fileURL) {
121+
defer { fileHandle.closeFile() }
122+
fileHandle.seekToEndOfFile()
123+
fileHandle.write(self)
124+
} else {
125+
try write(to: fileURL, options: .atomic)
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)