Swiftpack.co - RougeWare/Swift-Simple-Logging as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by RougeWare.
RougeWare/Swift-Simple-Logging 0.5.2
For when you need something more advanced than print, but not a whole heavy system
⭐ī¸ 0
🕓 2 years ago
iOS macOS watchOS tvOS
.package(url: "https://github.com/RougeWare/Swift-Simple-Logging.git", from: "0.5.2")

SimpleLogging

A simple, cross-platform, lightweight logging framework powered by Swift's built-in features (like print and FileHandle).

This framework was built for both out-of-the-box simplicity when you just need logging, and powerful extensibility for when your enterprise app has specific logging needs.

Terminology

  • Message - An abstract concept of something which will be logged. It generally has some text that the API user wants to log, and metadata such as where the log line is within the source code, and when the line was called.
  • Severity - How important a log line is. This allows for traditional severity filtering before a message is sent to a channel.
  • Location - An output location where the log message is sent, like stdout, a specific file, a custom function, or the default place where Swift's print function goes.
  • Channel - Filters mesages based on severity and sends messages which pass its filter to a location. Any one log line can go to multiple channels. The default channels are specified in the LogManager.

Examples

Severities

Six severity levels are defined in this package, but you can define more if you please:

  • đŸ’Ŧ verbose - The lowest builtin priority; anything and everything might be logged at this level
  • 👩🏾‍đŸ’ģ debug - Usually not included in user-facing logs, but helpful messages for debugging issues in the field
  • ℹī¸ info - Usually the lowest level that appears in user logs, information for power-users who look at logs
  • ⚠ī¸ warning - Describing potential future problems. "Future" might be the next line, the next release, etc.
  • 🆘 error - Problems that just happened. A server log might only print lines of this severity or higher.
  • 🚨 fatal - The only fatal lines in a log file should be the last lines, in the event of a crash

This package also pairs these with some convenient global-scope functions for quick logging:

log(verbose: "Starting...")
log(debug: "TODO: Implement startup procedure")
log(info: "Startup done")
log(warning: "Future versions won't support the `--magically-work` flag")

if username == "BenLeggiero" {
    log(error: "You aren't allowed in here")
    return
}

if system.environment.isInvalid {
    log(fatal: "Environment is invalid")
    fatalError()
}

Example output, with a channel which allows all messages:

2020-05-19 22:30:06.362Z đŸ’Ŧ Starting...
2020-05-19 22:30:06.362Z 👩🏾‍đŸ’ģ TODO: Implement statup procedure
2020-05-19 22:30:06.362Z ℹī¸ Startup done
2020-05-19 22:30:06.362Z ⚠ī¸ Future versions won't support the `--magically-work` flag
2020-05-19 22:30:06.362Z 🚨 Environment is invalid

If you want, you can also specify these (and any you make) explicitly:

log(severity: .trace, "\(i) iterations so far")
log(severity: .critical, "The system is down!")

By default, severities are represented by emoji (like ℹī¸ for info and 🆘 for error) so a human can more-easily skim a log. Each can also be represented by a plaintext character or long name (for example, debug's names are 👩🏾‍đŸ’ģ, "d", and "debug"). You can set this this per-channel, in case your channel can't handle UTF-16, or in case you just don't like that.

Channels

By default, this just logs to the same place as Swift's print statement. Because enterprise apps have different needs, it can also log to stdout, stderr, any FileHandle, or a custom function. Arbitrarily many of these can operate simultaneously. You can also specify this per-log-call or for all log calls.

If none is specified, the default channel filter discards messages lower than info severity, since that's the lowest built-in severity which users might care about if they're looking at the logs, but not debugging the code itself.

LogManager.defaultChannels += [
    try LogChannel(name: "General Log File", location: .file(path: "/tmp/com.acme.AwesomeApp/general.log")),
    try LogChannel(name: "Debug Log File", location: .file(path: "/tmp/com.acme.AwesomeApp/debug.log"), lowestAllowedSeverity: .debug),
    try LogChannel(name: "Error Log File", location: .file(path: "/tmp/com.acme.AwesomeApp/errors.log"), lowestAllowedSeverity: .error, logSeverityNameStyle: .short),
]

In the above example, info and up log messages will go to Swift's print target, and to a general log file, whereas error and up log messages will go to a specific error log file (which won't contain emoji), and debug log messages (and up) go to a specific debug log file. All channels will receive all error and up log messages. For example:

log(verbose: "This is thrown away")
log(debug: "This only goes to the debug log channel")
log(info: "This goes to most of the log channels")
log(warning: "Same here")
log(error: "This is the first item in the error log; everything gets this")
log(fatal: "Everything gets this too")

The above lines will result in these logs:

Everywhere Swift's print usually goes:
2020-05-19 22:30:06.362Z ℹī¸ This goes to most of the log channels
2020-05-19 22:30:06.362Z ⚠ī¸ Same here
2020-05-19 22:30:06.362Z 🆘 This is the first item in the error log; everything gets this
2020-05-19 22:30:06.362Z 🚨 Everything gets this too
/tmp/com.acme.AwesomeApp/general.log
2020-05-19 22:30:06.362Z ℹī¸ This goes to most of the log channels
2020-05-19 22:30:06.362Z ⚠ī¸ Same here
2020-05-19 22:30:06.362Z 🆘 This is the first item in the error log; everything gets this
2020-05-19 22:30:06.362Z 🚨 Everything gets this too
/tmp/com.acme.AwesomeApp/debug.log
2020-05-19 22:30:06.362Z 👩🏾‍đŸ’ģ This only goes to the debug log channel
2020-05-19 22:30:06.362Z ℹī¸ This goes to most of the log channels
2020-05-19 22:30:06.362Z ⚠ī¸ Same here
2020-05-19 22:30:06.362Z 🆘 This is the first item in the error log; everything gets this
2020-05-19 22:30:06.362Z 🚨 Everything gets this too
/tmp/com.acme.AwesomeApp/errors.log
2020-05-19 22:30:06.362Z 🆘 This is the first item in the error log; everything gets this
2020-05-19 22:30:06.362Z 🚨 Everything gets this too

Logging scope entry/exit

When tracing through code in your logs, it's common to put log statements when a scope is entered and when it's exited. This framework makes such an action first-class and quite easy:

func notable() {
    logEntry(); defer { logExit() }
    
    MyApp.notableOperation()
}
func longAsyncOperation() {
    logEntry(); defer { logExit() }
    
    DispatchQueue.main.async {
        logEntry(); defer { logExit() }
        
        longOperation()
    }
}

GitHub

link
Stars: 0
Last commit: 7 weeks ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Release Notes

0.5.2 - Better error logging and custom log channel locations
3 years ago

Big changes this time!

  • New CombinedLoggable and CombinedLogMessage to combine two messages in one log line
  • Added new log channel location: .custom, which takes one function that you can use to implement your own location
  • Replaced the confusing minimum log severity with a semantic LogSeverityFilter
  • Removed a bunch of odd log severity names. If you want these, feel free to implement them yourself - it's just a couple lines 😁
  • Added LoggableError to aide in logging errors
  • It now depends on FunctionTools for the new custom log channel location

Patch Changes

  • 0.5.1 - Bumped LazyContainers to 4.0.0 #16
  • 0.5.2 - Changed LazyContainers URL to the current one #18

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics