Simple console debug logging.
This simple library was created to try and address the following concerns:
- Simple usage - using something like
print()
is simple enough that many devs will throw them in their code rather than use a "heavier" framework. - Enhanced information in the console - File, method, and line number are included in the output automatically, as well as simple time information.
- Developer control for amount of information that is right for them - simple to change your local file to tailor output toward how you personally develop / debug.
This library was not originally intended to address:
- Remote logging, or logging to other targets.
Further information on the above items below.
let test = "FOO"
log( "TEST: \(test)", type: .base )
// [27:57:604] TestController.testOutput:65 > TEST: FOO
If this is included as a separate module, then you will need to make sure to import DebugLog
before usage.
One of the purposes was to allow for developers to not always have to worry about their debug statements being removed before checking in their work, but rather be able to keep those important to debugging and learning the flow through a section in the code behind a module flag. Then each developer can determine the what information they do or don't want to see in their console. These local changes would just be able to be discarded ( or stashed ) when pulling latest, so they should be easy to set.
A primary method of developer customizing for level of output by module is In DebugFlag
:
public struct DebugFlag {
public static let items: [DebugModule] = [
DebugModule(name: "Base", icon: "", show: true, type: .base),
DebugModule(name: "Error", icon: "🔥", show: true, type: .error),
DebugModule(name: "Network", icon: "", show: true, type: .network),
DebugModule(name: "AmEx", icon: "", show: false, type: .amex),
]
}
If you want to see output related to AmEx, simply set show: true
. Conversely, if you don't need to
see network calls, you can turn those off easily.
The other way to fine-tune what you see ( and how ) is in DebugFeature
. This allows you to do things
like get more granular output for some modules ( Eg: Viewing network request headers ), or to
change to having the full file path output instead of just the file name:
public struct DebugFeature {
/// Turn on to force all output to show ( not yet implemented )
static let showAllOutput = false
/// Turn on to show the passed log output before the file/line/time information
static let outputFirst = false
/// Turn on to show the filePath/fileName instead of just fileName
static let showFilePath = false
/// Turn on to show the headers for data requests in the output
static let requestHeaders = false
}
If you are working on a new module / section to the code, you just need two to add two things: Update
the DebugFilterType
enum to have a value for that section ( Eg: case plaid
), and then add to the
items array for that module in DebugFlag
public struct DebugFlag {
public static let items: [DebugModule] = [
// ... previous items
DebugModule(name: "Plaid", icon: "", show: false, type: .plaid),
]
}
Debug features are used to enable / disable certain things. These could be things like console output ( Eg: putting user output before file ), or for hiding additional information logging from modules ( Eg: writing out request headers in networking ). The second scenario is shown below.
fileprivate func makeNetworkCall() {
let method = "GET"
let shortPath = "/v1/test-call"
let headers = ["TOKEN": "1774-7772-3345"]
log("\(method) \(shortPath)", type: .network)
if DebugFeature.requestHeaders {
log("HEADERS: \(headers)", type: .network)
}
}
In the above scenario, the request headers will only get logged out if the associated DebugFeature flag has been enabled.
Absolutely, and there is already basic support implemented for os_log usage in a development context. But remember the primary intent is to provide a quick, simple method for developers to log information for development and testing purposes - with a heavy eye towards "discoverability". That said, a flag for os_log has been added to allow for expanded usage if desired. It would be very little additional work to allow all output through if the target is os_log.
I've seen too many examples of robust logging libraries not being used in favor of simple NSLog / print statements because a developer just wants a quick way to try and track things in a section they're working on through several files associated with a feature. The more barriers you put in the way of usage, the less likely it will get used. All the great features in the world don't matter if they are never used.
Discoverability is simply the ability to determine the origin of a console statement. Currently, without discoverability provided in the form of File.method:line if you have an excess of console output that buries statements you are trying to use for debugging, you don't know where to look to remove them. Having too much information diluting the output makes the console virtually worthless as a tool if you have several areas to look at.
This works great in cases where the console output has the full path in it or some other unique, identifying piece of information. However in the absence of that information, or if you need to see output from multiple modules at once ( Eg: Networking, Routes, and Amex ) then it falls a bit short.
Only because it allows me to more easily identify console output in the project that did not come from this library. Otherwise I would tend towards only errors having them to really make them stand out.
Traditionally there are extensive frameworks available for this that allows for all aspects of application usage to be tracked for a user session, including crashes. If this level is desired, I would propose that there are several existing, mature frameworks and services that will cover that need far better. But I think it could probably be extended a bit more than it currently is if there was a need for it.
It would be easy to modify to make sure that all logging statements to got OSLog when it's enabled, regardless of if their respective module is enabled. I would just say we would want to vote on if that should be default or not, or if it should be a debug feature flag, but it seems like a good modification.
The code itself is very simple, and would be trivial to add functionality to. That said, another goal of this library is to provide lean functionality, so I would encourage dilligent assessment for how much any given feature add would increase complexity as weight against actual potential usage.
I was considering this - would it be useful? The notable modules I found that had Obj-C still were PayPal Data Collector, mParticle, and AppBoy.
Got you covered:
logStack()
Please, let me know!