100 lines
3.2 KiB
Swift
100 lines
3.2 KiB
Swift
//
|
|
// FileLogRecorder.swift
|
|
// CleanroomLogger
|
|
//
|
|
// Created by Evan Maloney on 5/12/15.
|
|
// Copyright © 2015 Gilt Groupe. All rights reserved.
|
|
//
|
|
|
|
import Darwin.C.stdio
|
|
import Dispatch
|
|
|
|
/**
|
|
A `LogRecorder` implementation that appends log entries to a file.
|
|
|
|
- note: `FileLogRecorder` is a simple log appender that provides no mechanism
|
|
for file rotation or truncation. Unless you manually manage the log file when
|
|
a `FileLogRecorder` doesn't have it open, you will end up with an ever-growing
|
|
file. Use a `RotatingLogFileRecorder` instead if you'd rather not have to
|
|
concern yourself with such details.
|
|
*/
|
|
open class FileLogRecorder: LogRecorderBase
|
|
{
|
|
/** The path of the file to which log entries will be written. */
|
|
open let filePath: String
|
|
|
|
private let file: UnsafeMutablePointer<FILE>?
|
|
private let newlines: [Character] = ["\n", "\r"]
|
|
|
|
/**
|
|
Attempts to initialize a new `FileLogRecorder` instance to use the
|
|
given file path and log formatters. This will fail if `filePath` could
|
|
not be opened for writing.
|
|
|
|
- parameter filePath: The path of the file to be written. The containing
|
|
directory must exist and be writable by the process. If the file does not
|
|
yet exist, it will be created; if it does exist, new log messages will be
|
|
appended to the end of the file.
|
|
|
|
- parameter formatters: An array of `LogFormatter`s to use for formatting
|
|
log entries to be recorded by the receiver. Each formatter is consulted in
|
|
sequence, and the formatted string returned by the first formatter to
|
|
yield a non-`nil` value will be recorded. If every formatter returns `nil`,
|
|
the log entry is silently ignored and not recorded.
|
|
*/
|
|
public init?(filePath: String, formatters: [LogFormatter])
|
|
{
|
|
let f = fopen(filePath, "a")
|
|
guard f != nil else {
|
|
return nil
|
|
}
|
|
|
|
self.filePath = filePath
|
|
self.file = f
|
|
|
|
super.init(formatters: formatters)
|
|
}
|
|
|
|
deinit {
|
|
// we've implemented FileLogRecorder as a class so we
|
|
// can have a de-initializer to close the file
|
|
if file != nil {
|
|
fclose(file)
|
|
}
|
|
}
|
|
|
|
/**
|
|
Called by the `LogReceptacle` to record the specified log message.
|
|
|
|
- note: This function is only called if one of the `formatters` associated
|
|
with the receiver returned a non-`nil` string for the given `LogEntry`.
|
|
|
|
- parameter message: The message to record.
|
|
|
|
- parameter entry: The `LogEntry` for which `message` was created.
|
|
|
|
- parameter currentQueue: The GCD queue on which the function is being
|
|
executed.
|
|
|
|
- parameter synchronousMode: If `true`, the recording is being done in
|
|
synchronous mode, and the recorder should act accordingly.
|
|
*/
|
|
open override func record(message: String, for entry: LogEntry, currentQueue: DispatchQueue, synchronousMode: Bool)
|
|
{
|
|
var addNewline = true
|
|
if !message.isEmpty {
|
|
let lastChar = message[message.index(before: message.endIndex)]
|
|
addNewline = !newlines.contains(lastChar)
|
|
}
|
|
|
|
fputs(message, file)
|
|
|
|
if addNewline {
|
|
fputc(0x0A, file)
|
|
}
|
|
|
|
fflush(file)
|
|
}
|
|
}
|
|
|