l1men9yu/senna
**a logging engine backend of Apple's** [swift-log](https://github.com/apple/swift-log)
Status
[Swift5.0+] [[release]](https://github.com/L1MeN9Yu/Senna/releases) [[Build]](https://github.com/L1MeN9Yu/Senna/actions/workflows/Build.yml) [[codecov]](https://codecov.io/gh/L1MeN9Yu/Senna) [[license]](https://github.com/L1MeN9Yu/Senna/blob/main/LICENSE)
[[platforms]](https://github.com/L1MeN9Yu/Senna/blob/main/Package.swift)
Features
- Pure Swift
- Backend of
apple/swift-log - Both Darwin(iOS macOS watchOS tvOS) and Linux compatibility
- Builtin output target :
[stdout/stderr,file,oslog,syslog] - ANSI escape code
- Complete customizable for text out
- Support string interpolation the same as Apple's Unified Logging System
- 100% Code Coverage
Examples
Use Builtin Sinks
Simple stdout
//create sink
let sink = StandardSink.out()
//create formation
let formation = Formation.standard
//create log
var logger = Logger(label: "LogName") {
Handler(name: $0, sink: sink, formation: formation, logLevel: .trace)
}
// do some logs
logger.trace("This is a trace message")
logger.debug("This is a debug message")
logger.info("This is a info message")
logger.notice("This is a notice message")
logger.warning("This is a warning message")
logger.error("This is a error message")
logger.critical("This is a critical message")
```
Terminal out :

#### Change LogLevel
logger.logLevel = .info logger.debug("will not log") logger.info("will log")
#### Add MetaData
logger[metadataKey: "UserID"] = .stringConvertible(9527) logger.info("message with logger meta data") logger.info("message with both logger and message meta data", metadata: ["UserName": .string("L1MeN9Yu")])
Terminal out :

### Builtin Sinks
#### FileSink
let fileSink = FileSink("path/of/log")
Log message will write to file.
See [Tests](Tests/FileSinkTests.swift) for more.
#### OSLogSink (Apple platform only)
let osLogSink = OSLogSink(subsystem: "subsystem", category: "category")
Log message will write to OS log (Apple's syslog). Use `Connsole.app` in your macOS to watch oslog messages.
See [Tests](Tests/OSLogSinkTests.swift) for more.
#### SystemLogSink (Linux)
let systemLogSink = SystemLogSink()
Log message will write to syslog.
See [Tests](Tests/SystemLogSinkTests.swift) for more.
### Formation
`Formation` generate the log message.
There are some builtin `Formation`:
1. `Formation.standard`. This is default for `stdout/stderr`.
2. `Formation.standardXcode`. This is default for `stdout/stderr` display in Xcode due Xcode's console is not support ANSI escape code.

3. `Formation.file`. This is default for `File`.
4. `Formation.os`. This is default for `OSLog`.
5. `Formation.system`. This is default for `syslog`.
### Advanced Customize Formation
Create `Formation` is simple : `Formation(components: <#T##[Component]##[Senna.Component]#>, printer: <#T##Printable?##Senna.Printable?#>, separator: <#T##String?##Swift.String?#>)`
The Formation contains `components: [Component]`, `printer: Printable?` and `separator: String?`.
#### Component
Component is your log message's element. See [Component](Sources/Types/Component.swift) file.
#### Printable
The `Printable` enhanced your log messages, It can add color or style to the component.
The builtin `Printer` has two default instance.
`Printer.standard` for `stdout/stderr`.
`Printer.xcode` for `stdout/stderr` in Xcode.
You can create new `Printer` instance or Use `YourPrinter` which implements `Printable` protocol.
See [Printer](Sources/Implements/Printer.swift) and [Printable](Sources/Protocols/Printable.swift) for more.
#### Separator
The `Separator` string is used for split log message's component.
The `Formation.standard`'s separator is `" ▶ "`.
### Apple's Unified Logging System
Senna reimplement the string interpolation behavior of [Apple's Unified Logging System](https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code)
let sink = StandardSink.out() let formation = Formation.standard var logger = Logger(label: "LogName") { Handler(name: $0, sink: sink, formation: formation, logLevel: .trace) } logger[metadataKey: "UserID"] = .stringConvertible(9527) #if DEBUG let privacy = Privacy.public #else let privacy = Privacy.private #endif // default is private logger.senna.notice("the user name is \("L1MeN9Yu")") logger.senna.notice("the user name is \("L1MeN9Yu", privacy: privacy)")
Terminal out :

see [LoggerSennaTests.swift](Tests/LoggerSennaTests.swift) for more usages.Installation
Swift Package Manager
Add the following to your Package.swift file:
dependencies: [
.package(url: "https://github.com/L1MeN9Yu/Senna.git", from: "3.0.0")
]Credit
License
Senna is available under the MIT license. See the LICENSE file for details.
Thanks | 鸣谢
Thanks to [JetBrains][JetBrains] for "Licenses for Open Source Development". [JetBrains][JetBrains] supports non-commercial open source projects by providing core project contributors with a set of best-in-class developer tools free of charge.
感谢 [JetBrains][JetBrains] 提供的开源开发许可证。[JetBrains][JetBrains] 通过为项目核心开发者免费提供开发工具来支持非商业开源项目。
[JetBrains]: https://www.jetbrains.com/?from=Senna
Package Metadata
Repository: l1men9yu/senna
Default branch: main
README: README.md