emaloney / CleanroomLogger

CleanroomLogger provides an extensible Swift-based logging API that is simple, lightweight and performant
MIT License
1.32k stars 153 forks source link

custom logformatter #28

Closed navisingh closed 8 years ago

navisingh commented 9 years ago

How does one use multiple formatters: one for the xcode debug window (as shown below), another to go into a log file, a third to go in the ASL log file?

Here is a sample custom log formatter for anyone who is interested.

import Foundation
import CleanroomLogger

public struct LogFormatterTTY : LogFormatter
{
    private static let timestampFormatter: NSDateFormatter = {
        let fmt = NSDateFormatter()
        fmt.dateFormat = "hh:mm:ss.SSS"
        return fmt
    }()
    public static func stringRepresentationOfTimestamp(timestamp: NSDate)
        -> String
    {
        return timestampFormatter.stringFromDate(timestamp)
    }

    public static func stringRepresentationOfSeverity(severity: LogSeverity)
        -> String
    {
        var severityTag = severity.printableValueName.uppercaseString
        severityTag = severityTag.substringToIndex(severityTag.startIndex.advancedBy(1))

        return severityTag
    }
    public static func formatLogMessageWithSeverity(severity: String, caller: String, message: String, timestamp: String?, threadID: String?)
        -> String
    {
        var fmt = "\(severity) "
        if let timestamp = timestamp {
            fmt += "\(timestamp) "
        }
//        if let threadID = threadID {
//            fmt += "\(threadID) "
//        }
        fmt += "\(caller) \(message)"
        return fmt
    }
    public static func stringRepresentationForCallingFile(filePath: String, line: Int, function: String)
        -> String
    {
        let filename = NSURL(fileURLWithPath: filePath).URLByDeletingPathExtension?.lastPathComponent ?? "(unknown)"

        return "\(filename).\(function):\(line)"
    }

    public func formatLogEntry(entry: CleanroomLogger.LogEntry) -> String?
    {
        let severity = LogFormatterTTY.stringRepresentationOfSeverity(entry.severity)
        let caller = LogFormatterTTY.stringRepresentationForCallingFile(entry.callingFilePath, line: entry.callingFileLine, function: entry.callingFunction)
        var message = DefaultLogFormatter.stringRepresentationForPayload(entry)

        var timestamp: String?
            timestamp = LogFormatterTTY.stringRepresentationOfTimestamp(entry.timestamp)

        var threadID: String?
            threadID = DefaultLogFormatter.stringRepresentationOfThreadID(entry.callingThreadID)

        if message == entry.callingFunction {
            message = ""
        }

        return LogFormatterTTY.formatLogMessageWithSeverity(severity, caller: caller, message: message, timestamp: timestamp, threadID: threadID)
    }
}

public struct LogConfigurationTTY : LogConfiguration
{
    /** The minimum `LogSeverity` supported by the configuration. */
    public let minimumSeverity: LogSeverity

    /** The list of `LogFilter`s to be used for filtering log messages. */
    public let filters: [LogFilter]

    /** The list of `LogRecorder`s to be used for recording messages to the
     underlying logging facility. */
    public let recorders: [LogRecorder]

    /** A flag indicating when synchronous mode should be used for the
     configuration. */
    public let synchronousMode: Bool

    public init(minimumSeverity : LogSeverity = .Info){
        self.minimumSeverity = minimumSeverity
        self.filters = []
        self.recorders = [ASLLogRecorder(formatters: [LogFormatterTTY()])]
        self.synchronousMode = false
    }
}
emaloney commented 8 years ago

Hi Navi,

I've added the relevant sample code to a comment on your other open ticket, and will close this one.

E.