Light-weight logging lover in Swift. Hereinafter
CPL
stands forC
onsoleP
erseusL
ogger.
- Log to the console.
- Log to macOS Console.app.
- Log to custom output.
[TYPE] [DATE] [TIME] [PID:TID] message, file: #, line: #
CPL
is a single author and personale solution developed inperson-to-person
relationship paradigm.
Tip
To adopt CPL
for the specifics you need use Standalone.
A3 Environment and Approbation
/CHANGELOG
for details.
Xcode playground download page.
USE LOGGER LIKE A VARIABLE ANYWHERE YOU WANT.
Tip
As the single source code CPLStar.swift CPL with minimum changes can be used even in Xcode 10.1, just remove all statements starting with if #available(iOS 14.0, macOS 11.0, *)
.
Type | Name | License |
---|---|---|
Style | SwiftLint / v0.57.0 for Monterey+ | MIT |
Script | SwiftLint Shell Script to run SwiftLint | MIT |
Action | mxcl/xcodebuild@v3 | Unlicense |
Action | cirruslabs/swiftlint-action@v1 | MIT |
Standalone: the single source code file CPLStar.swift
Swift Package Manager:
https://github.com/perseusrealdeal/ConsolePerseusLogger
Note
If output is consoleapp and Environment Variable OS_ACTIVITY_MODE
in disable
log messaging will be restricted for Xcode console, but only.
import ConsolePerseusLogger
log.message("[\(type(of: self))].\(#function)")
import ConsolePerseusLogger
// MARK: - Log to Console.app
// log.logObject = ("MyApp", "MyLover") // Customs for Console.app Subsystem and Category.
log.output = .consoleapp
log.message("The app's start point...", .info)
import ConsolePerseusLogger
typealias Level = ConsolePerseusLogger.PerseusLogger.Level
func customPrint(_ text: String, _ type: Level, _ localTime: LocalTime, _ owner: PIDandTID) {
let time = "[\(localTime.date)] [\(localTime.time)]"
let id = "[\(owner.pid):\(owner.tid)]"
print("[MYLOG] [\(type)] \(time) \(id) \(text)")
}
log.customActionOnMessage = customPrint(_:_:_:_:)
log.format = .textonly
log.output = .custom
log.message("The app's start point...", .info)
Case 1:
as is
Image(systemName: "globe")
.onAppear {
log.message("This is the debug output.")
}
Case 2:
wrapper
Add an extension on View that returns itself and calls the logger's message method:
extension View {
func message(_ text: @autoclosure () -> String,
_ type: PerseusLogger.Level = .debug,
_ oput: PerseusLogger.Output = PerseusLogger.output,
_ file: StaticString = #file,
_ line: UInt = #line) -> Self {
log.message(text(), type, oput, file, line)
return self
}
}
Then use message as a view modifier to print debug information to the console when the view is built:
VStack {
ForEach(colors, id: \.self) { color in
Circle()
.foregroundColor(color)
.message("\(color)")
}
}
CPL applies the most common log types for indicating information category.
Level | Message Type | Description |
---|---|---|
5 | DEBUG | Debugging only |
4 | INFO | Helpful, but not essential |
3 | NOTICE | Might result in a failure |
2 | ERROR | Errors seen during the code execution |
1 | FAULT | Faults and bugs in the code |
Also, CPL considers Message Type to filter, look how it works:
Default values of CPL options depend on DEBUG/RELEASE.
Option | Default in DEBUG | Default in RELEASE |
---|---|---|
tuned | .on | .off |
output | .standard | .consoleapp |
level | .debug | .notice |
Other CPL options are the same for DEBUG/RELEASE by default.
Option | Default in DEBUG | Default in RELEASE |
---|---|---|
subsecond | .nanosecond | .nanosecond |
tidnumber | .hexadecimal | .hexadecimal |
format | .short | .short |
marks | true | true |
time | false | false |
owner | false | false |
directives | false | false |
logObject | ("Perseus", "Lover") | ("Perseus", "Lover") |
Special option goes kinda lifehack. Matter only if Simulator.
Option | Default in DEBUG | Default in RELEASE |
---|---|---|
debugIsInfo | true | true |
Each option can be reseted in run time with json config except option
turned
.
Case 1:
Using predefined json profile
import ConsolePerseusLogger
let isReseted = log.loadConfig(.debugRoutine)
let result = isReseted ? "CPL current options loaded." : "Failed to load options!"
log.message(result)
Case 2:
Using custom profile (URL required)
import ConsolePerseusLogger
var result = ""
if let path = Bundle.main.url(forResource: "CPLConfig", withExtension: "json") {
let isLoaded = log.loadConfig(path)
result = isLoaded ? "Options successfully loaded." : "Failed to load options!"
} else {
result = "Failed to create URL!"
}
log.message(result)
In case if CPL in use as a standalone file in SPM package.
//
// main.swift
//
import ConsolePerseusLogger
import class PackageA.PerseusLogger
import class PackageB.PerseusLogger
typealias logA = PackageA.PerseusLogger
typealias logB = PackageB.PerseusLogger
// MARK: - Subloggers
logA.turned = .off
logB.turned = .off
// MARK: - Logger
log.message("The app's start point...", .info)
Just a matter of fact that Console.app doesn't show any DEBUG message from any app running on Simulator (even if "Include Debug Messages" tapped in Console.app).
Console Perseus Logger running on Simulator doesn't pass DEBUG message to Console.app, instead it passes INFO message with text of DEBUG message by default if Simulator runs, so, a passed message being INFO looks like a DEBUG and it works perfactly well.
If for some reasons CPL must pass DEBUG like a DEBUG message the option should take false
log.debugIsInfo = false
.
#if targetEnvironment(simulator)
log.debugIsInfo = false
#endif
- Preconfigured Swift Package manifest Package.swift
- Preconfigured SwiftLint config .swiftlint.yml
- Preconfigured SwiftLint CI swiftlint.yml
- Preconfigured GitHub config .gitignore
- Preconfigured GitHub CI main.yml
Copyright © 7531 - 7533 Mikhail A. Zhigulin of Novosibirsk
Copyright © 7531 - 7533 PerseusRealDeal
- The year starts from the creation of the world according to a Slavic calendar.
- September, the 1st of Slavic year. It means that "Sep 01, 2024" is the beginning of 7533.
© 2025 The SwiftLint Contributors for SwiftLint
© GitHub for GitHub Action cirruslabs/swiftlint-action@v1
© 2021 Alexandre Colucci, geteimy.com for Shell Script SucceedsPostAction.sh
LICENSE for details.
Balance and Control | kept by | Mikhail A. Zhigulin |
Source Code | written by | Mikhail A. Zhigulin |
Documentation | prepared by | Mikhail A. Zhigulin |
Product Approbation | tested by | Mikhail A. Zhigulin |
- Language support: Reverso
- Git clients: SmartGit and GitHub Desktop
© Mikhail A. Zhigulin of Novosibirsk.