Different log levels for different groups of loggers
JetForMe opened this issue · 4 comments
One of the powerful features of Java's log4j is that different logging levels can be set for large swaths of the code. This is accomplished with a couple of things:
- Generally, each class has its own logger, named after the fully-qualified class name (Java has a hierarchical naming convention of pacakges and classes in them, e.g.
myapp.app.model.entities.Employee
- Log level can be specified at any level, e.g.
myapp.app.model
should log at TRACE, everything else at ERROR. - If a logger doesn't have a specific log level set, it uses its parent's level
These levels can be set at run time, making it easy to turn up or down the logging on parts of the code you need to focus on, without obscuring the output with too many messages from uninteresting code.
I don't see a way for swift-log to do that.
As I'm working to implement this functionality in my own LogHandler, I realize that the LogHandler's log
method isn't provided the calling Logger
’s data (like its label
), making implementing this functionality inelegant at best. I now have to pass the label as metadata when creating the logger. I’m going to open a separate issue to add this.
One of the powerful features of Java's log4j is that different logging levels can be set for large swaths of the code. This is accomplished with a couple of things:
...
I don't see a way for swift-log to do that.
These are good points which I totally agree with. In my project I tried to start repeating it like:
At a main entry point
var logLevel = Logger.Level.debug // a common and default log level
// ... code setting a log level based on a passed program parameter
LoggingSystem.bootstrap{ label in
var logHandler = StreamLogHandler.standardOutput(label: "com.github.vitalz.demo" + label)
logHandler.logLevel = logLevel
// TODO: MultiplexLogHandler([logHandler, fileLogHandler])
return logHandler
}
in my classes
public final class Controller {
static var logger: Logger { return Logger(label: "Controller") }
let log = Controller.logger
public func run() {
log.debug("Controller running...")
}
}
I've planned to add a YAML-config parser which extracts a logger config and to update LoggingSystem.bootstrap that it will set a log level for a passed label comparing it to configured labels on YAML.
I got some of the behavior I wanted with this class. If you create loggers with dotted names (e.g. com.mycompany.myapp.section1.logger1
), you can set thresholds with calls like this:
LogHandlerCoordinator.instance.set(rootThreshold: .debug)
LogHandlerCoordinator.instance.set(threshold: .warn, for: "com.mycompany.myapp.section1")
@JetForMe as you discovered already this would be a function of the log-backend and not the log-api (this library). for example, https://github.com/apple/swift-log/blob/main/Tests/LoggingTests/TestLogger.swift#L57 is a test log-backend that does a simplified version of this approach. of course, we would need a good log-backend that does this well. the log-backend that is included in swift-log is for development only and should not be used for real production applications