Open tombentley opened 12 years ago
Agreed, but I'm not sure the ceylon.logging
and the tool chain logging are much related though. In certain cases like the JS backend it will be mostly impossible to do so anyway. Still I think it would be useful to have ceylon.logging
on the JVM use the same Java backend if possible, if only for better integration with Java and to prevent us from having to ship several backends.
You're right, they don't need the same API, but I think there does need to be some commonality in how they're configured.
For example, the ceylon
command might accept a 'top level' --debug
option, which would echo debug-level log messages to standard output. But we might only be interested in 'application' debug (i.e. from ceylon.logging
), or 'system' debug (from the ceylon
command, ceylon-runtime etc). Perhaps it's as simple as using appropriate logging categories, but I thought it was at least worth mentioning here lest we overlook it and end up with a mess.
But that's the point I was trying to make, I don't think the ceylon
command should affect the application debugging, they're two different systems, especially because I think it will be difficult to intercept JS logging anyway.
I suffered this issue a little when refactoring some of the .src archive generation code. Having a logging abstraction in ceylon-common would definitely help to decouple a lot of stuff which sometimes is tied to, say, javac, just because it uses javac logging directly instead of some API (which can have a javac-logging backend for ceylonc).
So +1 for this; there should be a very simple logging API in ceylon-common, with a simple implementation which uses System.out
and System.err
, or JUL (or two implementation, one for each). Then ceylonc can have its own implementation using javac-logging. This would be only for current tools (compiler, runtime, etc) which are written in Java; ceylon.logging
like @quintesse says is going to be a logging API and probably implementation to be used in Ceylon modules.
Adding a logging API to ceylon-common should be simple enough. A default implementation should also be relatively simple. More problematic is how we're going to configure it, while not creating some over-complex monster.
I would be happy with:
error
, warn
, info
and debug
log levelsI still don't know about the default message format, or things like logging categories.
To push discussion along a bit, I've created a 'log' branch with a very simplistic sketch of what be a solution. The commit message for 45cae91 includes a few issues, but I'm sure there are plenty more.
I think we should copy the design of the standard Java logging APIs a bit more, especially the part where the String you pass is a format string and then you can pass several arguments to be used by it. This makes sure that the logging is as efficient as possible when not used.
+1
The alternative would be log4j-style if (log.isDebugEnabled())
guards around the log.debug()
(etc). I always hated those because it makes logging take up three times more vertical space than it should.
I see that those APIs make a distinction between 'message parameters' and exceptions, presumably so they can dump the exception's stacktrace, not just include its String.valueOf()
.
Do we also support the String message also being a key into a message catalog? If so, how would we find the catalog? If not, the facade is a leaky abstraction because depending on the implementation in use you'd either get a helpful message or rather less helpful message key.
And what I'd really suggest is to just use an existing interface like http://www.slf4j.org/apidocs/org/slf4j/Logger.html , it's a very popular package, it's tiny and at the same time very flexible if we ever want to use other implementations (like logback).
I've used it before and I liked it in those situations. I think using it would solve the API part.
I'm not certain about the configuration aspect though. The tool scripts could just include an appropriate backend jar in their classpath, but it would be legitimate for an application to want to have multiple compiler instances (for example) and direct the log messages to different places. Similarly I worry about the fact that the RunTool
(some day soon ceylon run
) will want to be doing its own logging, but the running application (which might also use slf4j) wouldn't want to pick up the same binding. I guess it all depends on how the modular classloader delegates (my point is I don't know).
(Btw: I fully concede that the simple API I wrote doesn't address this either)
I think the slf4j API is flexible enough so we can adjust it to that kind of situation in the future. Let's start simple and leave the complex situations for when we get to them, I think the unification of all loggers we currently use is already big enough of a job :)
Moving to M6
Currently a whole bunch of things each use their own logging:
Logger
interface. Because everything else already does its own logging there are already with 7 implementations (delegating to JUL,System.err
, javacLog
, plus a couple of No-op loggers)ceylon.logging
module.It seems like ceylon-common is a good place to define a common API (and some implementations).