Skip to content

Instantly share code, notes, and snippets.

@akisute
Forked from stigi/CocoaLumberjack.swift
Last active August 29, 2015 14:12
Show Gist options
  • Save akisute/dcf240430bc8ac5f4f01 to your computer and use it in GitHub Desktop.
Save akisute/dcf240430bc8ac5f4f01 to your computer and use it in GitHub Desktop.

CocoaLumberjack.swift

Important note

CocoaLumberjack now officially supports Swift (https://github.com/CocoaLumberjack/CocoaLumberjack/blob/2.0.0-rc/Classes/CocoaLumberjack.swift. I recommend you to install the official CocoaLumberjack.swift instead of this hack.

Prerequisites

This assumes you have the CocoaLumberjack pod in your Podfile (tested with 2.0.0-rc)
Also import `CocoaLumberjack/CocoaLumberjack in your bridging header

Configuring the loggin

  • As usual add all the loggers you might want/need: DDLog.addLogger(DDTTYLogger.sharedInstance())
  • Configure the log level like so: DDLog.logLevel = .Info
  • Log away :)
  • You might also want to enable/disable async logging: DDLog.logAsync = false

License

This Gist is under MIT

// Created by Ullrich Schäfer on 16/08/14.
// Updated by Masashi Ono (akisute) on 26/12/14.
//
// Tested on CocoaLumberjack 2.0.0 rc
//
// CocoaLumberjack now officially supports Swift (https://github.com/CocoaLumberjack/CocoaLumberjack/blob/2.0.0-rc/Classes/CocoaLumberjack.swift),
// but both the current CocoaPods (0.35) with 2.2.0 rc doesn't support Swift yet.
// We got to workaround this by installing CocoaLumberjack.swift manually.
// I recommend you to use the official CocoaLumberjack.swift instead of this hack.
// Bitmasks are a bit tricky in swift
// See http://natecook.com/blog/2014/07/swift-options-bitmask-generator/
// Refer DDLog.h
/*
typedef NS_OPTIONS(NSUInteger, DDLogFlag) {
DDLogFlagError = (1 << 0), // 0...00001
DDLogFlagWarning = (1 << 1), // 0...00010
DDLogFlagInfo = (1 << 2), // 0...00100
DDLogFlagDebug = (1 << 3), // 0...01000
DDLogFlagVerbose = (1 << 4) // 0...10000
};
*/
struct LogFlag : RawOptionSetType {
private var value: Int32 = 0
init(nilLiteral: ()) {}
init(rawValue: Int32) { self.value = rawValue }
var boolValue: Bool { return self.value != 0 }
var rawValue: Int32 { return self.value }
var DDLogFlagValue: DDLogFlag {
switch self.value {
case LogFlag.allZeros.rawValue:
return DDLogFlag.allZeros
case LogFlag.Error.rawValue:
return DDLogFlag.Error
case LogFlag.Warn.rawValue:
return DDLogFlag.Warning
case LogFlag.Info.rawValue:
return DDLogFlag.Info
case LogFlag.Debug.rawValue:
return DDLogFlag.Debug
case LogFlag.Verbose.rawValue:
return DDLogFlag.Verbose
default:
return DDLogFlag.allZeros
}
}
static var allZeros: LogFlag { return self(rawValue: 0) }
static var Error: LogFlag { return self(rawValue: 1 << 0) }
static var Warn: LogFlag { return self(rawValue: 1 << 1) }
static var Info: LogFlag { return self(rawValue: 1 << 2) }
static var Debug: LogFlag { return self(rawValue: 1 << 3) }
static var Verbose: LogFlag { return self(rawValue: 1 << 4) }
}
func == (lhs: LogFlag, rhs: LogFlag) -> Bool { return lhs.value == rhs.value }
func & (lhs: LogFlag, rhs: LogFlag) -> LogFlag { return LogFlag(rawValue: lhs.value & rhs.value) }
func | (lhs: LogFlag, rhs: LogFlag) -> LogFlag { return LogFlag(rawValue: lhs.value | rhs.value) }
func ^ (lhs: LogFlag, rhs: LogFlag) -> LogFlag { return LogFlag(rawValue: lhs.value ^ rhs.value) }
prefix func ~(x: LogFlag) -> LogFlag { return LogFlag(rawValue: ~x.value) }
// Refer DDLog.h
/*
typedef NS_ENUM(NSUInteger, DDLogLevel) {
DDLogLevelOff = 0,
DDLogLevelError = (DDLogFlagError), // 0...00001
DDLogLevelWarning = (DDLogLevelError | DDLogFlagWarning), // 0...00011
DDLogLevelInfo = (DDLogLevelWarning | DDLogFlagInfo), // 0...00111
DDLogLevelDebug = (DDLogLevelInfo | DDLogFlagDebug), // 0...01111
DDLogLevelVerbose = (DDLogLevelDebug | DDLogFlagVerbose), // 0...11111
DDLogLevelAll = NSUIntegerMax // 1111....11111 (DDLogLevelVerbose plus any other flags)
};
*/
struct LogLevel : RawOptionSetType {
private var value: Int32 = 0
init(nilLiteral: ()) {}
init(rawValue: Int32) { self.value = rawValue }
var boolValue: Bool { return self.value != 0 }
var rawValue: Int32 { return self.value }
var DDLogLevelValue: DDLogLevel { return DDLogLevel(rawValue: UInt(self.rawValue))! }
static var allZeros: LogLevel { return self(rawValue: 0) }
static var Off: LogLevel { return self(rawValue: 0b0) }
static var Error: LogLevel { return self(rawValue: LogFlag.Error.rawValue) }
static var Warn: LogLevel { return self(rawValue: LogLevel.Error.rawValue | LogFlag.Warn.rawValue) }
static var Info: LogLevel { return self(rawValue: LogLevel.Warn.rawValue | LogFlag.Info.rawValue) }
static var Debug: LogLevel { return self(rawValue: LogLevel.Info.rawValue | LogFlag.Debug.rawValue) }
static var Verbose: LogLevel { return self(rawValue: LogLevel.Debug.rawValue | LogFlag.Verbose.rawValue) }
static var All: LogLevel { return self(rawValue: Int32.max) }
}
func == (lhs: LogLevel, rhs: LogLevel) -> Bool { return lhs.value == rhs.value }
func & (lhs: LogLevel, rhs: LogLevel) -> LogLevel { return LogLevel(rawValue: lhs.value & rhs.value) }
func | (lhs: LogLevel, rhs: LogLevel) -> LogLevel { return LogLevel(rawValue: lhs.value | rhs.value) }
func ^ (lhs: LogLevel, rhs: LogLevel) -> LogLevel { return LogLevel(rawValue: lhs.value ^ rhs.value) }
prefix func ~(x: LogLevel) -> LogLevel { return LogLevel(rawValue: ~x.value) }
// what's a better way than poluting the global scope?
var __logLevel: LogLevel?
var __logAsync: Bool?
// Use those class properties insted of `#define LOG_LEVEL_DEF` and `LOG_ASYNC_ENABLED`
extension DDLog {
class var logLevel: LogLevel {
get {
return __logLevel ?? LogLevel.Error
}
set(logLevel) {
__logLevel = logLevel
}
}
class var logAsync: Bool {
get {
return (self.logLevel != LogLevel.Error) && (__logAsync ?? true)
}
set(logAsync) {
__logAsync = logAsync
}
}
class func logError (message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int32 = __LINE__) { log(.Error, message: message, function: function, file: file, line: line) }
class func logWarn (message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int32 = __LINE__) { log(.Warn, message: message, function: function, file: file, line: line) }
class func logInfo (message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int32 = __LINE__) { log(.Info, message: message, function: function, file: file, line: line) }
class func logDebug (message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int32 = __LINE__) { log(.Debug, message: message, function: function, file: file, line: line) }
private class func log (
flag: LogFlag,
message: String,
// No need to pass those in. the defaults will do just fine
function: String = __FUNCTION__,
file: String = __FILE__,
line: Int32 = __LINE__
)
{
let level:LogLevel = DDLog.logLevel
let async:Bool = (level != LogLevel.Error) && DDLog.logAsync
if flag.rawValue & level.rawValue != 0 {
let msg: DDLogMessage = DDLogMessage(
message: message,
level: level.DDLogLevelValue,
flag: flag.DDLogFlagValue,
context: UInt(0),
file: file,
function: function,
line: UInt(line),
tag: nil,
options: DDLogMessageOptions.allZeros,
timestamp: NSDate())
DDLog.log(async, message: msg)
}
}
}
// Shorthands, what you'd expect
/* //Not possible due to http://openradar.appspot.com/radar?id=5773154781757440
let logError = DDLog.logError
let logWarn = DDLog.logWarn
let logInfo = DDLog.logInfo
let logDebug = DDLog.logDebug
*/
func logError (message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int32 = __LINE__) { DDLog.logError(message, function: function, file: file, line: line) }
func logWarn (message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int32 = __LINE__) { DDLog.logWarn(message, function: function, file: file, line: line) }
func logInfo (message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int32 = __LINE__) { DDLog.logInfo(message, function: function, file: file, line: line) }
func logDebug (message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int32 = __LINE__) { DDLog.logDebug(message, function: function, file: file, line: line) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment