Integrating Fullstory logs with your iOS app logging framework can help you troubleshoot app issues, as well as uncover unintended behavior. In this guide, we're going to review a few popular logging frameworks and how you can integrate them with Fullstory.
CocoaLumberjack
CocoaLumberjack uses `DDAbstractLogger`. More info can be found here.
Guide
Installation instructions are on their github.
A way you use Fullstory with CocoaLumberjack is by creating a class for logging that inherits
`DDAbstractLogger`.
FSLumberjackLogger.swift (Link)
import Foundation
import FullStory
import CocoaLumberjack
class FSLumberjackLogger : DDAbstractLogger {
You may have multiple loggers in your project so to keep track you will want to use the `DDLoggerName` to return a logger name.
override var loggerName: DDLoggerName {
return DDLoggerName("com.fullstory.logger")
}
Finally you can create a logMessage method.
func logMessage(logMessage: DDLogMessage) {
guard let logFormatter = self.logFormatter else {
return
}
guard let messageBody = logFormatter.format(message: logMessage) else {
return
}
let logLevel: FSEventLogLevel
switch (logMessage.flag) {
case .error:
logLevel = FSLOG_ERROR
case .warning:
logLevel = FSLOG_WARNING
case .info:
logLevel = FSLOG_INFO
case .debug:
logLevel = FSLOG_DEBUG
default:
logLevel = FSLOG_INFO
}
FS.log(with: logLevel, message: messageBody)
}
Now you want to add this do your AppDelegate’s didFinishLaunchingWithOptions (Link):
DDLog.add(FSLumberjackLogger())
The result of this will be that you can use `DDLogs` convenient methods anywhere you import `CocoaLumberjack`. (Link) The methods are as follows:
- DDLogVerbose
- DDLogDebug
- DDLogInfo
- DDLogWarn
- DDLogError
DDLogVerbose("DDLogVerbose log message")
DDLogDebug("DDLogDebug log message")
DDLogInfo("DDLogInfo log message")
DDLogWarn("DDLogWarn log message")
DDLogError("DDLogError log message")
Calling these methods would produce the following result in a given session’s console:
Willow
Willow uses a LogWriter protocol that you can implement.
Guide
Installation instructions are on their github.
First you will want to make a file (It can be called FSWillowLogger...). Make sure that you import Fullstory & Willow:
import FullStory
import Willow
Then I would make a method that would switch off of the LogLevel called out by willow and return Fullstory’s event log level enum “FSEventLogLevel”.
func logLevelToFS(logLevel: LogLevel) -> FSEventLogLevel {
switch logLevel {
case .error:
return FSLOG_ERROR
case .warn:
return FSLOG_WARNING
case .debug:
return FSLOG_DEBUG
default:
return FSLOG_INFO
}
}
With Willow you can make an open class subclassing `LogWriter`.
open class FSWillowLogger: LogWriter { }
Now you want to add some convenient methods so you can use the logger to write Fullstory logs:
open func writeMessage(_ message: String, logLevel: LogLevel) {
FS.log(with: logLevelToFS(logLevel: logLevel), message: message)
}
open func writeMessage(_ message: LogMessage, logLevel: LogLevel) {
let message = "\(message.name): \(message.attributes)"
FS.log(with: logLevelToFS(logLevel: logLevel), message: message)
}
SwiftyBeaver
SwiftyBeaver has a BaseDestination class you can extend.
Setup
Instructions for install are in their github.
First you will want to make a file called FSSwiftyBeaverDestination.swift.
Next make sure to import SwiftyBeaver:
import FullStory
import SwiftyBeaver
Then I would make a method that would switch off of the SwiftyBeaver.Level called out by SwiftyBeaver and return Fullstory’s event log level enum:
func logLevelToFS(logLevel: SwiftyBeaver.Level) -> FSEventLogLevel {
switch logLevel {
case .debug:
return FSLOG_DEBUG
case .verbose:
return FSLOG_DEBUG
case .warning:
return FSLOG_WARNING
case .error:
return FSLOG_ERROR
default:
return FSLOG_INFO
}
}
Then you can make a class FSSwiftyBeaverDestination and make sure to inherit from BaseDestination:
public class FSSwiftyBeaverDestination: BaseDestination {
override public func send(_ level: SwiftyBeaver.Level, msg: String, thread: String,
file: String, function: String, line: Int, context: Any? = nil) -> String? {
let formattedString = super.send(level, msg: msg, thread: thread, file: file, function: function, line: line, context: context)
if let str = formattedString {
FS.log(with: logLevelToFS(logLevel: level), message: str)
}
return formattedString
}
}
You can then call the following where you wish to log into the didFinishLaunching method in the AppDelegate:
let fslog = FSSwiftyBeaverDestination()
log.addDestination(fslog)