Skip to content

Commit

Permalink
Changed Writer protocol (#74)
Browse files Browse the repository at this point in the history
Changed `Writer` protocol `log(timestamp:level:tag:message:runtimeContext:staticContext:)` method to `write(_ entry: Writer.LogEntry)` to make it easier to process messages by writers and formatters.
  • Loading branch information
tonystone authored Jan 13, 2019
1 parent 0759edd commit 400f6bb
Show file tree
Hide file tree
Showing 30 changed files with 617 additions and 348 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ All significant changes to this project will be documented in this file.
- Added `TextFormat`, an implementation of a OutputStreamFormatter that formats its output based on a supplied template (this is the default formatter for Console and File output).
- Added `JSONFormat`, an implementation of a OutputStreamFormatter that formats its output in standard JSON format.
- Added `OutputStreamWriter` protocol to define types that write byte streams to their output and accept `OutputStreamFormatter` types to format the output.
- Added `LogEntry` tuple type to `Writer` defining the formal types that a Writer writes.

#### Changed
- Required Swift 5 for compilation.
- Changed `Writer` protocol `log()` method to `write(_ entry: Writer.LogEntry)` to make it easier to process messages by writers and formatters.
- Changed `ConsoleWriter` to accept new `OutputStreamFormatter` instances allowing you to customize the output log format (default is `TextFormat`.)
- Changed `FileWriter` to accept new `OutputStreamFormatter` instances allowing you to customize the output log format (default is `TextFormat`.)
- Changed `FileWriter` archive file name date format to "yyyyMMdd-HHmm-ss-SSS".
Expand Down
22 changes: 11 additions & 11 deletions Sources/TraceLog/Formatters/JSONFormat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public struct JSONFormat: OutputStreamFormatter {

/// Text conversion function required by the `OutputStreamFormatter` protocol.
///
public func bytes(from timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) -> [UInt8]? {
public func bytes(from entry: Writer.LogEntry) -> [UInt8]? {
var text = String()

text.write("{\(conditional.newLine)")
Expand All @@ -126,16 +126,16 @@ public struct JSONFormat: OutputStreamFormatter {
text.write(",\(conditional.newLine)")
}
switch attributes[index] {
case .timestamp: self.emit(timestamp, forKey: "timestamp", to: &text)
case .level: self.emit(level, forKey: "level", to: &text)
case .tag: self.emit(tag, forKey: "tag", to: &text)
case .message: self.emit(message, forKey: "message", to: &text)
case .processName: self.emit(runtimeContext.processName, forKey: "processName", to: &text)
case .processIdentifier: self.emit(runtimeContext.processIdentifier, forKey: "processIdentifier", to: &text)
case .threadIdentifier: self.emit(runtimeContext.threadIdentifier, forKey: "threadIdentifier", to: &text)
case .file: self.emit(staticContext.file, forKey: "file", to: &text)
case .function: self.emit(staticContext.function, forKey: "function", to: &text)
case .line: self.emit(staticContext.line, forKey: "line", to: &text)
case .timestamp: self.emit(entry.timestamp, forKey: "timestamp", to: &text)
case .level: self.emit(entry.level, forKey: "level", to: &text)
case .tag: self.emit(entry.tag, forKey: "tag", to: &text)
case .message: self.emit(entry.message, forKey: "message", to: &text)
case .processName: self.emit(entry.runtimeContext.processName, forKey: "processName", to: &text)
case .processIdentifier: self.emit(entry.runtimeContext.processIdentifier, forKey: "processIdentifier", to: &text)
case .threadIdentifier: self.emit(entry.runtimeContext.threadIdentifier, forKey: "threadIdentifier", to: &text)
case .file: self.emit(entry.staticContext.file, forKey: "file", to: &text)
case .function: self.emit(entry.staticContext.function, forKey: "function", to: &text)
case .line: self.emit(entry.staticContext.line, forKey: "line", to: &text)
}
}
text.write("\(conditional.newLine)}")
Expand Down
4 changes: 2 additions & 2 deletions Sources/TraceLog/Formatters/OutputStreamFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import Foundation
///
public protocol OutputStreamFormatter {

/// Accepts traceLogs standard parameters and outputs an Array of bytes
/// Accepts traceLogs standard LogEntry and outputs an Array of bytes
/// containing the formatted output.
///
func bytes(from timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) -> [UInt8]?
func bytes(from entry: Writer.LogEntry) -> [UInt8]?
}
24 changes: 12 additions & 12 deletions Sources/TraceLog/Formatters/TextFormat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ public struct TextFormat: OutputStreamFormatter {

/// Text conversion function required by the `OutputStreamFormatter` protocol.
///
public func bytes(from timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) -> [UInt8]? {
public func bytes(from entry: Writer.LogEntry) -> [UInt8]? {
var text = String()

/// Write all the elements that have been pre-calculated
Expand All @@ -293,17 +293,17 @@ public struct TextFormat: OutputStreamFormatter {
/// Embed the variables within the constants.
case .variable(let substitution):
switch substitution {
case .date: self.write(Date(timeIntervalSince1970: timestamp), to: &text)
case .timestamp: self.write(timestamp, to: &text)
case .level: self.write(level, to: &text)
case .tag: self.write(tag, to: &text)
case .message: self.write(message, to: &text)
case .processName: self.write(runtimeContext.processName, to: &text)
case .processIdentifier: self.write(runtimeContext.processIdentifier, to: &text)
case .threadIdentifier: self.write(runtimeContext.threadIdentifier, to: &text)
case .file: self.write(staticContext.file, to: &text)
case .function: self.write(staticContext.function, to: &text)
case .line: self.write(staticContext.line, to: &text)
case .date: self.write(Date(timeIntervalSince1970: entry.timestamp), to: &text)
case .timestamp: self.write(entry.timestamp, to: &text)
case .level: self.write(entry.level, to: &text)
case .tag: self.write(entry.tag, to: &text)
case .message: self.write(entry.message, to: &text)
case .processName: self.write(entry.runtimeContext.processName, to: &text)
case .processIdentifier: self.write(entry.runtimeContext.processIdentifier, to: &text)
case .threadIdentifier: self.write(entry.runtimeContext.threadIdentifier, to: &text)
case .file: self.write(entry.staticContext.file, to: &text)
case .function: self.write(entry.staticContext.function, to: &text)
case .line: self.write(entry.staticContext.line, to: &text)
}
}
}
Expand Down
11 changes: 5 additions & 6 deletions Sources/TraceLog/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,13 @@ internal final class Logger {

if localConfig.logLevel(for: tag) >= level {

let runtimeContext = RuntimeContextImpl()
let staticContext = StaticContextImpl(file: file, function: function, line: line)

/// Evaluate the message now
let messageString = message()
/// Evaluate the message and create the LogEntry now that we
/// know we are going to output the message.
///
let entry: Writer.LogEntry = (timestamp: timestamp, level: level, tag: tag, message: message(), runtimeContext: RuntimeContextImpl(), staticContext: StaticContextImpl(file: file, function: function, line: line))

for writer in localConfig.writers {
writer.log(timestamp, level: level, tag: tag, message: messageString, runtimeContext: runtimeContext, staticContext: staticContext)
writer.write(entry)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/TraceLog/Proxies/AsyncWriterProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ internal class AsyncWriterProxy: WriterProxy {
}

@inline(__always)
internal func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) {
internal func write(_ entry: Writer.LogEntry) {
queue.async {
self.writer.log(timestamp, level: level, tag: tag, message: message, runtimeContext: runtimeContext, staticContext: staticContext)
self.writer.write(entry)
}
}
}
4 changes: 2 additions & 2 deletions Sources/TraceLog/Proxies/DirectWriterProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal class DirectWriterProxy: WriterProxy {
}

@inline(__always)
internal func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) {
self.writer.log(timestamp, level: level, tag: tag, message: message, runtimeContext: runtimeContext, staticContext: staticContext)
internal func write(_ entry: Writer.LogEntry) {
self.writer.write(entry)
}
}
4 changes: 2 additions & 2 deletions Sources/TraceLog/Proxies/SyncWriterProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ internal class SyncWriterProxy: WriterProxy {
}

@inline(__always)
internal func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) {
internal func write(_ entry: Writer.LogEntry) {
queue.sync {
self.writer.log(timestamp, level: level, tag: tag, message: message, runtimeContext: runtimeContext, staticContext: staticContext)
self.writer.write(entry)
}
}
}
4 changes: 2 additions & 2 deletions Sources/TraceLog/Proxies/WriterProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Foundation

internal protocol WriterProxy {

/// Call to log
/// Call to write to the writer.
///
func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext)
func write(_ entry: Writer.LogEntry)
}
14 changes: 11 additions & 3 deletions Sources/TraceLog/Writer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ import Swift
///
public protocol Writer {

///
/// Called when the logger needs to log an event to this logger.
/// Log Entry represents an element that can be written by a Writer.
///
/// - Parameters:
/// - timestamp: Timestamp of the log event (number of seconds from 1970).
Expand All @@ -51,5 +50,14 @@ public protocol Writer {
/// - SeeAlso: RuntimeContext
/// - SeeAlso: StaticContext
///
func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext)
typealias LogEntry = (timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext)

///
/// Called when the logger needs to log an event to this logger.
///
/// - Parameter entry: A LogEntry type to write to the output.
///
/// - SeeAlso: LogEntry
///
func write(_ entry: LogEntry)
}
4 changes: 2 additions & 2 deletions Sources/TraceLog/Writers/ConsoleWriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ public class ConsoleWriter: OutputStreamWriter {
///
/// Required log function for the logger
///
public func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) {
public func write(_ entry: Writer.LogEntry) {

guard let bytes = format.bytes(from: timestamp, level: level, tag: tag, message: message, runtimeContext: runtimeContext, staticContext: staticContext)
guard let bytes = format.bytes(from: entry)
else { return }

///
Expand Down
4 changes: 2 additions & 2 deletions Sources/TraceLog/Writers/FileWriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ public class FileWriter: OutputStreamWriter {

/// Required log function for the logger
///
public func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) {
public func write(_ entry: Writer.LogEntry) {

guard let bytes = format.bytes(from: timestamp, level: level, tag: tag, message: message, runtimeContext: runtimeContext, staticContext: staticContext)
guard let bytes = format.bytes(from: entry)
else { return }

/// Note: Since we could be called on any thread in TraceLog direct mode
Expand Down
4 changes: 2 additions & 2 deletions Sources/TraceLogTestHarness/BufferReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ public class BufferReader: Reader {
///
public init() {}

public func logEntry(for writer: BufferWriter, timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) -> LogEntry? {
public func logEntry(for writer: BufferWriter, timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) -> TestLogEntry? {

guard let logEntry = writer.buffer[message]
else { return nil }

return LogEntry(timestamp: logEntry.timestamp,
return TestLogEntry(timestamp: logEntry.timestamp,
level: logEntry.level,
message: logEntry.message,
tag: logEntry.tag,
Expand Down
6 changes: 3 additions & 3 deletions Sources/TraceLogTestHarness/BufferWriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class BufferWriter: Writer {
///
/// A buffer to hold the values written to this writer.
///
public var buffer: [String: (timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext)] = [:]
public var buffer: [String: Writer.LogEntry] = [:]

/// Initialize an instance of `self` to its initial empty state.
///
Expand All @@ -36,7 +36,7 @@ public class BufferWriter: Writer {
///
/// Required log function for the `Writer`.
///
public func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) {
self.buffer[message] = (timestamp, level, tag, message, runtimeContext, staticContext)
public func write(_ entry: Writer.LogEntry) {
self.buffer[entry.message] = entry
}
}
Loading

0 comments on commit 400f6bb

Please sign in to comment.