When you send a log Event
to a logger and therefore to a specified transport, the event should be transformed into a textual or binary representation.
The EventMessageFormatter
protocol is consulted when attempting to convert an event into a string; its implementation is straightforward:
public protocol EventMessageFormatter {
func format(event: Event) -> SerializableData?
}
format(event:)
function is responsible for converting an event to SerializableData
, which can be Data
or String
, depending on the type of output you want.
The vast majority of transports offer, in their configuration, a property called formatters
: you can specify one or more formatters that will be executed in order and contribute to transforming the output at each step.
Typically, you are done specifying a single formatter that defines the event's output for a particular transport instance.
Glider offers several event formatters, some suitable for console display and others suggested for persistent storage.
The FieldsFormatter
provides a simple interface for constructing a customized EventMessageFormatter
by specifying different fields and their visual representation.
Let’s say you wanted to construct a formatters that outputs the following fields separated by tabs:
- The event's timestamp property as an ISO8601 time value
- The severity of the event as a numeric value
- The message attached to the event (tail truncated to 200 chars)
You could do this by constructing a FieldsFormatter
as follows:
let myFormatter = FieldsFormatter(fields: [
.timestamp(style: .iso8601),
.level(style: .numeric),
.message( {
$0.truncate = .tail(length: 200)
$0.stringFormat = "Message [%@]"
}
])
let consoleTransport = ConsoleTransport {
$0.formatters = [myFormatter]
}
let logger = Log {
$0.transports = ConsoleTransport
}
You can fully customize the format; there are 20+ different event properties you can use for your formatted messages; for each property, you can also customize how it's visually presented by setting the following properties:
truncate
: truncate the output with three modes (lead, middle, and trail) at a specified lengthpadding
: pad the output by aligning it on the left, center, and righttransforms
: specify one or more functions to transform the Stringcolors
: with supported formatters (by default,TerminalFormatter
with ANSII compatible terminals andXCodeFormatter
with a hack) you can specify the color attributes of the textformat
: how complex properties of an event should be encoded (extra
,tags
,object
oruser
)stringFormat
: specify how to decorate the output via string formatting
The JSONFormatter
formatter is used to write event data by using the JSON file format.
Note Not all properties are expressible in JSON. For example event's
object
cannot be serialized. If you want to add it to formatter'sfield
to store, you must setencodeDataAsBase64 = true
. Data will be encoded using Base64 which means a sensible increment of the final payload size. Consider using other formats when you deal with binary data (MessagePack
](https://msgpack.org/index.html) withMsgPackFormatter
, for example).
This formatter is similar to the FieldFormatter
; you should specify fields to include in the payload and eventually the JSON encoding options.
let fileTransport = try FileTransport(fileURL: fileURL, {
// Using the `standard` format, it will serialize level, message, extra, and tags-
$0.formatters = [JSONFormatter.standard()]
})
In this example, we want to customize the fields used in the payload:
let customJSONFormatter = JSONFormatter(
jsonOptions: [],
encodeDataAsBase64: true, // used to encode object
fields: [
.timestamp(style: .iso8601),
.level(style: .numeric),
.message(),
.object(),
.extra(keys: nil),
.tags(keys: nil)
])
The MsgPackDataFormatter
allows storing Event
data using the MessagePack
file format, which produces a compact (and faster to read) representation of the data compared to other formats like JSON.
Note Since MsgPack is a binary format, we suggest using it when you need to store data you will read with another program.
The MsgPackDataFormatter.standard()
configuration encode automatically timestamp
, level
, message
, objectMetadata
, object
, extra
and tags
.
You can still customize it by passing your list of fields
:
let msgPackCustomFormatter = MsgPackFormatter(fields: [
.callSite(),
.message(),
.category(),
.subsystem(),
.fingerprint()
])
TableFormatter
is formatted log messages for console display by presenting data with an ASCII table.
This is useful when printing complex data using tables rendered via console.
The following formatter is used to print a tabular version of a network call.
let tableFormatter = TableFormatter(messageFields: [
.timestamp(style: .xcode, {
$0.padding = .left(columns: 23)
),
.message(),
], tableFields: [
.extra(keys: ["service", "url", "time", "headers", "body", "curl"])
])
tableFormatter.maxColumnWidths = (30, 100)
$0.console(tableFormatter)
})
This is an example of the result:
Note Of course, you should use a monospaced font to have the best rendering.
This formatter is used to print logs into terminals or stdout
/stderr
.
It also supports colors and styles; the output supports ANSI escape codes for colors and styles.
The formatted field's default includes an ISO8601 timestamp, the level, and the message.
TheXCodeFormatter
is used to print messages directly on XCode debug console.
It mimics the typical debug message structure and adds colorization to the output.
While the XCode console does not support colorization, you can still use a hack to show them.
- Add the font file named ColoredConsole-Bold.ttf via the Mac OS application Font Book.
- Back to Xcode. Go to "Preference" ⇢ "Texts & Colors" ⇢ "Executable console Output", click the font icon below, then set the font to "Colored Console Bold"
- Use the
XCodeFormatter
and set thecolorize
property to add colors to some of the fields
For example:
let xcodeFormatter = XCodeFormatter {
// By default, both the `message` and `level` are colorized automatically with a red.
$0.colorize = .onlyImportant
}
Note ColoredConsole-Bold is a font based on FiraMono-Bold, which adds ligatures to enable colored messages.
If you need more customization, you can create your own FieldFormatter
and add colors to the fields.
The following formatter colorizes the message
of an event with a yellow text and black background (it works with ANSI Capable Terminals).
let myFormatter = FieldFormatter(fields: [
.timestamp(style: .iso8601),
.literal(" "),
.level(style: .simple),
.message({ msgConfig in
msgConfig.colors = [ANSITerminalStyles.fg(.yellow), ANSITerminalStyles.bg(.black)]
})
])
``` variants of the ASCII character set. Take a look at [ColoredConsole](https://github.com/jjrscott/ColoredConsole) repo for more information.
## SysLogFormatter
This formatter produces a log in the standard [RFC5424](https://datatracker.ietf.org/doc/html/rfc5424).
The message comprises three parts: the header, the structured data, and the named message.
- header (priority, version, timestamp, host, application, PID, message-id)
- structured data - section with square brackets
- message
For example:
`<priority>VERSION ISOTIMESTAMP HOSTNAME APPLICATION PID MESSAGEID [STRUCTURED-DATA] MESSAGE`
> **Note**
> Sys-log formatter does not log `Scope`.
```swift
let sysLogFormatter = SysLogFormatter(hostname: "myawesomeapp", extraFields: [.callingThread(style: .integer), .eventUUID()])