I know that polluting Obj is bad, but could we possibly add simple logging there, with methods logError, logInfo, and maybelogDetail? Along with a simple dispatch system that organizes things by the class where log call occurs? Anything else fancier (like choosing a custom logging category or checking the current log level) would require calls to separate logging classes.
The default would also be to dump all "info" and "error" level messages to Sys.err.
That would making logging a nice breeze (and consistent if in the core) compared to most other systems.
I imagine the log methods looking something like this:
Thanks for the links, and you are right. I didn't investigate the current APIs before posting. Apologies on that.
I was thinking more about echo. It's so convenient (and nicely so) that I'm afraid it will be too easy for people to use that for logging. If logInfo is equally accessible, people might go through logging correctly.
Also, I'd usually rather not go through the effort of digging up a particular log object (as in const static Log log = Log.get("acme")). I'd rather just get one named for my pod (or "pod::Type" or whatever) in most cases.
As ever, just a thought.
brianSat 12 Jul 2008
Tom, I can see where you are coming from, but I don't want to pollute the Obj namespace with anything not critical. I think adding echo was a big deal since we prevent application classes from using it (although it is so useful to make it worthwhile). In this case I'm not sure using a log is really more onerous than using what it takes to print in Java:
If we can come up with a convention or way to pass in "my current pod name or type qname" into the get method we could do something like:
Log.self.trace("...")
There isn't any language feature to do that right now though.
I think the important thing is that I agree logging should be standardized across everything - even the core system functions. So I decided to build logging into sys directly (with 3 whole classes!) which was a hard pill for me to swallow since I want to keep sys as small as possible.
tompalmerSat 12 Jul 2008
Thanks for the info. I thought of something that might work. How about each type gets its own log by default (using a once method even for lazy init), so you can do things like this:
type.log.info("Hello, world!")
if (type.log.isDebug) {
type.log.debug("No, really. Hello, world!")
}
Is that a good compromise?
And people can always go get their custom-named logs if wanted. I think the one sneaky thing here is that you'd get the log for the current object's type (meaning the subtype if there is one). To be sure to get the log for the lexically scoped type (which is what people would probably expect), you'd have to say Type.type.log.info("whatever"). Still, I think either is probably good enough in most cases.
I agree that the current Fan model is much like in Java. I just think it should be easier than that for the common case.
brianSat 12 Jul 2008
Tom - I'm with you a 100% on making it so easy that you can't help but use it (therefore creating consistent logging). I like your idea - the very common case is that there is a log per pod (actually that is what I have already in fand, web, webapp, etc). So my proposal is this:
// new way
type.error("...")
obj.type.info("...")
// which is a shortcut for:
Log.get(type.pod.name).error("...")
Log.get(obj.type.pod.name).info("...")
I really like that idea. It creates a good simple convention.
tompalmerSat 12 Jul 2008
Glad to hear that might work out.
brianSun 13 Jul 2008
done for next build
tompalmerSun 13 Jul 2008
Awesome.
By the way, is that type.error("...") or type.log.error("...")?
Also, is there some way to reference a pod statically by name? Or just by API with strings (or type.pod)?
brianSun 13 Jul 2008
By the way, is that type.error("...") or type.log.error("...")?
type.log.error(...)
katoxTue 14 Oct 2008
When writing debug log statements, we expect that they will be turned off most of the time. Therefore be aware of the hidden costs of string concatenation. You can use the isDebug method to skip creating a log message.
A proper way but who does it? Most people skip the test or they remove the logging code after they are finished with debugging. Thinking about recent changes what about using ?. operator to simplify that even more? Instead of:
if (type.log.isDebug) {
type.log.debug("No, really. Hello, world!")
}
not sure about the syntax but something less verbose would be very nice. If plain . operator was disallowed for possibly null objects it would be perfectly safe...
But integrated logging is sweet in any case.
And maybe trace debug level could be added -- the most used logging systems converged to five levels (log4j/logback). (JCL has even more -- not used and deployed with buggy implementation of custom Level.)
tompalmerWed 15 Oct 2008
Interesting thoughts.
Side note, I still think type.log isn't what most people want most of the time (since instances of subclasses will end up logging to the wrong place), which is one of the reasons I promote # to reference the surrounding type (in a static sense).
brianWed 15 Oct 2008
Side note, I still think type.log isn't what most people want most of the time (since instances of subclasses will end up logging to the wrong place), which is one of the reasons I promote # to reference the surrounding type (in a static sense).
I'm not sure I follow that. In that case # would mean the same thing as .type wouldn't it? Neither of those solutions would solve the subclass issue. Although the advantage of # is that it would work in a static context.
tompalmerWed 15 Oct 2008
I take # to mean the lexically enclosing class, not the class of this, though I guess I might have missed the meanings of #slot as to whether it cares about the type of this.
tompalmer Fri 11 Jul 2008
I know that polluting
Obj
is bad, but could we possibly add simple logging there, with methodslogError
,logInfo
, and maybelogDetail
? Along with a simple dispatch system that organizes things by the class where log call occurs? Anything else fancier (like choosing a custom logging category or checking the current log level) would require calls to separate logging classes.The default would also be to dump all "info" and "error" level messages to
Sys.err
.That would making logging a nice breeze (and consistent if in the core) compared to most other systems.
I imagine the log methods looking something like this:
andy Fri 11 Jul 2008
We actually already have a logging API in sys:
tompalmer Sat 12 Jul 2008
Thanks for the links, and you are right. I didn't investigate the current APIs before posting. Apologies on that.
I was thinking more about
echo
. It's so convenient (and nicely so) that I'm afraid it will be too easy for people to use that for logging. IflogInfo
is equally accessible, people might go through logging correctly.Also, I'd usually rather not go through the effort of digging up a particular log object (as in
const static Log log = Log.get("acme")
). I'd rather just get one named for my pod (or"pod::Type"
or whatever) in most cases.As ever, just a thought.
brian Sat 12 Jul 2008
Tom, I can see where you are coming from, but I don't want to pollute the Obj namespace with anything not critical. I think adding echo was a big deal since we prevent application classes from using it (although it is so useful to make it worthwhile). In this case I'm not sure using a log is really more onerous than using what it takes to print in Java:
If we can come up with a convention or way to pass in "my current pod name or type qname" into the get method we could do something like:
There isn't any language feature to do that right now though.
I think the important thing is that I agree logging should be standardized across everything - even the core system functions. So I decided to build logging into sys directly (with 3 whole classes!) which was a hard pill for me to swallow since I want to keep sys as small as possible.
tompalmer Sat 12 Jul 2008
Thanks for the info. I thought of something that might work. How about each type gets its own log by default (using a
once
method even for lazy init), so you can do things like this:Is that a good compromise?
And people can always go get their custom-named logs if wanted. I think the one sneaky thing here is that you'd get the log for the current object's type (meaning the subtype if there is one). To be sure to get the log for the lexically scoped type (which is what people would probably expect), you'd have to say
Type.type.log.info("whatever")
. Still, I think either is probably good enough in most cases.I agree that the current Fan model is much like in Java. I just think it should be easier than that for the common case.
brian Sat 12 Jul 2008
Tom - I'm with you a 100% on making it so easy that you can't help but use it (therefore creating consistent logging). I like your idea - the very common case is that there is a log per pod (actually that is what I have already in fand, web, webapp, etc). So my proposal is this:
So we can now just write:
I really like that idea. It creates a good simple convention.
tompalmer Sat 12 Jul 2008
Glad to hear that might work out.
brian Sun 13 Jul 2008
done for next build
tompalmer Sun 13 Jul 2008
Awesome.
By the way, is that
type.error("...")
ortype.log.error("...")
?Also, is there some way to reference a pod statically by name? Or just by API with strings (or
type.pod
)?brian Sun 13 Jul 2008
katox Tue 14 Oct 2008
A proper way but who does it? Most people skip the test or they remove the logging code after they are finished with debugging. Thinking about recent changes what about using
?.
operator to simplify that even more? Instead of:we could write
not sure about the syntax but something less verbose would be very nice. If plain
.
operator was disallowed for possibly null objects it would be perfectly safe...But integrated logging is sweet in any case.
And maybe
trace
debug level could be added -- the most used logging systems converged to five levels (log4j/logback). (JCL has even more -- not used and deployed with buggy implementation of custom Level.)tompalmer Wed 15 Oct 2008
Interesting thoughts.
Side note, I still think
type.log
isn't what most people want most of the time (since instances of subclasses will end up logging to the wrong place), which is one of the reasons I promote#
to reference the surrounding type (in a static sense).brian Wed 15 Oct 2008
I'm not sure I follow that. In that case
#
would mean the same thing as.type
wouldn't it? Neither of those solutions would solve the subclass issue. Although the advantage of#
is that it would work in a static context.tompalmer Wed 15 Oct 2008
I take
#
to mean the lexically enclosing class, not the class ofthis
, though I guess I might have missed the meanings of#slot
as to whether it cares about the type ofthis
.