A Swift logging backend that writes logs to files using the C fopen
/fwrite
APIs.
It is an implementation of a LogHandler
as defined by the Swift Server Working Group logging API.
Add the following dependency in your Package.swift
.package(url: "https://github.com/Ponyboy47/swift-log-file.git", from: "0.2.0")
During application startup:
import Logging
import FileLogging
// Create a factory which will point any newly created logs to the same file
let fileFactory = FileLogHandlerFactory(path: "/path/to/file.log")
// Initialize the file log handler
LoggingSystem.bootstrap(fileFactory.makeFileLogHandler)
Elsewhere:
// Create a logger
let logger = Logger(label: "MyApp")
// Write a log message
logger.info("Hello world!")
During application startup:
import Logging
import FileLogging
// Create a factory with just a directory where logs will be created
let fileFactory = FileLogHandlerFactory(path: "/path/to/logs/directory/")
// Initialize the file log handler
LoggingSystem.bootstrap(fileFactory.makeFileLogHandler)
Elsewhere:
// Creates a new log file at /path/to/logs/directory/MyApp.log
let logger = Logger(label: "MyApp")
logger.info("Hello world!")
This implementation includes both a date-based and size-based rotating mechanism for logs. The bootstrapping is a bit verbose, but it makes creating the loggers just as easy as what you see anywhere else.
The path
parameter for the RotatingFileLogHandlerFactory
behaves exactly the same as the path
parameter in the FileLogHandlerFactory
. Specifying a file or uncreated path will be used as a FilePath
while a directory will be used as a parent location for files based on the label during Logger
creation.
The max
parameter defaults to nil
. Passing a max of nil
means old logs will never be deleted. It is good practice to include a maximum if you're expecting lots of logs or you can set up some other tool to clean up/offload extra files.
import Logging
import FileLogging
// Create a factory that will rotate logs at midnight every day and deletes any
// logs from more than 7 days ago
let dateRotatingFactory = RotatingFileLogHandlerFactory<DateRotatingFileLogHandler>(path: "/path/to/file.log", options: .daily, max: 7)
LoggingSystem.bootstrap(dateRotatingFactory.makeRotatingFileLogHandler)
Elsewhere
let logger = Logger(label: "MyApp")
logger.info("Hello world!")
import Logging
import FileLogging
// Create a factory that will rotate logs as soon as the size would exceed 100
// megabytes and only permits up to 5 rotations before deleting old log files
let sizeRotatingFactory = RotatingFileLogHandlerFactory<SizeRotatingFileLogHandler>(path: "/path/to/file.log", options: 100.megabytes, max: 5)
LoggingSystem.bootstrap(sizeRotatingFactory.makeRotatingFileLogHandler)
Elsewhere
let logger = Logger(label: "MyApp")
logger.info("Hello world!")
- Track when we were passed FileStreams directly so we know not to close them explicitly
- Don't use so many fatalErrors
- Performance tests
-
Date
vsTimeInterval
(Date
vsDouble
comparisons/calculations)
-
- Find some shorter names for things (RotatingFileLogHandlerFactory? And it requires a generic type?)
- Allow customizing the datetime format printed in the logs
MIT (c) 2019 Jacob Williams