Logging
Logger
The Logger
component enables logging of text messages used for error recording and debugging.
These messages can be logged to several destinations, for example, the iOS console, one or more files, or custom destinations.
Note: To upload logs to SAP Mobile Services, use the SAPcpmsLogUploader
component from the SAPFoundation
framework.
In addition to this API reference, see Logging for more information.
Basic Usage
Log levels:
- off - turns logging off
- error - indicates a serious failure
- warn - indicates a potential problem
- info - informational messages
- debug - provides tracing information
Log level recommendations:
Use the debug and info log levels to trace the current states of your application. Log these messages extensively, for example, when your code handles different conditions of an operation, or when the state of your app changes (for example, in case the connection is lost, or a user interface is switched).
Use the warn log level for errors that allow your app to function without having any impact on the user experience.
Use the error log level for errors that put your app’s stability at risk or indicate a malfunction, incorrect usage, or runtime error. Typical examples include catching an error or exception, illegal user input, or situations where your app is about to terminate unexpectedly.
Set the log level of the Logger:
Logger.root.logLevel = LogLevel.error
Note: LogLevel.debug
can be used for local development, use LogLevel.error
in a production environment.
Using the Logger Hierarchy
Multiple logger instances can exist simultaneously.
Each logger instance is part of a hierarchy and has a keyPath associated with it.
The root of the hierarchy is the root
logger: it is the parent of all Logger
instances.
Each Logger
instance you create is a direct or indirect descendant of the root
instance.
Loggers are created with a name, which preferably contains dots (“.”) that defines the hierarchy: each element of the name separated by a dot can be a parent of the instance.
You can use a logger instance in any class by calling:
public class MyClass {
private let logger = Logger.shared(named: <#LoggerIdentifier#>)
}
Log messages
Warning: Avoid logging sensitive data, since logged data is readable in the log.
Set the level of messages to be logged with one of these methods:
logger.error("Message", error: errorObj) // equivalent to logger.log("Message", error: errorObj, forLevel:.error)
logger.warn("Message", error: errorObj) // equivalent to logger.log("Message", error: errorObj, forLevel:.warn)
logger.info("Message", error: errorObj) // equivalent to logger.log("Message", error: errorObj, forLevel:.info)
logger.debug("Message", error: errorObj) // equivalent to logger.log("Message", error: errorObj, forLevel:.debug)
If the level of messages is lower than the logger’s, it is not logged.
Advanced Usage
LogHandlers
LogHandler
s are attached to Logger
instances, and define the destinations where log messages are written: OSLogConsoleHandler
and FileLogHandler
are typical handlers.
They are used to write log messages to the console or to a file respectively.
Handler
s that are attached to parent Logger
instances are inherited by child Logger instances (unless otherwise specified).
This allows fine-grained control and makes it possible to configure the log destination for an entire subtree of the Logger hierarchy.
OSLogConsoleHandler
is attached to the Logger.root
by default.
Add FileLogHandler
to write logs to a file, For example:
let fileHandler = try FileLogHandler(fileURL: <#your URL#>)
Logger.root.add(handler: fileHandler)
A tyical use is to write to the documents forder of the app:
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let filePath = documentsPath + "/MyAppLog.txt"
let handler = try! FileLogHandler(fileURL: URL(fileURLWithPath: filePath))
These logs can be then read back with xcode by downloading or browsing the container of the app . In Xcode select your device at Window / Devices and Simulators. Clicking the cogwheel icon enables you to browse or download the container.
LogFormatters
LogFormatter
s are responsible for formatting the messages logged with a Logger
instance before they are written to the destination LogHandler
s.
Such formatting can include adding a sequence number, logging date and time, or formatting the output in a special way, depending on your organization’s logging policy.
Typically each logging LogHandler
has an associated LogFormatter
.
There are two default formatters available:
OSLogFormatter
: used byOSLogConsoleHandler
FileLogFormatter
: used byFileLogHandler
-
A class for writing log messages to a variety of different sinks, so called handlers.
In your code, you can log messages with one of the following methods:
logger.error("Message", error: errorObj) logger.warn("Message", error: errorObj) logger.info("Message", error: errorObj) logger.debug("Message", error: errorObj)
All calls to
shared(named: String)
always returns an instance ofLogger
and the instance always has a parent of typeLogger
. The only exception is the root logger which has no direct parent.There can be multiple logger instances at the same time, which are all descendants of the root logger. Each logger instance is part of a hierarchy and has a keyPath associated with it. Each instance is used to create log messages using methods like
Logger.error("Message")
.Log messages are handled by the handlers associated with each logger. All attached LogHandlers are passed to the loggers ancestors in the log hierarchy. This behaviour can be controlled through the
useParentHandlers
parameter.Each handler must conform to the
LogHandler
protocol. Each handler can have its ownLogFormatter
, which is responsible for the output format of the log messages.Logger
s as well asLogHandler
s objects can include an optionalLogLevel
. Consequently, log messages with a lower level are not processed by the logger or handler object respectively. If a specific level is not set, the level is obtained from the ancestor logger instances in the hierarchy.IMPORTANT: Avoid logging sensitive data. All logged data will be readable in the log.
See moreDeclaration
Swift
public class Logger : Hashable, Equatable, CustomStringConvertible
-
LogRecord objects are used to pass logging requests between the logging framework and individual log Handlers.
See moreDeclaration
Swift
public struct LogRecord
-
The LogLevel enum defines a set of standard logging levels that can be used to control logging output. The logging Levels are ordered. Enabling logging at a given level also enables logging at all higher levels. Clients must use the predefined constants such as
See moreLogLevel.debug
. Error is the highest and debug is the lowest level.Declaration
Swift
public enum LogLevel : UInt, Comparable, CustomStringConvertible
-
A default implementation of a LogHandler logging to Xcode’s console. This implementation uses Apple’s print() method to log to the console.
See moreDeclaration
Swift
open class ConsoleLogHandler : LogHandler
-
A
LogHandler
implementation that provides a rolling file handler implementation.Log messages are written to a file, which is rolled if it exceeds a specified size. A certain number of backup files can be kept on disk.
If you want to write logs to file, you can add
FileLogHandler
as follows:
See morelet fileLogHandler = try FileLogHandler(fileUrl: fileUrl) Logger.root.add(handler: fileLogHandler)
Declaration
Swift
open class FileLogHandler : LogHandler
-
See moreLogHandler
protocol accepts a logging request and exports the desired messages to a target, for example, a file, the console, etc. It can be disabled by setting its logging level to.off
.Declaration
Swift
public protocol LogHandler : AnyObject
-
A ConsoleHandler using Apple’s OSLog to log to the console.
See moreDeclaration
Swift
open class OSLogConsoleHandler : ConsoleLogHandler
-
Default implementation of LogFormatter protocol optimized for console handlers. This default implemention is used by the ConsoleLogHandler.
See moreDeclaration
Swift
open class ConsoleLogFormatter : LogFormatter
-
Default implementation of LogFormatter protocol optimized for file or stream handlers. This implemention is used by the FileLogHandler.
See moreDeclaration
Swift
open class FileLogFormatter : ConsoleLogFormatter
-
A LogFormatter protocol provides support for formatting LogRecords. Typically each LogHandler will have a LogFormatter associated with it. The LogFormatter takes a LogRecord and converts it to a string. Some formatters (such as the FileLogFormatter) need to put head strings above a set of formatted records. The head property can be used to obtain these strings.
There are 2 default formatters alreadey available:
- DefaultLogFormatter -> normally used by a console handler
- FileLogFormatter -> normally used by a file handler
Declaration
Swift
public protocol LogFormatter : AnyObject
- DefaultLogFormatter -> normally used by a console handler
-
Formatter for the
See moreOSLogConsoleHandler
Declaration
Swift
open class OSLogConsoleFormatter : ConsoleLogFormatter
-
Describes the SAPcpms Log settings structure
See moreDeclaration
Swift
public struct SAPcpmsLogSettings
-
This function compares if a log level is from lower severity than the other.
Parameters
lhs
left hand logLevel for comparison
rhs
right hand logLevel for comparison
Return Value
true if the left hand log level do has a lower severity than the right hand log level, otherwise false
-
This function compares two log levels, if they do have the same severity.
Parameters
lhs
left hand logLevel for comparison
rhs
right hand logLevel for comparison
Return Value
true if the log levels do have the same severity, otherwise false