GWT Logging Design

55 views
Skip to first unread message

Emily Crutcher

unread,
Jan 31, 2008, 4:07:37 PM1/31/08
to Google Web Toolkit Contributors
Here is the initial WIKI for the gwt incubator Logging design. Any feedback you have would be welcome.

               Cheers,

                       Emily

http://code.google.com/p/google-web-toolkit-incubator/wiki/Logging

--
"There are only 10 types of people in the world: Those who understand binary, and those who don't"

Henri Karapuu

unread,
Jan 31, 2008, 5:29:36 PM1/31/08
to Google Web Toolkit Contributors
> Here is the initial WIKI for the gwt incubator Logging design. Any feedback
> you have would be welcome.

- Should definitely work in the server side too (use case: client and
server share code)

- Should support Category / Channel concept. Here is example of the
syntax that i'm using currently. Not the prettiest, but works ok:
Logger.error(Channel.BEAN, "Unable to set value - conversion failed",
e)

- It would be nice to have support for configuring handlers per level,
and for multiple handlers. Use case: at Level of ERROR or higher the
log message could be sent _also_ to server via RPC.

/Henri Karapuu

John Tamplin

unread,
Jan 31, 2008, 5:43:34 PM1/31/08
to Google-Web-Tool...@googlegroups.com
On Jan 31, 2008 4:07 PM, Emily Crutcher <e...@google.com> wrote:
Here is the initial WIKI for the gwt incubator Logging design. Any feedback you have would be welcome.

It should support logging to the javascript console whether firebug is installed or not.

--
John A. Tamplin
Software Engineer, Google

Emily Crutcher

unread,
Jan 31, 2008, 6:21:18 PM1/31/08
to Google-Web-Tool...@googlegroups.com
Good point. That should definitely be a goal as well.

Ray Cromwell

unread,
Jan 31, 2008, 6:46:18 PM1/31/08
to Google-Web-Tool...@googlegroups.com
Can we file a side compiler RFE to verify temporary expressions at the
callsite are optimized away when debugging is enabled? :)

That is,

log.warn("The value " + value.getValue() + " is invalid")

should result in nothing, rather than evaluating value.getValue() and
concatenating the result only to throw it away. :)

-Ray

Fred Sauer

unread,
Jan 31, 2008, 6:58:19 PM1/31/08
to Google-Web-Tool...@googlegroups.com
Thanks Emily.


A few thoughts...


Firebug/Console Logging
  • Agree with John - It seems console.log() is commonly made available in JavaScript libraries.
  • I might suggest renaming the Firebug logger to, say, Console logger, and have the Firebug functionality degrade gracefully to console.log()

GWT.log
  • Having GWT.log() as a target may be very useful was well

Server Side Logging
  • I would almost argue this is a must-have, since that would be the only reasonable way to support logging in domain objects which are used on both client and server

JDK 1.4 vs log4j vs. Apache Commons
  • I don't know what the numbers are, both in terms of actual projects using a particular API, or actual developers familiar with one API or another, but, log4j has been around longer, and therefore may be accepted/known
  • I find JDK 1.4 logging to be a bit clumsy, although workable; I don't like their level names, or the default to only log SEVERE messages; plus, what is CONFIG anyway :)
  • I like log4j for its straight forward levels and diverse set of available appenders, so, I'd like to see the gwt API and levels modeled after log4j

Direct Access to Loggers
  • This is especially useful for widget loggers which may need to be manipulated at run time
  • However, this could certainly wait till a later release, after use cases have been flushed out

Number of compile time options
  • I like the simplified notion of logging either being turned on or off, with runtime log level filtering on top of that; it's much easier to explain and understand
  • Having a multitude of compile time log levels can always be added later (I do think we should leave the door open to this option), but could also be left to a specialized logging package, or an advanced how-to
  • I also think loggers need to be able to be turned off at compile time; Instantiating the loggers with GWT.create(...) would allow users an easy way to replace any logger with a Null Logger

Grouping/Categories
  • I've seen multiple requests for both grouping (as in Firebug's console.group()), and categories (with different filters/levels by category)

Widget Loggers
  • This may be a place where we'd want to make a user provided implementation plugable at compile time, as expect to see various specialized use cases
  • A simple GWT.create(...) could take care of this requirement

Fred
--
Fred Sauer
fr...@allen-sauer.com

jdwy

unread,
Feb 1, 2008, 8:55:56 AM2/1/08
to Google Web Toolkit Contributors
>>Server Side Logging
Yes yes, I agree! Thanks Fred. This is a must have for me. (Though I'm
happy sticking with gwt-log now that it support this :)

>> JDK 1.4 vs log4j vs. Apache Commons
When thinking about API I would also add SLF4j to this list since
they've already done some thinking about how to be a facade for a
number of logging implementations and I like their nomenclature. In
practice I'm a log4j guy as well.
http://www.slf4j.org/api/index.html

-Jeff

On Jan 31, 6:58 pm, "Fred Sauer" <f...@allen-sauer.com> wrote:
> Thanks Emily.
>
> A few thoughts...
>
> Firebug/Console Logging
>
>    - Agree with John - It seems console.log() is commonly made available
>    in JavaScript libraries.
>    - I might suggest renaming the Firebug logger to, say, Console logger,
>    and have the Firebug functionality degrade gracefully to console.log()
>
> GWT.log
>
>    - Having GWT.log() as a target may be very useful was well
>
> Server Side Logging
>
>    - I would almost argue this is a must-have, since that would be the
>    only reasonable way to support logging in domain objects which are used on
>    both client and server
>
> JDK 1.4 vs log4j vs. Apache Commons
>
>    - I don't know what the numbers are, both in terms of actual projects
>    using a particular API, or actual developers familiar with one API or
>    another, but, log4j has been around longer, and therefore may be
>    accepted/known
>    - I find JDK 1.4 logging to be a bit clumsy, although workable; I
>    don't like their level names, or the default to only log SEVERE messages;
>    plus, what is CONFIG anyway :)
>    - I like log4j for its straight forward levels and diverse set of
>    available appenders, so, I'd like to see the gwt API and levels modeled
>    after log4j
>
> Direct Access to Loggers
>
>    - This is especially useful for widget loggers which may need to be
>    manipulated at run time
>    - However, this could certainly wait till a later release, after use
>    cases have been flushed out
>
> Number of compile time options
>
>    - I like the simplified notion of logging either being turned on or
>    off, with runtime log level filtering on top of that; it's much easier to
>    explain and understand
>    - Having a multitude of compile time log levels can always be added
>    later (I do think we should leave the door open to this option), but could
>    also be left to a specialized logging package, or an advanced how-to
>    - I also think loggers need to be able to be turned off at compile
>    time; Instantiating the loggers with GWT.create(...) would allow users
>    an easy way to replace any logger with a Null Logger
>
> Grouping/Categories
>
>    - I've seen multiple requests for both grouping (as in Firebug's
>    console.group()), and categories (with different filters/levels by
>    category)
>
> Widget Loggers
>
>    - This may be a place where we'd want to make a user provided
>    implementation plugable at compile time, as expect to see various
>    specialized use cases
>    - A simple GWT.create(...) could take care of this requirement
>
> Fred
>
> On Jan 31, 2008 2:07 PM, Emily Crutcher <e...@google.com> wrote:
>
> > Here is the initial WIKI for the gwt incubator Logging design. Any
> > feedback you have would be welcome.
>
> >                Cheers,
>
> >                        Emily
>
> >http://code.google.com/p/google-web-toolkit-incubator/wiki/Logging
>
> > --
> > "There are only 10 types of people in the world: Those who understand
> > binary, and those who don't"
>
> --
> Fred Sauer
> f...@allen-sauer.com

Emily Crutcher

unread,
Feb 1, 2008, 11:35:32 AM2/1/08
to Google-Web-Tool...@googlegroups.com
On Thu, Jan 31, 2008 at 6:58 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
Thanks Emily.


A few thoughts...


Firebug/Console Logging
  • Agree with John - It seems console.log() is commonly made available in JavaScript libraries.
  • I might suggest renaming the Firebug logger to, say, Console logger, and have the Firebug functionality degrade gracefully to console.log()
That seems like a good idea. Do you think you might implement this? As right now the plan is to use gwt-log's infrastructure for almost all this functionality.

 

GWT.log
  • Having GWT.log() as a target may be very useful was well
I think I don't understand this comment, can you elaborate?
 

Server Side Logging
  • I would almost argue this is a must-have, since that would be the only reasonable way to support logging in domain objects which are used on both client and server
I could see that argument. It will be slightly awkward code, because GWT.create will actually throw an error when run outside a GWT development environment, but it does seem like a useful feature.
 

JDK 1.4 vs log4j vs. Apache Commons
  • I don't know what the numbers are, both in terms of actual projects using a particular API, or actual developers familiar with one API or another, but, log4j has been around longer, and therefore may be accepted/known
  • I find JDK 1.4 logging to be a bit clumsy, although workable; I don't like their level names, or the default to only log SEVERE messages; plus, what is CONFIG anyway :)
  • I like log4j for its straight forward levels and diverse set of available appenders, so, I'd like to see the gwt API and levels modeled after log4j
I like log4j as well, however my concern here is to create a API familiar to the greatest number of our users, which seems like it is the Java logging API. If you have data that would suggest otherwise, that would be interesting to see.
 

Direct Access to Loggers
  • This is especially useful for widget loggers which may need to be manipulated at run time
  • However, this could certainly wait till a later release, after use cases have been flushed out
This would depend upon whether we can completely flush the call sites. As one of the big reasons we are creating a logging package is to maintain the zero cost logging messages when logging is turned off. 

That being said, given the awesome work Scott/Mathew have done for dead code stripping, it might be easier then I think to create instance loggers.





Number of compile time options
  • I like the simplified notion of logging either being turned on or off, with runtime log level filtering on top of that; it's much easier to explain and understand
  • Having a multitude of compile time log levels can always be added later (I do think we should leave the door open to this option), but could also be left to a specialized logging package, or an advanced how-to
I like this idea. One point that was made on a separate thread is that some programs want "severe" logging turned on at all time, which might make this feature come in sooner then expected.
 
 
  • I also think loggers need to be able to be turned off at compile time; Instantiating the loggers with GWT.create(...) would allow users an easy way to replace any logger with a Null Logger
 Right now, the goal is that we have absolutely no class or method invocations left so there should be no need for a Null Logger.


Grouping/Categories
  • I've seen multiple requests for both grouping (as in Firebug's console.group()), and categories (with different filters/levels by category)
The way this is handled in the current design is that each handler has an optional set of parameters supplied to it.  Those parameters can be used to specify group or category. 

 

Widget Loggers
  • This may be a place where we'd want to make a user provided implementation plugable at compile time, as expect to see various specialized use cases
  • A simple GWT.create(...) could take care of this requirement
Yes, I'm creating TreeHandler to test this requirement.. My hope is all I need to do is guard the creation in a call to isLoggingEnabled()

         Thanks for your great feedback!

                       Emily
 

Fred

On Jan 31, 2008 2:07 PM, Emily Crutcher <e...@google.com> wrote:
Here is the initial WIKI for the gwt incubator Logging design. Any feedback you have would be welcome.

               Cheers,

                       Emily

http://code.google.com/p/google-web-toolkit-incubator/wiki/Logging

--
"There are only 10 types of people in the world: Those who understand binary, and those who don't"




--
Fred Sauer
fr...@allen-sauer.com


Fred Sauer

unread,
Feb 1, 2008, 1:37:27 PM2/1/08
to Google-Web-Tool...@googlegroups.com
Emily,

On Feb 1, 2008 9:35 AM, Emily Crutcher <e...@google.com> wrote:
On Thu, Jan 31, 2008 at 6:58 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
Firebug/Console Logging
  • Agree with John - It seems console.log() is commonly made available in JavaScript libraries.
  • I might suggest renaming the Firebug logger to, say, Console logger, and have the Firebug functionality degrade gracefully to console.log()
That seems like a good idea. Do you think you might implement this? As right now the plan is to use gwt-log's infrastructure for almost all this functionality.

It's on the to-do this. I currently have two separate loggers (i.e. firebug and console loggers). I need to at least disable the console logger when firebug(lite) is available (which is a one line code change), but I think it makes more sense to combine the two into a single logger with varying levels of integration with $wnd.console, depending on the browser and/or installed library or debugging facility. Over time, I also expect the browsers/libraries/frameworks to expand, and hopefully coalesce a bit around a common API, so I think some runtime detection at logger initialization will go a long ways here.



GWT.log
  • Having GWT.log() as a target may be very useful was well
I think I don't understand this comment, can you elaborate?

I'm assuming that client code would call something like 'org.google.gwt.log.client.Log.debug(.., ...)', and that module configuration (via deferred binding parameters) would then target the provided messages to various logger such as $wnd.console, System.err, RPC, Widget, etc. Having the option of these messages go to hosted mode tree logger is what I was proposing here.

 
 
Server Side Logging
  • I would almost argue this is a must-have, since that would be the only reasonable way to support logging in domain objects which are used on both client and server
I could see that argument. It will be slightly awkward code, because GWT.create will actually throw an error when run outside a GWT development environment, but it does seem like a useful feature.

I have this working in gwt-log with a bit of library magic, and I definitely think this is worth doing. Otherwise, I expect that the lack of a common logging API for both client and server is going to be a common struggling block.


 
JDK 1.4 vs log4j vs. Apache Commons
  • I don't know what the numbers are, both in terms of actual projects using a particular API, or actual developers familiar with one API or another, but, log4j has been around longer, and therefore may be accepted/known
  • I find JDK 1.4 logging to be a bit clumsy, although workable; I don't like their level names, or the default to only log SEVERE messages; plus, what is CONFIG anyway :)
  • I like log4j for its straight forward levels and diverse set of available appenders, so, I'd like to see the gwt API and levels modeled after log4j
I like log4j as well, however my concern here is to create a API familiar to the greatest number of our users, which seems like it is the Java logging API. If you have data that would suggest otherwise, that would be interesting to see.

Maybe we could have a poll on GWT and GWTC (pinned?) to get an idea of the community thinks. Another option (slf4j does this), is to provide optional, API compatible, drop-in replacement for these logging libraries on the client side. (I'm not recommending this out of the gate, but might be an option to consider longer term if the community is really split down the middle on what to support.) In other words, while client code might write 'org.apache.log4j.Logger.getLogger("...").debug(...)', GWT would provide an implementation of that API that would do everything we talked about here.

If there is a strong community preference for JDK 1.4 style logging, I'll go with that, but would otherwise recommend we pick the 'better' logging solution to model ourselves after. (We must, of course, first agree upon which is the 'better' model.)



 
Direct Access to Loggers
  • This is especially useful for widget loggers which may need to be manipulated at run time
  • However, this could certainly wait till a later release, after use cases have been flushed out
This would depend upon whether we can completely flush the call sites. As one of the big reasons we are creating a logging package is to maintain the zero cost logging messages when logging is turned off. 
That being said, given the awesome work Scott/Mathew have done for dead code stripping, it might be easier then I think to create instance loggers.

In the worst case, the getFooLogger() methods could return null, which client code could guard against, and use to conditionally execute logging related code. However, I also expect that we can avoid this, based on compiler optimizations, which would allows us to return instead a NullLogger with lots of empty implementation methods in it, which would cause client logging code to get compiled out. For initialization/configuration code with side-effects users could always guard with Log.isLoggingEnabled(), or widgetLogger.isLoggerEnabled().


 
Number of compile time options
  • I like the simplified notion of logging either being turned on or off, with runtime log level filtering on top of that; it's much easier to explain and understand
  • Having a multitude of compile time log levels can always be added later (I do think we should leave the door open to this option), but could also be left to a specialized logging package, or an advanced how-to
I like this idea. One point that was made on a separate thread is that some programs want "severe" logging turned on at all time, which might make this feature come in sooner then expected.

For gwt-log I felt that the implementation burden of allowing  any of the log levels as compile time levels was low enough that this was worth doing. However, I  can also see the benefit of providing only two levels (on/off) for a core GWT logging solution, to encourage better programming practices. That is, rather than someone leaving SEVERE/ERROR/FATAL logging turned on for production, the developer is encouraged to handle these cases in a application-meaningful way. Having a SEVERE logging message popup in a widget logger, or on my firebug console, when I am in Gmail is probably not going to provide the best user experience. (Although, neither does 'Oops, error 767' :)


  • I also think loggers need to be able to be turned off at compile time; Instantiating the loggers with GWT.create(...) would allow users an easy way to replace any logger with a Null Logger
 Right now, the goal is that we have absolutely no class or method invocations left so there should be no need for a Null Logger.

I see the NullLogger as an implementation detail, providing a deferred binding 'replace-with' class: a logger with empty implementation methods that would all get compiled out.
 


Grouping/Categories
  • I've seen multiple requests for both grouping (as in Firebug's console.group()), and categories (with different filters/levels by category)
The way this is handled in the current design is that each handler has an optional set of parameters supplied to it.  Those parameters can be used to specify group or category. 

There are implementation differences we will need to consider, e.g.
  • The GWT tree logger would let you create two separate child trees, with logging messages separately going to each child tree, based on, say, category.
  • Firebug logger's group()/endGroup() only allows you to be logging at the end of the log tree, be it inside a group or not.
  • Other loggers may allow after-the-fact filtering/grouping to effectively separation/categorization
Questions:
  • Should the GWT logging solution provide only the lowest common denominator?
  • If not, how should each logging target degrade?


 
Widget Loggers
  • This may be a place where we'd want to make a user provided implementation plugable at compile time, as expect to see various specialized use cases
  • A simple GWT.create(...) could take care of this requirement
Yes, I'm creating TreeHandler to test this requirement.. My hope is all I need to do is guard the creation in a call to isLoggingEnabled()

Sounds good.


 
         Thanks for your great feedback!

Thank you.



--
Fred Sauer
fr...@allen-sauer.com

Emily Crutcher

unread,
Feb 1, 2008, 6:53:55 PM2/1/08
to Google-Web-Tool...@googlegroups.com
I would love to take a quick poll, from water-cooler discussions it seems like there are a sizable fraction of people who would like to see  java.util.logging.Logger  supported even though
 a) only some of the Logger methods would be supported
 b) there would be extra compiled overhead for creating and assigning null loggers in some cases.
 c) there would be a bit of extra overhead when logging, as we would have to create and introduce LogRecords (which are useful though) into the system.

Do you agree?
 
          Thanks,

                     Emly

P.S. regular scheduled logging discussion continues with answered inlined below.


On Fri, Feb 1, 2008 at 1:37 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
Emily,

On Feb 1, 2008 9:35 AM, Emily Crutcher <e...@google.com> wrote:
On Thu, Jan 31, 2008 at 6:58 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
Firebug/Console Logging
  • Agree with John - It seems console.log() is commonly made available in JavaScript libraries.
  • I might suggest renaming the Firebug logger to, say, Console logger, and have the Firebug functionality degrade gracefully to console.log()
That seems like a good idea. Do you think you might implement this? As right now the plan is to use gwt-log's infrastructure for almost all this functionality.

It's on the to-do this. I currently have two separate loggers (i.e. firebug and console loggers). I need to at least disable the console logger when firebug(lite) is available (which is a one line code change), but I think it makes more sense to combine the two into a single logger with varying levels of integration with $wnd.console, depending on the browser and/or installed library or debugging facility. Over time, I also expect the browsers/libraries/frameworks to expand, and hopefully coalesce a bit around a common API, so I think some runtime detection at logger initialization will go a long ways here.

Sounds great.
 


GWT.log
  • Having GWT.log() as a target may be very useful was well
I think I don't understand this comment, can you elaborate?

I'm assuming that client code would call something like 'org.google.gwt.log.client.Log.debug(.., ...)', and that module configuration (via deferred binding parameters) would then target the provided messages to various logger such as $wnd.console, System.err, RPC, Widget, etc. Having the option of these messages go to hosted mode tree logger is what I was proposing here.


Yes, that sounds like a good idea.
 

 
 
Server Side Logging
  • I would almost argue this is a must-have, since that would be the only reasonable way to support logging in domain objects which are used on both client and server
I could see that argument. It will be slightly awkward code, because GWT.create will actually throw an error when run outside a GWT development environment, but it does seem like a useful feature.

I have this working in gwt-log with a bit of library magic, and I definitely think this is worth doing. Otherwise, I expect that the lack of a common logging API for both client and server is going to be a common struggling block.

How does it work? As that seems like a  cool technique.
 


 
JDK 1.4 vs log4j vs. Apache Commons
  • I don't know what the numbers are, both in terms of actual projects using a particular API, or actual developers familiar with one API or another, but, log4j has been around longer, and therefore may be accepted/known
  • I find JDK 1.4 logging to be a bit clumsy, although workable; I don't like their level names, or the default to only log SEVERE messages; plus, what is CONFIG anyway :)
  • I like log4j for its straight forward levels and diverse set of available appenders, so, I'd like to see the gwt API and levels modeled after log4j
I like log4j as well, however my concern here is to create a API familiar to the greatest number of our users, which seems like it is the Java logging API. If you have data that would suggest otherwise, that would be interesting to see.

Maybe we could have a poll on GWT and GWTC (pinned?) to get an idea of the community thinks. Another option (slf4j does this), is to provide optional, API compatible, drop-in replacement for these logging libraries on the client side. (I'm not recommending this out of the gate, but might be an option to consider longer term if the community is really split down the middle on what to support.) In other words, while client code might write 'org.apache.log4j.Logger.getLogger("...").debug(...)', GWT would provide an implementation of that API that would do everything we talked about here. 

If there is a strong community preference for JDK 1.4 style logging, I'll go with that, but would otherwise recommend we pick the 'better' logging solution to model ourselves after. (We must, of course, first agree upon which is the 'better' model.)

Aside from naming standards, what features do you see that should  be added?
 



 
Direct Access to Loggers
  • This is especially useful for widget loggers which may need to be manipulated at run time
  • However, this could certainly wait till a later release, after use cases have been flushed out
This would depend upon whether we can completely flush the call sites. As one of the big reasons we are creating a logging package is to maintain the zero cost logging messages when logging is turned off. 
That being said, given the awesome work Scott/Mathew have done for dead code stripping, it might be easier then I think to create instance loggers.

In the worst case, the getFooLogger() methods could return null, which client code could guard against, and use to conditionally execute logging related code. However, I also expect that we can avoid this, based on compiler optimizations, which would allows us to return instead a NullLogger with lots of empty implementation methods in it, which would cause client logging code to get compiled out. For initialization/configuration code with side-effects users could always guard with Log.isLoggingEnabled(), or widgetLogger.isLoggerEnabled().


So far, it seems like there is still code which is not killed, at least using my experiments,  however, if you see the discussion above, it might end up being worth it.



 
Number of compile time options
  • I like the simplified notion of logging either being turned on or off, with runtime log level filtering on top of that; it's much easier to explain and understand
  • Having a multitude of compile time log levels can always be added later (I do think we should leave the door open to this option), but could also be left to a specialized logging package, or an advanced how-to
I like this idea. One point that was made on a separate thread is that some programs want "severe" logging turned on at all time, which might make this feature come in sooner then expected.

For gwt-log I felt that the implementation burden of allowing  any of the log levels as compile time levels was low enough that this was worth doing. However, I  can also see the benefit of providing only two levels (on/off) for a core GWT logging solution, to encourage better programming practices. That is, rather than someone leaving SEVERE/ERROR/FATAL logging turned on for production, the developer is encouraged to handle these cases in a application-meaningful way. Having a SEVERE logging message popup in a widget logger, or on my firebug console, when I am in Gmail is probably not going to provide the best user experience. (Although, neither does 'Oops, error 767' :)

Hmm... That is yet another good point. I wonder if there is another solution still...
 
 

There are implementation differences we will need to consider, e.g.
  • The GWT tree logger would let you create two separate child trees, with logging messages separately going to each child tree, based on, say, category.
  • Firebug logger's group()/endGroup() only allows you to be logging at the end of the log tree, be it inside a group or not.
  • Other loggers may allow after-the-fact filtering/grouping to effectively separation/categorization 
This might actually be an argument for creating LogRecords, though we'd have to make sure they are completely compiled out at call sites. If we introduced LogRecords, then users could give LogRecords extra information.


        Cheers,

                 Emily

 

--
Fred Sauer
fr...@allen-sauer.com

Peter Blazejewicz

unread,
Feb 1, 2008, 7:36:16 PM2/1/08
to Google Web Toolkit Contributors
hi Fred,
> It's on the to-do this. [....]
as to console runtime degratation:
http://ajaxian.com/archives/graceful-degradation-of-firebug-console-object
http://paul.irish.aurgasm.us/2008/graceful-degredation-of-your-firebug-specific-code/

regards,
Peter

On Feb 1, 7:37 pm, "Fred Sauer" <f...@allen-sauer.com> wrote:
> Emily,
>
> On Feb 1, 2008 9:35 AM, Emily Crutcher <e...@google.com> wrote:
>
> > On Thu, Jan 31, 2008 at 6:58 PM, Fred Sauer <f...@allen-sauer.com> wrote:
>
> > > Firebug/Console Logging
>
> > > - Agree with John - It seems console.log() is commonly made
> > > available in JavaScript libraries.
> > > - I might suggest renaming the Firebug logger to, say, Console
> > > logger, and have the Firebug functionality degrade gracefully to
> > > console.log()
>
> > > That seems like a good idea. Do you think you might implement this? As
> > right now the plan is to use gwt-log's infrastructure for almost all this
> > functionality.
>
> It's on the to-do this. I currently have two separate loggers (i.e. firebug
> and console loggers). I need to at least disable the console logger when
> firebug(lite) is available (which is a one line code change), but I think it
> makes more sense to combine the two into a single logger with varying levels
> of integration with $wnd.console, depending on the browser and/or installed
> library or debugging facility. Over time, I also expect the
> browsers/libraries/frameworks to expand, and hopefully coalesce a bit around
> a common API, so I think some runtime detection at logger initialization
> will go a long ways here.
>
> GWT.log
>
>
>
> > > - Having GWT.log() as a target may be very useful was well
>
> > > I think I don't understand this comment, can you elaborate?
>
> I'm assuming that client code would call something like '
> org.google.gwt.log.client.Log.debug(.., ...)', and that module configuration
> (via deferred binding parameters) would then target the provided messages to
> various logger such as $wnd.console, System.err, RPC, Widget, etc. Having
> the option of these messages go to hosted mode tree logger is what I was
> proposing here.
>
> > Server Side Logging
>
> > > - I would almost argue this is a must-have, since that would be
> > > the only reasonable way to support logging in domain objects which are used
> > > on both client and server
>
> > > I could see that argument. It will be slightly awkward code, because
> > GWT.create will actually throw an error when run outside a GWT development
> > environment, but it does seem like a useful feature.
>
> I have this working in gwt-log with a bit of library magic, and I definitely
> think this is worth doing. Otherwise, I expect that the lack of a common
> logging API for both client and server is going to be a common struggling
> block.
>
>
>
> > JDK 1.4 vs log4j vs. Apache Commons
>
> > > - I don't know what the numbers are, both in terms of actual
> > > projects using a particular API, or actual developers familiar with one API
> > > or another, but, log4j has been around longer, and therefore may be
> > > accepted/known
> > > - I find JDK 1.4 logging to be a bit clumsy, although workable; I
> > > don't like their level names, or the default to only log SEVERE messages;
> > > plus, what is CONFIG anyway :)
> > > - I like log4j for its straight forward levels and diverse set of
> > > available appenders, so, I'd like to see the gwt API and levels modeled
> > > after log4j
>
> > > I like log4j as well, however my concern here is to create a API
> > familiar to the greatest number of our users, which seems like it is the
> > Java logging API. If you have data that would suggest otherwise, that would
> > be interesting to see.
>
> Maybe we could have a poll on GWT and GWTC (pinned?) to get an idea of the
> community thinks. Another option (slf4j does this), is to provide optional,
> API compatible, drop-in replacement for these logging libraries on the
> client side. (I'm not recommending this out of the gate, but might be an
> option to consider longer term if the community is really split down the
> middle on what to support.) In other words, while client code might write '
> org.apache.log4j.Logger.getLogger("...").debug(...)', GWT would provide an
> implementation of that API that would do everything we talked about here.
>
> If there is a strong community preference for JDK 1.4 style logging, I'll go
> with that, but would otherwise recommend we pick the 'better' logging
> solution to model ourselves after. (We must, of course, first agree upon
> which is the 'better' model.)
>
> > Direct Access to Loggers
>
> > > - This is especially useful for widget loggers which may need to
> > > be manipulated at run time
> > > - However, this could certainly wait till a later release, after
> > > use cases have been flushed out
>
> > > This would depend upon whether we can completely flush the call sites.
> > As one of the big reasons we are creating a logging package is to maintain
> > the zero cost logging messages when logging is turned off.
> > That being said, given the awesome work Scott/Mathew have done for dead
> > code stripping, it might be easier then I think to create instance loggers.
>
> In the worst case, the getFooLogger() methods could return null, which
> client code could guard against, and use to conditionally execute logging
> related code. However, I also expect that we can avoid this, based on
> compiler optimizations, which would allows us to return instead a NullLogger
> with lots of empty implementation methods in it, which would cause client
> logging code to get compiled out. For initialization/configuration code with
> side-effects users could always guard with Log.isLoggingEnabled(), or
> widgetLogger.isLoggerEnabled().
>
> > Number of compile time options
>
> > > - I like the simplified notion of logging either being turned on
> > > or off, with runtime log level filtering on top of that; it's much easier to
> > > explain and understand
> > > - Having a multitude of compile time log levels can always be
> > > added later (I do think we should leave the door open to this option), but
> > > could also be left to a specialized logging package, or an advanced how-to
>
> > > I like this idea. One point that was made on a separate thread is that
> > some programs want "severe" logging turned on at all time, which might make
> > this feature come in sooner then expected.
>
> For gwt-log I felt that the implementation burden of allowing any of the
> log levels as compile time levels was low enough that this was worth doing.
> However, I can also see the benefit of providing only two levels (on/off)
> for a core GWT logging solution, to encourage better programming practices.
> That is, rather than someone leaving SEVERE/ERROR/FATAL logging turned on
> for production, the developer is encouraged to handle these cases in a
> application-meaningful way. Having a SEVERE logging message popup in a
> widget logger, or on my firebug console, when I am in Gmail is probably not
> going to provide the best user experience. (Although, neither does 'Oops,
> error 767' :)
>
> > > - I also think loggers need to be able to be turned off at compile
> > > time; Instantiating the loggers with GWT.create(...) would allow
> > > users an easy way to replace any logger with a Null Logger
>
> > > Right now, the goal is that we have absolutely no class or method
> > invocations left so there should be no need for a Null Logger.
>
> I see the NullLogger as an implementation detail, providing a deferred
> binding 'replace-with' class: a logger with empty implementation methods
> that would all get compiled out.
>
> Grouping/Categories
>
>
>
> > > - I've seen multiple requests for both grouping (as in Firebug's
> > > console.group()), and categories (with different filters/levels by
> > > category)
>
> > > The way this is handled in the current design is that each handler has
> > an optional set of parameters supplied to it. Those parameters can be used
> > to specify group or category.
>
> There are implementation differences we will need to consider, e.g.
>
> - The GWT tree logger would let you create two separate child trees,
> with logging messages separately going to each child tree, based on, say,
> category.
> - Firebug logger's group()/endGroup() only allows you to be logging at
> the end of the log tree, be it inside a group or not.
> - Other loggers may allow after-the-fact filtering/grouping to
> effectively separation/categorization
>
> Questions:
>
> - Should the GWT logging solution provide only the lowest common
> denominator?
> - If not, how should each logging target degrade?
>
> > Widget Loggers
>
> > > - This may be a place where we'd want to make a user provided
> > > implementation plugable at compile time, as expect to see various
> > > specialized use cases
> > > - A simple GWT.create(...) could take care of this requirement
>
> > > Yes, I'm creating TreeHandler to test this requirement.. My hope is all
> > I need to do is guard the creation in a call to isLoggingEnabled()
>
> Sounds good.
>
> > Thanks for your great feedback!
>
> Thank you.
>
> --
> Fred Sauer
> f...@allen-sauer.com

Fred Sauer

unread,
Feb 4, 2008, 12:19:26 PM2/4/08
to Google-Web-Tool...@googlegroups.com
Emily,

On Feb 1, 2008 4:53 PM, Emily Crutcher <e...@google.com> wrote:
I would love to take a quick poll, from water-cooler discussions it seems like there are a sizable fraction of people who would like to see  java.util.logging.Logger  supported even though
 a) only some of the Logger methods would be supported
 b) there would be extra compiled overhead for creating and assigning null loggers in some cases.
 c) there would be a bit of extra overhead when logging, as we would have to create and introduce LogRecords (which are useful though) into the system.

Do you agree?

First, for the record:
 +1 log4j


Next, I want to briefly throw out he idea of mapped diagnostic context for people to consider:
  http://logback.qos.ch/manual/mdc.html
Should this be a part of a GWT loggingAPI?


In my opinion, having ANY runtime overhead when logging is turned off is a deal breaker. I'm willing to live a few extras bytes in the compiled code, and even with a few clock cycles of one time initialization code. But, if I put a log statement anywhere in my code, I don't want to see any of it left in the compiled JavaScript. Of course, I understand that in some cases I might need a 'if (Log.isFooEnabled()) {...}' guard. So, if log records cannot be made to work in this scenario, then I must vote to throw them out the door.


On Fri, Feb 1, 2008 at 1:37 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
On Feb 1, 2008 9:35 AM, Emily Crutcher <e...@google.com> wrote:
On Thu, Jan 31, 2008 at 6:58 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
Server Side Logging
  • I would almost argue this is a must-have, since that would be the only reasonable way to support logging in domain objects which are used on both client and server
I could see that argument. It will be slightly awkward code, because GWT.create will actually throw an error when run outside a GWT development environment, but it does seem like a useful feature.

I have this working in gwt-log with a bit of library magic, and I definitely think this is worth doing. Otherwise, I expect that the lack of a common logging API for both client and server is going to be a common struggling block.

How does it work? As that seems like a  cool technique.

A magician never reveals his tricks :). Seriously, though: In hosted mode I use two different byte code versions of the same classes. One is used by the JVM directly, via the same class loader tree which runs the servlets. The other is used by client code.


 
JDK 1.4 vs log4j vs. Apache Commons
  • I don't know what the numbers are, both in terms of actual projects using a particular API, or actual developers familiar with one API or another, but, log4j has been around longer, and therefore may be accepted/known
  • I find JDK 1.4 logging to be a bit clumsy, although workable; I don't like their level names, or the default to only log SEVERE messages; plus, what is CONFIG anyway :)
  • I like log4j for its straight forward levels and diverse set of available appenders, so, I'd like to see the gwt API and levels modeled after log4j
I like log4j as well, however my concern here is to create a API familiar to the greatest number of our users, which seems like it is the Java logging API. If you have data that would suggest otherwise, that would be interesting to see.

Maybe we could have a poll on GWT and GWTC (pinned?) to get an idea of the community thinks. Another option (slf4j does this), is to provide optional, API compatible, drop-in replacement for these logging libraries on the client side. (I'm not recommending this out of the gate, but might be an option to consider longer term if the community is really split down the middle on what to support.) In other words, while client code might write 'org.apache.log4j.Logger.getLogger("...").debug(...)', GWT would provide an implementation of that API that would do everything we talked about here. 

If there is a strong community preference for JDK 1.4 style logging, I'll go with that, but would otherwise recommend we pick the 'better' logging solution to model ourselves after. (We must, of course, first agree upon which is the 'better' model.)

Aside from naming standards, what features do you see that should  be added?

The author of log4j, Ceki Gülcü, has written up his critique on JDK logging here:
  http://www.jajakarta.org/log4j/jakarta-log4j-1.1.3/docs/critique.html

Of course, the full set of critiques, if you agree with them, really only apply in a JVM, and only if you are using the actual JDK logging implementation. Also, the impact of certain concerns can/could be eliminated by JVM optimizations.

Our own JDK-logging-inspired implementation wouldn't necessarily be affected by all the same issues. Things also become very different in web mode, with optimized JavaScript. However, I would imagine that if the gwt logging solution were to be modeled after JDK logging, then developers would likely be steered towards JDK logging on the server, and any JVM related concerns would have a real impact there.

Some log4j features I like:
  • Straight forward log levels: DEBUG, INFO, WARN, ERROR, FATAL
  • Low overhead at runtime
  • Large number of available appenders
  • Flexible pattern layout
  • Well-known, mature


--
Fred Sauer
fr...@allen-sauer.com

Emily Crutcher

unread,
Feb 4, 2008, 2:10:11 PM2/4/08
to Google-Web-Tool...@googlegroups.com
On Feb 4, 2008 12:19 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
Emily,

On Feb 1, 2008 4:53 PM, Emily Crutcher <e...@google.com> wrote:
I would love to take a quick poll, from water-cooler discussions it seems like there are a sizable fraction of people who would like to see  java.util.logging.Logger  supported even though
 a) only some of the Logger methods would be supported
 b) there would be extra compiled overhead for creating and assigning null loggers in some cases.
 c) there would be a bit of extra overhead when logging, as we would have to create and introduce LogRecords (which are useful though) into the system.

Do you agree?

First, for the record:
 +1 log4j
:-).
 

 



Next, I want to briefly throw out he idea of mapped diagnostic context for people to consider:
  http://logback.qos.ch/manual/mdc.html
Should this be a part of a GWT loggingAPI?

It seems like a nice feature for an add-on, but we were thinking for the core  logging API to have a relatively small and simple implementation .
 


In my opinion, having ANY runtime overhead when logging is turned off is a deal breaker. I'm willing to live a few extras bytes in the compiled code, and even with a few clock cycles of one time initialization code. But, if I put a log statement anywhere in my code, I don't want to see any of it left in the compiled JavaScript. Of course, I understand that in some cases I might need a 'if (Log.isFooEnabled()) {...}' guard. So, if log records cannot be made to work in this scenario, then I must vote to throw them out the door.

Agreed.
 



On Fri, Feb 1, 2008 at 1:37 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
On Feb 1, 2008 9:35 AM, Emily Crutcher <e...@google.com> wrote:
On Thu, Jan 31, 2008 at 6:58 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
Server Side Logging
  • I would almost argue this is a must-have, since that would be the only reasonable way to support logging in domain objects which are used on both client and server
I could see that argument. It will be slightly awkward code, because GWT.create will actually throw an error when run outside a GWT development environment, but it does seem like a useful feature.

I have this working in gwt-log with a bit of library magic, and I definitely think this is worth doing. Otherwise, I expect that the lack of a common logging API for both client and server is going to be a common struggling block.

How does it work? As that seems like a  cool technique.

A magician never reveals his tricks :). Seriously, though: In hosted mode I use two different byte code versions of the same classes. One is used by the JVM directly, via the same class loader tree which runs the servlets. The other is used by client code.

Wow, that really is magic!
 


 
JDK 1.4 vs log4j vs. Apache Commons
  • I don't know what the numbers are, both in terms of actual projects using a particular API, or actual developers familiar with one API or another, but, log4j has been around longer, and therefore may be accepted/known
  • I find JDK 1.4 logging to be a bit clumsy, although workable; I don't like their level names, or the default to only log SEVERE messages; plus, what is CONFIG anyway :)
  • I like log4j for its straight forward levels and diverse set of available appenders, so, I'd like to see the gwt API and levels modeled after log4j
I like log4j as well, however my concern here is to create a API familiar to the greatest number of our users, which seems like it is the Java logging API. If you have data that would suggest otherwise, that would be interesting to see.

Maybe we could have a poll on GWT and GWTC (pinned?) to get an idea of the community thinks. Another option (slf4j does this), is to provide optional, API compatible, drop-in replacement for these logging libraries on the client side. (I'm not recommending this out of the gate, but might be an option to consider longer term if the community is really split down the middle on what to support.) In other words, while client code might write 'org.apache.log4j.Logger.getLogger("...").debug(...)', GWT would provide an implementation of that API that would do everything we talked about here. 

If there is a strong community preference for JDK 1.4 style logging, I'll go with that, but would otherwise recommend we pick the 'better' logging solution to model ourselves after. (We must, of course, first agree upon which is the 'better' model.)

Aside from naming standards, what features do you see that should  be added?

The author of log4j, Ceki Gülcü, has written up his critique on JDK logging here:
  http://www.jajakarta.org/log4j/jakarta-log4j-1.1.3/docs/critique.html

Of course, the full set of critiques, if you agree with them, really only apply in a JVM, and only if you are using the actual JDK logging implementation. Also, the impact of certain concerns can/could be eliminated by JVM optimizations.

Our own JDK-logging-inspired implementation wouldn't necessarily be affected by all the same issues. Things also become very different in web mode, with optimized JavaScript. However, I would imagine that if the gwt logging solution were to be modeled after JDK logging, then developers would likely be steered towards JDK logging on the server, and any JVM related concerns would have a real impact there.

Some log4j features I like:
  • Straight forward log levels: DEBUG, INFO, WARN, ERROR, FATAL
  • Low overhead at runtime
  • Large number of available appenders
  • Flexible pattern layout
  • Well-known, mature

I see the appeal. If I was deciding on API alone I'd chose log4j.  My primary argument is that GWT is supplying the Java library classes, so to chose not to model logging on the Java logging classes would need very compelling reasons. 

When simply comparing the two systems Log4j has a nicer API. However, the documentation, ease of deployment, and simplicity of the java logging API makes it easier for casual users to learn. We really want to encourage casual users to use the logging API as that creates better application. 

         Cheers,

                  Emily


 

 

--
Fred Sauer
fr...@allen-sauer.com

Ray Cromwell

unread,
Feb 4, 2008, 3:57:00 PM2/4/08
to Google-Web-Tool...@googlegroups.com
I'll preface this by saying that I have been a log4j user since its
inception, and never used Java logging, nor commons-logging. For me,
any runtime impact is unacceptable, be it codesize or performance. I
am also a little sensitive to API bloat, I prefer KISS designs.

I really don't think the client logging design needs to have LogRecord
and probably not even categories. Those are more suitable for large
and long running apps, or fancy stuff like socket logging, or
Chainsaw-style log viewers, but I think GWT logging analysis may be
better done in a batch capture fashion. Launch the app, run your
tests, save the logs, and then post-process the logs. You could then
view the post-processed logs with a Chainsaw-style viewer as long as
there was sufficient information.

All of the runtime stuff of mapping categories to log levels and
appenders seems to me to be overly complex for GWT. My preference
would be for a simple design 'inspired' by log4j, and maybe a subset
of it.

-Ray

John Tamplin

unread,
Feb 4, 2008, 4:24:12 PM2/4/08
to Google-Web-Tool...@googlegroups.com
On Feb 4, 2008 3:57 PM, Ray Cromwell <cromw...@gmail.com> wrote:
I'll preface this by saying that I have been a log4j user since its
inception, and never used Java logging, nor commons-logging. For me,
any runtime impact is unacceptable, be it codesize or performance. I
am also a little sensitive to API bloat, I prefer KISS designs.

Personally I think tradeoffs need to be made given the current state of compiler optimizations.  I think a common idiom is to get a logger instance and store it in a static final instance variable, and then call methods on that.

If GWT.create returns a NullLogger instance, for example, if logging is disabled, then the compiler currently can remove all the invocations of it.  However, the static final field remains along with a stub assignment.  In that case, you are talking about a few bytes added to the compiled output executed once, and I think that is acceptable.  Future compiler work should be able to remove even that.
 
I really don't think the client logging design needs to have LogRecord
and probably not even categories. Those are more suitable for large
and long running apps, or fancy stuff like socket logging, or
Chainsaw-style log viewers, but I think GWT logging analysis may be
better done in a batch capture fashion. Launch the app, run your
tests, save the logs, and then post-process the logs. You could then
view the post-processed logs with a Chainsaw-style viewer as long as
there was sufficient information.

All of the runtime stuff of mapping categories to log levels and
appenders seems to me to be overly complex for GWT. My preference
would be for a simple design 'inspired' by log4j, and maybe a subset
of it.

The problem with "inspired by" is that you can't use common code for server and client logging.  If you have shared code and you want logging in that code, you will have a problem if you have different logging systems.

If we went with java.util.logging support, then no magic is required (beyond that which the compiler already does to use differetnt java.* classes for compiles) and shared code can work exactly the same.  Either a Logger instance is passed into some code, it has a way to get some shared Logger instance, or it calls java.util.logging.Logger.getLogger() to get one.  In the GWT code, getLogger() would do a GWT.create to return NullLogger, FineLogger, etc.  FineLogger would have null methods for finer and finest, delegators for fine, severe, etc, and log(Level level, ...) would have if(level < Logger.FINE) ... which the compiler can completely remove if the passed level is a constant (the common case), and work correctly if it is set dynamically.

Aside from the issue of how to transparently swap code for log4j, I am not sure that the compiler will be able to completely remove all traces of filtered log levels given the API.

So, for me, I think implementing that portion of java.util.logging which makes sense (for example, leaving out setLevel or else having a DynamicLogger implementation which does runtime-checks if we want to allow it), and then any code that uses that subset and is translatable can be shared freely between client and server and it will just work.  I agree the API isn't ideal, but then we use java.util.Date whose API isn't ideal for similar reasons.

Ray Cromwell

unread,
Feb 4, 2008, 5:26:22 PM2/4/08
to Google-Web-Tool...@googlegroups.com
On Feb 4, 2008 1:24 PM, John Tamplin <j...@google.com> wrote:
> The problem with "inspired by" is that you can't use common code for server
> and client logging. If you have shared code and you want logging in that
> code, you will have a problem if you have different logging systems.
...
This is not a problem as long as the implementation delegates, this is
exactly what the myriad of commons-logging like APIs do, dynamically
bind to log4j, java.util.logging, or others (SimpleLog)

> So, for me, I think implementing that portion of java.util.logging which
> makes sense (for example, leaving out setLevel or else having a
> DynamicLogger implementation which does runtime-checks if we want to allow
> it), and then any code that uses that subset and is translatable can be
> shared freely between client and server and it will just work.

I'm unclear about whether you are agreeing or not :) I was suggesting
that a subset, inspired by the full logging APIs, and this most
certainly would run in the server. In the second paragraph, you argue
for subsetting java.util.logging, while I was suggesting forming a
subset 'inspired' by log4j. I would actually prefer a KISS 'commons'
approach, in that the 'cloud safe' code uses some
com.google.gwt.logging package, which can delegate on the server to
your logging API of choice. If you use the actual
java.util.logging.Logger class, you run into not only supporting
setLevel, but also addHandler(), getResourceBundle(), etc. which
means stubbing them out, and making sure that developers know to not
call them in client code (not without precedent, e.g. Exception stack
traces)

As for the overhead of the static final field and initializer, yes,
that may be acceptable in small doses, but I think littering all of
your client translatable code with Loggers (the usual practice I see
in J2EE apps) may be asking for trouble. Remember, aggressive
subclassing of JSO was poo-pooed because it was inefficient, until the
new compiler and JSO design arrived. I think similar caution is
warranted when considering any new complex package being dropped into
GWT, especially one that encourages people to sprinkle it through
their entire codebase. We should atleast be very upfront with users
about the overhead.

-Ray

John Tamplin

unread,
Feb 4, 2008, 5:43:02 PM2/4/08
to Google-Web-Tool...@googlegroups.com
On Feb 4, 2008 5:26 PM, Ray Cromwell <cromw...@gmail.com> wrote:
On Feb 4, 2008 1:24 PM, John Tamplin <j...@google.com> wrote:
> The problem with "inspired by" is that you can't use common code for server
> and client logging.  If you have shared code and you want logging in that
> code, you will have a problem if you have different logging systems.
...
This is not a problem as long as the implementation delegates, this is
exactly what the myriad of commons-logging like APIs do, dynamically
bind to log4j,  java.util.logging, or others (SimpleLog)

But now your shared code has to use this new API, which means existing code has to change even if it was translatable before.  I agree that the myriad logging systems means that any choice is likely to require a certain subset of users will be unhappy.
 
I'm unclear about whether you are agreeing or not :)  I was suggesting
that a subset, inspired by the full logging APIs, and this most
certainly would run in the server. In the second paragraph, you argue
for subsetting java.util.logging, while I was suggesting forming a
subset 'inspired' by log4j. I would actually prefer a KISS 'commons'
approach, in that the 'cloud safe' code uses some
com.google.gwt.logging package, which can delegate on the server to
your logging API of choice.  If you use the actual
java.util.logging.Logger class, you run into not only supporting
setLevel, but also addHandler(), getResourceBundle(), etc.  which
means stubbing them out, and making sure that developers know to not
call them in client code (not without precedent, e.g. Exception stack
traces)

Right, but we have a long history of that in java.* classes anyway.  Eventually, IDE plugins will help here.

I would like to maximize the cases where existing code can be used unchanged.  We need some magic to swap out implementations on the client and server, and we already have that in place for java.*.  I think we can support the commonly used subset of java.util.logging so existing code can work without modification and we can achieve zero overhead in the logging disabled case.

So I guess I am agreeing with the general sentiment of your proposal but disagreeing with the specific suggestion :).
 
As for the overhead of the static final field and initializer, yes,
that may be acceptable in small doses,  but I think littering all of
your client translatable code with Loggers (the usual practice I see
in J2EE apps) may be asking for trouble.  Remember, aggressive
subclassing of JSO was poo-pooed because it was inefficient, until the
new compiler and JSO design arrived. I think similar caution is
warranted when considering any new complex package being dropped into
GWT, especially one that encourages people to sprinkle it through
their entire codebase. We should atleast be very upfront with users
about the overhead.

It depends on the final API what can be achieved there -- for example, if you have an addHandler() interface and the client code actually calls it, I believe there is currently no way around leaving clinit calls at each call site (if you support addHandler() but don't use it, then it can be removed entirely).  I agree that we have to be very cautious about what is supported, but if you disallow dynamic levels (or only support them with a deferred binding target of "dynamic") then I believe with logging off there can be exactly zero overhead -- intermediate levels would likely be stuck with the extra object creations.  To me, that is acceptable if you pay nothing at all when it is completely turned off, even if the overhead is larger than ideal for some other situations.

Ray Cromwell

unread,
Feb 4, 2008, 5:56:18 PM2/4/08
to Google-Web-Tool...@googlegroups.com
I agree. As long as you don't pay for runtime use when it's off, I'm
ok with it, because I can work around issues of static final
initializers, or simply not go hog wild spreading loggers everywhere.
I would get concerned if gwt-user.jar got overly polluted with loggers
which were adding non-trivial bloat in size to my compiled app. :)

-Ray

Fred Sauer

unread,
Feb 4, 2008, 6:01:54 PM2/4/08
to Google-Web-Tool...@googlegroups.com
I would add, that, *if* we were to end up agreeing that, say, log4j was better/preferable than JDK logging, then we could do exactly the same thing: replace org.apache.log4j.* implementations just you would java.util.*.

--
Fred Sauer
fr...@allen-sauer.com

John Tamplin

unread,
Feb 4, 2008, 6:17:51 PM2/4/08
to Google-Web-Tool...@googlegroups.com
On Feb 4, 2008 6:01 PM, Fred Sauer <fr...@allen-sauer.com> wrote:
I would add, that, *if* we were to end up agreeing that, say, log4j was better/preferable than JDK logging, then we could do exactly the same thing: replace org.apache.log4j.* implementations just you would java.util.*.

Yes, other than it would have to be done where java.* already works.

However, i am not convinced the log4j API can be made to be zero overhead.  I haven't actually tried to do it, and there may be games to play with lazy initialization that makes it work, but off the top of my head it looks complicated enough that there will be some runtime penalty.

Emily Crutcher

unread,
Feb 4, 2008, 6:41:42 PM2/4/08
to Google-Web-Tool...@googlegroups.com
This is actually why I like the static API, as then we don't need to tell people how to use  logging without causing code bloat, it happens automatically. Though I do think Fred had a good point about categories being useful, though it seems like a string category might be sufficient, and static final strings should go away I believe, though I will have to test...

Also, I'm not convinced that for shared code you wouldn't want an adapter anyway. As your logging needs when running code in hosted mode or web mode are different then your needs when you are running that same code on the server.  

John Tamplin

unread,
Feb 4, 2008, 6:46:30 PM2/4/08
to Google-Web-Tool...@googlegroups.com
On Feb 4, 2008 6:41 PM, Emily Crutcher <e...@google.com> wrote:
This is actually why I like the static API, as then we don't need to tell people how to use  logging without causing code bloat, it happens automatically. Though I do think Fred had a good point about categories being useful, though it seems like a string category might be sufficient, and static final strings should go away I believe, though I will have to test...

That answer is simple -- set the logging property to "off"/"null"/whatever you want to call it -- zero overhead.  Regarding overhead when you have it turned on,  I think that is less of an issue and those that care can read the documentation to see how to make sure there is minimal impact where it isn't going to be used.
 
Also, I'm not convinced that for shared code you wouldn't want an adapter anyway. As your logging needs when running code in hosted mode or web mode are different then your needs when you are running that same code on the server.  

What is different about them?

If I call logger.fine("Warning, array size has grown to " + size) in my data object, how do I want that to be handled differently when in the server code vs on the client with logging enabled?

Henri Karapuu

unread,
Feb 5, 2008, 2:52:16 AM2/5/08
to Google Web Toolkit Contributors
> I really don't think the client logging design needs to have LogRecord
> and probably not even categories. Those are more suitable for large
> and long running apps

Categories are cornerstone of logging, and critically important when
logging is used as alternative for running a debugger: if there is no
support for categories and per-category log level you can not drill
down to the finer level log messages of problem area without drowning
in messages from other areas.

Also consider the requirement that the same logging API must also work
when the code is executed in server (for shared code use). If the api
does not support categories, that also means no categories in the
server side for shared code, which probably is simply unacceptable for
many.

I believe that leaving out category concept entirely would lead to
significantly lower adaptation of the logging API. Certainly for me it
would be useless.

OTOH, i think that simple constant string based categories are
acceptable compromise, and they could be made even optional. And the
per-category levels don't need to affect compilation; they are needed
mainly for debuggin so a basic run time filtering should be ok.

/Henri Karapuu

John Tamplin

unread,
Feb 5, 2008, 3:06:46 AM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 2:52 AM, Henri Karapuu <hkar...@gmail.com> wrote:

> I really don't think the client logging design needs to have LogRecord
> and probably not even categories. Those are more suitable for large
> and long running apps

Categories are cornerstone of logging, and critically important when
logging is used as alternative for running a debugger: if there is no
support for categories and per-category log level you can not drill
down to the finer level log messages of problem area without drowning
in messages from other areas.

Also consider the requirement that the same logging API must also work
when the code is executed in server (for shared code use). If the api
does not support categories, that also means no categories in the
server side for shared code, which probably is simply unacceptable for
many.
 
Remember that GWT's requirements are rather different -- here we care most about code size, both from the added logging code and the implications that has to the optimizer.  For logging to be useful in GWT, it needs to have exactly zero overhead on the generated code when turned off.  Having lots of different levels for different categories is not really suitable for choosing the log level at compile time using generators (and then choosing the proper script to be run depending on whether you want logging or not), as the number of permutations would become unmanageable and the set of categories would have to be known at compile time.  So, the only way categories can be supported like you want is to have a dynamic logger binding, at which point all the logging code is present in every location because you don't know the log level at compile time.  This may be necessary and useful for some situations, but it will add so much bloat it will likely not be acceptable for use in production code by anyone and the resulting differences in the compiled output may result in changes in the errant behavior by turning logging on, which would defeat the purpose.

You aren't going to want huge amounts of log output from a web app in any case -- the browsers simply don't provide a useful way of wading through lots of data and the logging will definitely impact performance.

Henri Karapuu

unread,
Feb 5, 2008, 3:20:40 AM2/5/08
to Google Web Toolkit Contributors
> In the second paragraph, you argue
> for subsetting java.util.logging, while I was suggesting forming a
> subset 'inspired' by log4j

I think for server side use the most important thing is that the log
messages can be ultimately directed to whatever logging system the
server side already uses (otherwise we would end up with two different
sets of log files).

The exact API that we program against is secondary concern, but
Commons Logging seems to be the most used solution.

Also, Commons Logging has the benefit that it is already a 'delegating
bridge', instead of actual logging system, and would thus enable the
critical requirement of directing logs to the same system that rest of
the server side uses (be it jdk logging or log4j) without any
additional effort.

/Henri Karapuu

Henri Karapuu

unread,
Feb 5, 2008, 3:32:58 AM2/5/08
to Google Web Toolkit Contributors
> For logging to be useful in GWT, it needs to have
> exactly zero overhead on the generated code when turned off. Having lots of
> different levels for different categories is not really suitable for
> choosing the log level at compile time using generators

I think it would be perfectly acceptable that the log compilation is
on/off switch, and the category and level-per-category facilities are
only runtime filtering in the client, mainly used when the developer
debugs the application, be it in hosted or web mode.

I think that should not add much if any overhead?

Also please consider the arguments for situation where shared code
runs in server -- if there are no categories in the api, it would mean
no categories for logs even in production servers!

/Henri Karapuu

Ray Cromwell

unread,
Feb 5, 2008, 3:46:30 AM2/5/08
to Google-Web-Tool...@googlegroups.com
I see two main uses for categories: One is to assign log levels to
categories so that a bunch of logging statements can have their log
levels and msgs routed en masse at runtime. e.g. use your IDE to
connect to a running app, and change org.foo.FooImpl from NONE to
DEBUG and route to FooAppender. The second, is to assist UI
navigation in drilling down on massive volumes of log data.

I think the latter can be easily handled by a String identifier,
because offline tools can easily process such files, as long as the
format of the fields in each log entry is consistent, (e.g.
Timestamp,Level, Identifier, Msg)

The former case, of controlling log levels during runtime I think is
not as useful for GWT and is much more applicable to long running
apps. I can see a need for it in some cases (e.g. DEBUG/TRACE
generates a bazillion msgs, so numerous it will kill the browser, so
you only want to TRACE class Bar) Still, I think this is the exception
and not the rule.

Henri Karapuu

unread,
Feb 5, 2008, 4:15:25 AM2/5/08
to Google Web Toolkit Contributors
On Feb 5, 10:46 am, "Ray Cromwell" <cromwell...@gmail.com> wrote:
> The second, is to assist UI navigation in drilling down on massive volumes of log data.
>
> I think the latter can be easily handled by a String identifier,
> because offline tools can easily process such files, as long as the
> format of the fields in each log entry is consistent, (e.g.
> Timestamp,Level, Identifier, Msg)

Well, we could think category support as just a build-in way to add
that String identifier, plus a build-in way to filter out certain
messages based on that identifier.

My point is that the support for this should be build-in. Otherwise
half of the users will make their own wrappers and handling for the
string identifiers, which will lead to a lot of wasted effort, and
make the home-brew 'category extensions' incompatible with each other
and thus cause problems in code re-use between different projects.

Also, the string identifier filtration in just off-line tools is not
what i'm really after. The filtration should be done at early stage,
so that it would work with all log outputs, from GWT's shell debug
window in hosted mode to html panel output in web mode to physical log
file in server side etc.

/Henri Karapuu

John Tamplin

unread,
Feb 5, 2008, 11:00:45 AM2/5/08
to Google-Web-Tool...@googlegroups.com
Ok, given recent posts it seems obvious there will be no existing solution everyone can agree on, so I retract my suggestion of implementing java.util.logging and agree with Emily and Ray (and maybe others) that we should inconvenience everyone equaly and suggest:
  • create a new API for GWT and shared code optimized/limited to our needs
  • the server side would not do any logging itself but delegate to any of the popular logging solutions, configurable in some way
  • client side would support categories but not different log levels per category, but on the server side they could if the underlying log system supported it
  • client side API would have zero overhead if turned off, small one-use overhead (ie, object allocation) is acceptable for other debug levels but must still have zero overhead at filtered call sites
Comments?

Fred Sauer

unread,
Feb 5, 2008, 11:24:37 AM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 9:00 AM, John Tamplin <j...@google.com> wrote:
Ok, given recent posts it seems obvious there will be no existing solution everyone can agree on, so I retract my suggestion of implementing java.util.logging and agree with Emily and Ray (and maybe others) that we should inconvenience everyone equaly and suggest:
  • create a new API for GWT and shared code optimized/limited to our needs
  • the server side would not do any logging itself but delegate to any of the popular logging solutions, configurable in some way
  • client side would support categories but not different log levels per category, but on the server side they could if the underlying log system supported it
I don't see why we couldn't add client side *runtime* support for different log levels by category as well.

 
  • client side API would have zero overhead if turned off, small one-use overhead (ie, object allocation) is acceptable for other debug levels but must still have zero overhead at filtered call sites
Comments?


--
John A. Tamplin
Software Engineer, Google




--
Fred Sauer
fr...@allen-sauer.com

Emily Crutcher

unread,
Feb 5, 2008, 11:36:58 AM2/5/08
to Google-Web-Tool...@googlegroups.com
This seems like a very nice summary.

Henri Karapuu

unread,
Feb 5, 2008, 11:41:31 AM2/5/08
to Google Web Toolkit Contributors
> - client side would support categories but not different log levels
> per category

I don't see point in having categories if they don't have individually
configurable levels (the category would not be much more than prefix
for the log message).

But, I think the real use cases (increased logging of specific problem
areas at development time) can be satisfied just fine with runtime
filtering. The per category levels would not need to have any effect
on the compile time behavior or optimizations, simply some messages
would be skipped based on category/level combination at runtime. Or am
i again missing something? :)

Besides of that, the presented compromises sound good.

/Henri Karapuu

Emily Crutcher

unread,
Feb 5, 2008, 11:49:10 AM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 11:24 AM, Fred Sauer <fr...@allen-sauer.com> wrote:

On Feb 5, 2008 9:00 AM, John Tamplin <j...@google.com> wrote:
Ok, given recent posts it seems obvious there will be no existing solution everyone can agree on, so I retract my suggestion of implementing java.util.logging and agree with Emily and Ray (and maybe others) that we should inconvenience everyone equaly and suggest:
  • create a new API for GWT and shared code optimized/limited to our needs
  • the server side would not do any logging itself but delegate to any of the popular logging solutions, configurable in some way
  • client side would support categories but not different log levels per category, but on the server side they could if the underlying log system supported it
I don't see why we couldn't add client side *runtime* support for different log levels by category as well.

I think as long as we have a declarative UI, this should be possible, i.e.
Log.setCategoryLevel(category, Level.WARN);
 
 


 
  • client side API would have zero overhead if turned off, small one-use overhead (ie, object allocation) is acceptable for other debug levels but must still have zero overhead at filtered call sites
Comments?


--
John A. Tamplin
Software Engineer, Google




--

Ray Cromwell

unread,
Feb 5, 2008, 11:57:21 AM2/5/08
to Google-Web-Tool...@googlegroups.com
I hope wasn't misunderstood. I'm not completely opposed to the
java.util.logging idea, I was just concerned about it's apparent
'heavy' nature and conceptual weight (I tend to prefer simple APIs). I
think if these fears were alleviated, I'd be mostly ambivalent whether
it was com.google.gwt or j.u.logging. On the plus side, j.u.logging
could be added to the official list of JRE Emul classes. :) The
benefit of designing your own API from scratch is it seems you can
control the conceptual weight and performance characteristics more
deterministically vs implementing an existing API for the first time.

-Ray

John Tamplin

unread,
Feb 5, 2008, 12:00:25 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 11:57 AM, Ray Cromwell <cromw...@gmail.com> wrote:

 I hope wasn't misunderstood. I'm not completely opposed to the
java.util.logging idea, I was just concerned about it's apparent
'heavy' nature and conceptual weight (I tend to prefer simple APIs). I
think if these fears were alleviated, I'd be mostly ambivalent whether
it was com.google.gwt or j.u.logging. On the plus side, j.u.logging
could be added to the official list of JRE Emul classes. :)  The
benefit of designing your own API from scratch is it seems you can
control the conceptual weight and performance characteristics more
deterministically vs implementing an existing API for the first time.

No, but when different people think different packages are the most commonly used or most important, then it seems like there will be no consensus on which to base our logging on.  So, the only way to move forward ina reasonable time is to just say that isn't something we care about and design something that exactly meets our needs rather than something that can be made to fit our needs.  Aside from that, I don't believe any of the APIs besides java.util.logging could be implemented client-side with the zero-overhead requirements, so if it isn't going to be based on that one we need to create our own anyway.

John Tamplin

unread,
Feb 5, 2008, 12:20:57 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 11:41 AM, Henri Karapuu <hkar...@gmail.com> wrote:

>    - client side would support categories but not different log levels
>    per category

I don't see point in having categories if they don't have individually
configurable levels (the category would not be much more than prefix
for the log message).

The point is that the different levels for GWT will be done at compile time with different deferred bindings.  This way, there is exactly zero overhead at the call site for log messages that do not meet the filtering criteria (subject to the usual caveat of wrapping expensive side-effect code in an if(isLoggable...) block).  Extending the log levels to per-category means that you now have an additional factor of n x m permutations (n=log levels, m=categories) on top of however many permutations you have for localization and browser differences, which will quickly lead you into multi-hour compiles and a real hassle of trying to choose the proper script to run.

I realize there is a use case for dyanmically setting log levels, and in that case it could be per-category since you are going to be stuck with the overhead of having the logging code present at all call sites and the runtime tests rather than doing at compile time so the extra cost is negligible.  I could see having a "dynamic" deferred binding target for loglevel that produced that, but then the problem is what do you do with the ability to set dynamic levels for the staticly bound loggers?  It is conceivable that the API could be structured in such a way that it made sense for that to be ignored, but it isn't clear to me how to arrange that at present.
 
But, I think the real use cases (increased logging of specific problem
areas at development time) can be satisfied just fine with runtime
filtering. The per category levels would not need to have any effect
on the compile time behavior or optimizations, simply some messages
would be skipped based on category/level combination at runtime. Or am
i again missing something? :)

I think I explain that above.  As an example, assuming loglevel=severe as a deferred binding property:

a;
logger.warn("This is a warning message");
b;
logger.severe("Severe error");
if(logger.isLoggable(Level.TRACE)) {
  // a lot of code to generate some trace message
  logger.log(...);
}
c;

Would get compiled exactly as:

a;
b;
Logger_severe("Severe error");  // compiler de-virtualizes call, which means this can be inlined depending on complexity
c;

If you have dynamically configurable levels, whether settable for categories or not:

a;
if (logger.currentLevel >= Level.WARN) {
  logger.log("warning message");
}
b;
if (logger.currentLevel >= Level.SEVERE) {
  logger.log("Severe error");
}
if(logger.currentLevel >= Level.TRACE) {
  // a lot of code to generate some trace message
  logger.log(...);
}
c;

And the size of your code, as well as its execution time, balloons even if you have logging turned off for everything.  This is why, for all but temporary debugging support (in which case a debugger with conditional breakpoints is almost certainly better), I don't see dynamic log levels, whether for individual categories or not, being useful for GWT apps.  As discussed above, I don't think it is feasible to support per-category log levels statically, so that means to me that per-category log levels are not useful on the client.

John Tamplin

unread,
Feb 5, 2008, 12:21:59 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 11:24 AM, Fred Sauer <fr...@allen-sauer.com> wrote:
I don't see why we couldn't add client side *runtime* support for different log levels by category as well.

See the response to Henri about the same thing.

John Tamplin

unread,
Feb 5, 2008, 12:23:11 PM2/5/08
to Google-Web-Tool...@googlegroups.com
Forgot to mention, my suggestion for handling different client/server code is to put the server code in a new location, and at build time it gets stuck into the gwt-servlet.jar which already needs to be present for the server code.

Fred Sauer

unread,
Feb 5, 2008, 12:39:34 PM2/5/08
to Google-Web-Tool...@googlegroups.com
John,

If the *compile time* log level is SEVERE, then you can reduce the compiled output to:
  a;

  b;
  if (logger.currentLevel >= Level.SEVERE) {
    logger.log("Severe error");
  }
  c;

In order to do this with today's compiler, you may have to replace tests like "logger.currentLevel >= Level.WARN" with "logger.isWarnEnabled()", which would have the deferred binding implementation of "return false" when the compile time log level is SEVERE.


--
Fred Sauer
fr...@allen-sauer.com

Ray Cromwell

unread,
Feb 5, 2008, 1:10:17 PM2/5/08
to Google-Web-Tool...@googlegroups.com
My 2 cents is that while it is possible to use deferred binding for
all of the log levels, I think the better sweet spot is simply ON/OFF
(statically w/deferred binding), and use dynamic checks when logging
is on. It's my expectation that production mode apps will use a
NullLogger with no logging compiled in of any kind. DB will remove
callsite log calls for the other log levels, but you still end up with
the whole logging apparatus and support classes compiled into your app
for the levels that are on. I know people imagine handling exceptions
and logging WARN/ERROR even in production apps, but IMHO, it's much
better to handle these with a user visible error feedback.

-Ray

Emily Crutcher

unread,
Feb 5, 2008, 1:25:24 PM2/5/08
to Google-Web-Tool...@googlegroups.com
I think the current plan is to support both use cases, as there are big projects that have told us they'd like to use one or the other, so we'd have the following deferred binding:


logging:on -- logging is supported, all logging statements are compiled in. Initial logging level is WARN unless overridden by a logging URL argument.

logging:off -- no logging support
logging:production -- SEVERE logging messages are compiled in.   Logging level is set to SEVERE.  No URL logging level argument support. Logging levels can still be set in code. 

John Tamplin

unread,
Feb 5, 2008, 1:27:42 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 1:10 PM, Ray Cromwell <cromw...@gmail.com> wrote:
 My 2 cents is that while it is possible to use deferred binding for
all of the log levels, I think the better sweet spot is simply ON/OFF
(statically w/deferred binding), and use dynamic checks when logging
is on.  It's my expectation that production mode apps will use a
NullLogger with no logging compiled in of any kind. DB will remove
callsite log calls for the other log levels, but you still end up with
the whole logging apparatus and support classes compiled into your app
for the levels that are on.  I know people imagine handling exceptions
and logging WARN/ERROR even in production apps, but IMHO, it's much
better to handle these with a user visible error feedback.

I think a common use case will be to leave severe (or whatever you call it) logging enabled in production, and I think we need to make sure that is as low-impact as possible.  I think for that case, it needs to be done entirely at compile time.  There can be other deferred binding targets which support dynamic levels, but I think the static option needs to be available.

Regarding the number of permutations, I like Fred's suggestion of two deferred binding targets (none/all or whatever names you like) but the generator understands others so you can add extends-property lines in your module file if you want the intermediate levels.  Extending that idea we can support whatever mix of functionality we want in the generator and have a separate discussion about which levels are provided by default.

Ray Cromwell

unread,
Feb 5, 2008, 1:35:26 PM2/5/08
to Google-Web-Tool...@googlegroups.com
"extends-property lines in your module file if you want the intermediate levels"

Perfect.

John Tamplin

unread,
Feb 5, 2008, 2:08:22 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 1:25 PM, Emily Crutcher <e...@google.com> wrote:
I think the current plan is to support both use cases, as there are big projects that have told us they'd like to use one or the other, so we'd have the following deferred binding:


logging:on -- logging is supported, all logging statements are compiled in. Initial logging level is WARN unless overridden by a logging URL argument.

If you only support the logging level via the URL, then this is a static deferred binding option, right?
 
logging:off -- no logging support
logging:production -- SEVERE logging messages are compiled in.   Logging level is set to SEVERE.  No URL logging level argument support. Logging levels can still be set in code. 

Can the logging levels be set lower than severe, or is that only to basically turn off logging at runtime?  If the former, you will have massive overhead for simply building with logging turned on, and in the latter case I am not sure of the use case for having the code present but only allowing severe logs to be turned on or off at runtime.

Ian Petersen

unread,
Feb 5, 2008, 2:15:01 PM2/5/08
to Google-Web-Tool...@googlegroups.com
Regarding the interplay between statically-determined logging levels
and categories with different levels, what about the equivalent of
log4j.xml?

My thoughts here are only half-formed, and I'm not entirely sure if it
would be useful to anyone, but I thought I'd throw it out there
anyway. People seem to want categories to aid in filtering log
output, but there is some pushback because implementing different log
levels on different categories seems to stymie static dead code
removal. What if there was a configuration file, similar to
log4j.xml, that specifies the category log levels and is read at
compile time? Would this be useful? Would it permit the static dead
code removal that seems to be a top priority? Is it too complex for a
first pass?

Ian

--
Tired of pop-ups, security holes, and spyware?
Try Firefox: http://www.getfirefox.com

John Tamplin

unread,
Feb 5, 2008, 2:22:03 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 2:15 PM, Ian Petersen <ispe...@gmail.com> wrote:
Regarding the interplay between statically-determined logging levels
and categories with different levels, what about the equivalent of
log4j.xml?

My thoughts here are only half-formed, and I'm not entirely sure if it
would be useful to anyone, but I thought I'd throw it out there
anyway.  People seem to want categories to aid in filtering log
output, but there is some pushback because implementing different log
levels on different categories seems to stymie static dead code
removal.  What if there was a configuration file, similar to
log4j.xml, that specifies the category log levels and is read at
compile time?  Would this be useful?  Would it permit the static dead
code removal that seems to be a top priority?  Is it too complex for a
first pass?

I don't think that would fit in with deferred binding very well -- you would now have the set of permutations determined by an external xml file instead of contained just in your module.  I guess you could have one permutation defined which means to read the xml file to get the per-category levels, but you still get into messy issues such as if the category can't be determined at compile time (ie, log(obj.logCategory, log.WARN, msg)) which would then require that code be generated to store all the log levels in the output JS and the code to interact with them.  We could restrict the category to a constant, but what if you wanted a constant expression?  It seems a very slippery slope with a lot of complication for little benefit.

Fred Sauer

unread,
Feb 5, 2008, 3:00:35 PM2/5/08
to Google-Web-Tool...@googlegroups.com

Putting larger and more complex applications aside for a moment (since those folks can dig through the fine print and determine what the optimal solution is for them), I think the use cases we should be optimizing for include 1) production apps, and 2) people starting to use logging for the first time or just casually logging.

With this in mind, I'd like to see:
  1. Out of the box (e.g. in a default project), no increase in compile time
    • => a single default deferred binding value (so there are no additional deferred binding combinations)
  2. Encourage developers to 'do the right thing' in terms of handling the unexpected in the user interface
    • => discourage the use of logging in production
    • => don't have a default of 'SEVERE'
  3. When logging is 'turned on', then by default all logging levels should produce output. I lot of folks are going to write Log.debug(...) and expect there to be output
    • => don't have a default of 'WARN'
    • => logging turned on should equate to 'FINEST' (or whatever is the lowest level)
  4. Larger projects get additional control over compile time log levels
    • => support additional levels via extend-property


...which means....

On Feb 5, 2008 12:08 PM, John Tamplin <j...@google.com> wrote:
On Feb 5, 2008 1:25 PM, Emily Crutcher <e...@google.com> wrote:
I think the current plan is to support both use cases, as there are big projects that have told us they'd like to use one or the other, so we'd have the following deferred binding:


logging:on -- logging is supported, all logging statements are compiled in. Initial logging level is WARN unless overridden by a logging URL argument.

If you only support the logging level via the URL, then this is a static deferred binding option, right?

I'd prefer DEBUG/FINEST (or whatever is the lowest) instead of WARN for the beginner trying to get Log.debug(....) to just work.




logging:off -- no logging support
ok

 
logging:production -- SEVERE logging messages are compiled in.   Logging level is set to SEVERE.  No URL logging level argument support. Logging levels can still be set in code. 

I'd prefer we omit this last option, so that we discourage the use of logging as a production solution to unexpected runtime problems. Those problems should be addressed differently in the UI, in an application reasonable way. Production should mean logging turned off.



Can the logging levels be set lower than severe, or is that only to basically turn off logging at runtime?  If the former, you will have massive overhead for simply building with logging turned on, and in the latter case I am not sure of the use case for having the code present but only allowing severe logs to be turned on or off at runtime.

I would expect to be able to adjust the runtime log level as follows:
    compile time level <= run time level <= OFF
i.e. you can always reduce the amount of logging at run time.


In any case it should be understood that there is additional overhead when any type of compile time logging is enabled. Adjusting the runtime log level is only a means of temporarily throttling messages for the purpose of easier debugging during development. I think we can reinforce this by, for example, generating a log message to indicate any change in runtime log level.

Suppose a developer were to set the compile time level to 'FINEST', but then thought all they needed to do for production was to set the runtime level to OFF (via say Log.setCurrentLogLevel(OFF) in onModuleLoad()). By always emitting a message like 'Log level changed to ....', the developer could not be lulled into thinking that logging was somehow actually completely turned off.

(Actually, for the specific case when the runtime level is set to 'OFF', it might not hurt to spit out another message with information on how to properly turn logging off in production.)


--
Fred Sauer
fr...@allen-sauer.com

Emily Crutcher

unread,
Feb 5, 2008, 3:33:48 PM2/5/08
to Google-Web-Tool...@googlegroups.com

I'd prefer DEBUG/FINEST (or whatever is the lowest) instead of WARN for the beginner trying to get Log.debug(....) to just work.

I see your point,  but as a developer I would want to easily add messages that do not show up by default.  Maybe though setting the levels at CONFIG then documenting FINE and FINEST might be better then starting them at WARN...

 





logging:off -- no logging support
ok

 
logging:production -- SEVERE logging messages are compiled in.   Logging level is set to SEVERE.  No URL logging level argument support. Logging levels can still be set in code. 

I'd prefer we omit this last option, so that we discourage the use of logging as a production solution to unexpected runtime problems. Those problems should be addressed differently in the UI, in an application reasonable way. Production should mean logging turned off.

Unfortunately we know of some applications that are waiting for this library that do not agree with you.  They plan to also do something intelligent in the UI, but want to use the RPC handlers they are already going to have set up to actually log the error.

 




Can the logging levels be set lower than severe, or is that only to basically turn off logging at runtime?  If the former, you will have massive overhead for simply building with logging turned on, and in the latter case I am not sure of the use case for having the code present but only allowing severe logs to be turned on or off at runtime.

I would expect to be able to adjust the runtime log level as follows:
    compile time level <= run time level <= OFF
i.e. you can always reduce the amount of logging at run time.


In any case it should be understood that there is additional overhead when any type of compile time logging is enabled. Adjusting the runtime log level is only a means of temporarily throttling messages for the purpose of easier debugging during development. I think we can reinforce this by, for example, generating a log message to indicate any change in runtime log level.

Suppose a developer were to set the compile time level to 'FINEST', but then thought all they needed to do for production was to set the runtime level to OFF (via say Log.setCurrentLogLevel(OFF) in onModuleLoad()). By always emitting a message like 'Log level changed to ....', the developer could not be lulled into thinking that logging was somehow actually completely turned off.

(Actually, for the specific case when the runtime level is set to 'OFF', it might not hurt to spit out another message with information on how to properly turn logging off in production.)

This seems like a very good idea.

 

--

Ray Cromwell

unread,
Feb 5, 2008, 4:14:36 PM2/5/08
to Google-Web-Tool...@googlegroups.com
This begs the question as to whether or not the provider code will be
omitted from the selection script when it is unused (if logging =
production). I just looked at the SelectionScriptGenerator to verify,

private void genPropProviders(PrintWriter pw) {
for (Iterator iter = moduleProps.iterator(); iter.hasNext();) {
Property prop = (Property) iter.next();
String activeValue = prop.getActiveValue();
if (activeValue == null) {
// Emit a provider function, defined by the user in module config.
PropertyProvider provider = prop.getProvider();
...

Which seems to say that yes, it is omitted.

-Ray

Fred Sauer

unread,
Feb 5, 2008, 4:40:32 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 1:33 PM, Emily Crutcher <e...@google.com> wrote:
I'd prefer DEBUG/FINEST (or whatever is the lowest) instead of WARN for the beginner trying to get Log.debug(....) to just work.

I see your point,  but as a developer I would want to easily add messages that do not show up by default.  Maybe though setting the levels at CONFIG then documenting FINE and FINEST might be better then starting them at WARN...

My first take on it is this:
  • Day one, I start to use logging.
    • Of all the Log.debug()/warn()/info()/error()/trace()/whatever() methods, which am I most likely to use? I would think it would be Log.debug(). If I get no output before the default is WARN, then I'm a bit confused.
    • I'm not going to have a lot of debug statements out of the box, so I don't mind seeing everything
  • Day three, I'm starting to do a lot more logging and now I'm thinking about actually using the different levels and about throttling back from 'show be everything'
    • This is where your "but as a developer I would want to easily add messages that do not show up by default" comes in

I'll admit there is a flip side:
  • If I inherit a module/library that does a lot of logging, I would be overwhelmed if by default the l saw everything
  • If GWT core did a lot of low level logging, I wouldn't want to see that by default either



This whole 'libraries/modules with their own logging code' issue does make be reconsider the notion of categories or some kind of separation of logging control. What if instead of categories we used a different deferred binding trick:

Let's say the base log interface is:
   com.google.gwt.client.log.Log


The 'foo' library developer could extend that interface to:
  public interface com.libmaker.gwt.foo.FooLog
      extends com.google.gwt.client.log.Log {
  }

and then instantiate a global log class to be used exclusively by the 'foo' library with:
  static Log log = GWT.create(com.libmaker.gwt.foo.FooLog.class);




Separately, the 'bar' application developer could also extend the base interface to:
  public interface com.appmaker.gwt.bar.BarLog
      extends com.google.gwt.client.log.Log {
  }

and instantiate a log implementation dedicated to the 'bar' application with:
  static Log log = GWT.create(com.appmaker.gwt.bar.BarLog.class);




Then the compile time log level of both the 'foo' library and the 'bar' application could be controlled independently:

  <replace-with class='com.google.gwt.client.log.impl.LogImplOff'>
    <when-type-is class='com.appmaker.gwt.bar.BarLog' />
  </replace-with>

  <replace-with class='com.google.gwt.client.log.impl.LogImplDebug'>
    <when-type-is class='com.libmaker.gwt.foo.FooLog' />
  </replace-with>



 
logging:production -- SEVERE logging messages are compiled in.   Logging level is set to SEVERE.  No URL logging level argument support. Logging levels can still be set in code. 

I'd prefer we omit this last option, so that we discourage the use of logging as a production solution to unexpected runtime problems. Those problems should be addressed differently in the UI, in an application reasonable way. Production should mean logging turned off.

Unfortunately we know of some applications that are waiting for this library that do not agree with you.  They plan to also do something intelligent in the UI, but want to use the RPC handlers they are already going to have set up to actually log the error.

Indeed. I have no idea why the rest of world doesn't just agree with me :). That would be soooo much simpler.


Actually, I can see the use case for leaving logging on with a 'SEVERE' level, and possibly using a pair of loggers:
  1. RPC (Remote) logger
  2. Oops logger (as "Oops... gmail encountered error 767"), which might not display the text of the SEVERE message, but it would trigger some error message update in the UI

--
Fred Sauer
fr...@allen-sauer.com

Emily Crutcher

unread,
Feb 5, 2008, 4:51:01 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 4:40 PM, Fred Sauer <fr...@allen-sauer.com> wrote:


On Feb 5, 2008 1:33 PM, Emily Crutcher <e...@google.com> wrote:
I'd prefer DEBUG/FINEST (or whatever is the lowest) instead of WARN for the beginner trying to get Log.debug(....) to just work.

I see your point,  but as a developer I would want to easily add messages that do not show up by default.  Maybe though setting the levels at CONFIG then documenting FINE and FINEST might be better then starting them at WARN...

My first take on it is this:
  • Day one, I start to use logging.
    • Of all the Log.debug()/warn()/info()/error()/trace()/whatever() methods, which am I most likely to use? I would think it would be Log.debug(). If I get no output before the default is WARN, then I'm a bit confused.
    • I'm not going to have a lot of debug statements out of the box, so I don't mind seeing everything
  • Day three, I'm starting to do a lot more logging and now I'm thinking about actually using the different levels and about throttling back from 'show be everything'
    • This is where your "but as a developer I would want to easily add messages that do not show up by default" comes in
This is where the java logging levels actually help you, as a naive user I would use "info", "warn", or "config". I'm pretty sure I would not use "fine", "finner", "finest", so if we bump down the logging level to "config", then hopefully both use cases would be met.

 

I'll admit there is a flip side:
  • If I inherit a module/library that does a lot of logging, I would be overwhelmed if by default the l saw everything
  • If GWT core did a lot of low level logging, I wouldn't want to see that by default either



This whole 'libraries/modules with their own logging code' issue does make be reconsider the notion of categories or some kind of separation of logging control. What if instead of categories we used a different deferred binding trick:

Let's say the base log interface is:
   com.google.gwt.client.log.Log


The 'foo' library developer could extend that interface to:
  public interface com.libmaker.gwt.foo.FooLog
      extends com.google.gwt.client.log.Log {
  }

and then instantiate a global log class to be used exclusively by the 'foo' library with:
  static Log log = GWT.create(com.libmaker.gwt.foo.FooLog.class);




Separately, the 'bar' application developer could also extend the base interface to:
  public interface com.appmaker.gwt.bar.BarLog
      extends com.google.gwt.client.log.Log {
  }

and instantiate a log implementation dedicated to the 'bar' application with:
  static Log log = GWT.create(com.appmaker.gwt.bar.BarLog.class);




Then the compile time log level of both the 'foo' library and the 'bar' application could be controlled independently:

  <replace-with class='com.google.gwt.client.log.impl.LogImplOff'>
    <when-type-is class='com.appmaker.gwt.bar.BarLog' />
  </replace-with>

  <replace-with class='com.google.gwt.client.log.impl.LogImplDebug'>
    <when-type-is class='com.libmaker.gwt.foo.FooLog' />
  </replace-with>

I like our library developers, I don't want to make them mess with deferred bindings if they don't have to.  Besides, I'd rather let the user decide what logging information to see from each library. This, to me, is a very persuasive argument that we should support category filtering on the client.

Cheers,

         Emily 


--
Fred Sauer
fr...@allen-sauer.com

John Tamplin

unread,
Feb 5, 2008, 4:57:31 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 4:51 PM, Emily Crutcher <e...@google.com> wrote:
I like our library developers, I don't want to make them mess with deferred bindings if they don't have to.  Besides, I'd rather let the user decide what logging information to see from each library. This, to me, is a very persuasive argument that we should support category filtering on the client.

Ok, but how do you propose doing this without either
 a) exploding the number of permutations
 b) doing category level checks at runtime

To me, neither of those are acceptable and are much worse than not having per-category level checks on the client.

Emily Crutcher

unread,
Feb 5, 2008, 5:00:36 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 4:57 PM, John Tamplin <j...@google.com> wrote:
On Feb 5, 2008 4:51 PM, Emily Crutcher <e...@google.com> wrote:
I like our library developers, I don't want to make them mess with deferred bindings if they don't have to.  Besides, I'd rather let the user decide what logging information to see from each library. This, to me, is a very persuasive argument that we should support category filtering on the client.

Ok, but how do you propose doing this without either
 a) exploding the number of permutations
 b) doing category level checks at runtime

Why are level checks at runtime a problem?


 

To me, neither of those are acceptable and are much worse than not having per-category level checks on the client.


--
John A. Tamplin
Software Engineer, Google

Fred Sauer

unread,
Feb 5, 2008, 5:09:29 PM2/5/08
to Google Web Toolkit Contributors
On Feb 5, 2008 2:51 PM, Emily Crutcher <e...@google.com> wrote:


On Feb 5, 2008 4:40 PM, Fred Sauer <fr...@allen-sauer.com> wrote:


On Feb 5, 2008 1:33 PM, Emily Crutcher <e...@google.com> wrote:
I'd prefer DEBUG/FINEST (or whatever is the lowest) instead of WARN for the beginner trying to get Log.debug(....) to just work.

I see your point,  but as a developer I would want to easily add messages that do not show up by default.  Maybe though setting the levels at CONFIG then documenting FINE and FINEST might be better then starting them at WARN...

My first take on it is this:
  • Day one, I start to use logging.
    • Of all the Log.debug()/warn()/info()/error()/trace()/whatever() methods, which am I most likely to use? I would think it would be Log.debug(). If I get no output before the default is WARN, then I'm a bit confused.
    • I'm not going to have a lot of debug statements out of the box, so I don't mind seeing everything
  • Day three, I'm starting to do a lot more logging and now I'm thinking about actually using the different levels and about throttling back from 'show be everything'
    • This is where your "but as a developer I would want to easily add messages that do not show up by default" comes in
This is where the java logging levels actually help you, as a naive user I would use "info", "warn", or "config". I'm pretty sure I would not use "fine", "finner", "finest", so if we bump down the logging level to "config", then hopefully both use cases would be met.


I would be okay with 'CONFIG', given the JDK inspired level names:
  • SEVERE (highest value)
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST (lowest value)
If we had the log4j levels, then I'd want 'DEBUG' as the default.
  • FATAL
  • ERROR
  • WARN
  • INFO
  • DEBUG
  • TRACE
Hey, I think that means we agree.


 
I'll admit there is a flip side:
  • If I inherit a module/library that does a lot of logging, I would be overwhelmed if by default the l saw everything
  • If GWT core did a lot of low level logging, I wouldn't want to see that by default either
This whole 'libraries/modules with their own logging code' issue does make be reconsider the notion of categories or some kind of separation of logging control. What if instead of categories we used a different deferred binding trick:

Let's say the base log interface is:
   com.google.gwt.client.log.Log


The 'foo' library developer could extend that interface to:
  public interface com.libmaker.gwt.foo.FooLog
      extends com.google.gwt.client.log.Log {
  }

and then instantiate a global log class to be used exclusively by the 'foo' library with:
  static Log log = GWT.create(com.libmaker.gwt.foo.FooLog.class);




Separately, the 'bar' application developer could also extend the base interface to:
  public interface com.appmaker.gwt.bar.BarLog
      extends com.google.gwt.client.log.Log {
  }

and instantiate a log implementation dedicated to the 'bar' application with:
  static Log log = GWT.create(com.appmaker.gwt.bar.BarLog.class);




Then the compile time log level of both the 'foo' library and the 'bar' application could be controlled independently:

  <replace-with class='com.google.gwt.client.log.impl.LogImplOff'>
    <when-type-is class='com.appmaker.gwt.bar.BarLog' />
  </replace-with>

  <replace-with class='com.google.gwt.client.log.impl.LogImplDebug'>
    <when-type-is class='com.libmaker.gwt.foo.FooLog' />
  </replace-with>

I like our library developers, I don't want to make them mess with deferred bindings if they don't have to.  Besides, I'd rather let the user decide what logging information to see from each library. This, to me, is a very persuasive argument that we should support category filtering on the client.


I think we can simplify a bit for the application developer:
  1. Keep the above deferred binding sub interface capability for library developers, GWT proper and so on.
  2. Provide all the necessary defaults in the GWT logging *.gwt.xml module file for the application developer, so that she can just call Log.foo(...) out of the box, without having to create a sub interface
  3. Large/complex projects can later follow the library developer route and add sub interfaces if they really need to


--
Fred Sauer
fr...@allen-sauer.com

Emily Crutcher

unread,
Feb 5, 2008, 5:13:12 PM2/5/08
to Google-Web-Tool...@googlegroups.com
Hey, I think that means we agree.

Naa... ;-).
 

I think we can simplify a bit for the application developer:
  1. Keep the above deferred binding sub interface capability for library developers, GWT proper and so on.
  2. Provide all the necessary defaults in the GWT logging *.gwt.xml module file for the application developer, so that she can just call Log.foo(...) out of the box, without having to create a sub interface
  3. Large/complex projects can later follow the library developer route and add sub interfaces if they really need to
I agree that people should be able to create sub interfaces, however I still would not want to make them have to, which means I'm still in favor of category level logging control.
 


--
Fred Sauer
fr...@allen-sauer.com

John Tamplin

unread,
Feb 5, 2008, 5:14:58 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 5:00 PM, Emily Crutcher <e...@google.com> wrote:
Why are level checks at runtime a problem?

Once you start doing the level checks at runtime, you have significant overhead in terms of code size and execution time.  Presuming you store the categories in a hash, the generated code looks something like:

if(logger.categoryLevelMap.get("category") >= Level.WARN) {
  // ...
}

which can't get optimized any further.  The compiler does not know how to track values through a hash map, so even if you assign the category values to constants, the compiler can't statically remove any of these checks.  You could an extra level of tests, so that if the maximum level compiled in is ERROR, this code could get removed, ie:

if(logger.isErrorEnabled()) {
  if(logger.categoryLevelMap.get("category") >= LEVEL.WARN) {
    // ...
  }
}

but that doesn't allow you to have a particular category lower than the statically configured level.  In that case, I don't see how this really helped you for your use case of having different libraries having different levels -- ie, if you set it to DEBUG so you can get one the output for the module you want, all of the logging messages in any of the modules will still be present, even if they will actually never be called because the level for their categories will always be ERROR, for example.

Emily Crutcher

unread,
Feb 5, 2008, 5:27:56 PM2/5/08
to Google-Web-Tool...@googlegroups.com
I'm not sure I understand. The call to log would look like this:
Log.warn("my message", "category");

If logging is "production" or "off", the message is completely removed.  If logging is on, then the LogImpl class would have to check if the category is enabled, but that should be relatively small code.

John Tamplin

unread,
Feb 5, 2008, 5:36:17 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 5:27 PM, Emily Crutcher <e...@google.com> wrote:
I'm not sure I understand. The call to log would look like this:
Log.warn("my message", "category");

If logging is "production" or "off", the message is completely removed.  If logging is on, then the LogImpl class would have to check if the category is enabled, but that should be relatively small code.

My point is if you do that, then you have no way of turning logging for a particular category to DEBUG without statically including all debug code everywhere.  Since the motivation seemed to be someone who wanted to debug just their code without impacting library code they didn't write, I don't see how this solves that use case.

Ian Petersen

unread,
Feb 5, 2008, 5:37:47 PM2/5/08
to Google-Web-Tool...@googlegroups.com
I think Fred's suggestion of libraries using subclasses of the Log
interface in deferred binding is a good example of how GWT.create()
could be improved by adding parameters to it.

What if libraries did this:

Log logger = GWT.create(com.google.gwt.client.log.Log.class,
"com.libmaker.gwt.foo.Foo");

instead of this:

Log logger = GWT.create(com.libmaker.gwt.foo.FooLog.class)

You could then statically determine a log level for each category.
The generator that gets invoked to instantiate the Log interface could
look at some configuration item (in module.gwt.xml, or in log4j.xml,
or whatever) to determine which kind of logger to return. If
"com.libmaker.gwt.foo.Foo" is set to OFF, then the generator returns
NullLogger. If it's set to FINE then it returns the FineLogger, etc.

I think this would capture the best parts of Fred's suggestion,
without tripping over Emily's concern about making library writers
into deferred binding experts. I _think_ it also avoids creating an
explosion of deferred binding permutations, but I might be missing
something.

Thoughts?

Emily Crutcher

unread,
Feb 5, 2008, 5:47:10 PM2/5/08
to Google-Web-Tool...@googlegroups.com

Actually, that's not the use case I'm looking for, as all I want is a way to control the output in a log file that someone has to look through, not statically remove those calls.   A debugger can be very useful, however if the error shows up in an automated test or if the tester is not the developer, having controlled logging output can be very useful.

 

--
John A. Tamplin
Software Engineer, Google

Fred Sauer

unread,
Feb 5, 2008, 5:48:19 PM2/5/08
to Google-Web-Tool...@googlegroups.com

I think we can simplify a bit for the application developer:
  1. Keep the above deferred binding sub interface capability for library developers, GWT proper and so on.
  2. Provide all the necessary defaults in the GWT logging *.gwt.xml module file for the application developer, so that she can just call Log.foo(...) out of the box, without having to create a sub interface
  3. Large/complex projects can later follow the library developer route and add sub interfaces if they really need to
I agree that people should be able to create sub interfaces, however I still would not want to make them have to, which means I'm still in favor of category level logging control.

Maybe we need both:
  • Libraries probably need to use deferred binding to separate their logging code from the application
  • The default application log implementation could certainly utilize (runtime) categories
--
Fred Sauer
fr...@allen-sauer.com

Emily Crutcher

unread,
Feb 5, 2008, 5:54:43 PM2/5/08
to Google-Web-Tool...@googlegroups.com
I like the idea of GWT.create() with arguments, there are many reasons it would be very cool, but the last thing I want to do right now is distract our wonderful compiler team with the design for logging and I believe there are more compelling use cases out there to champion the feature. That being said, Ian, I think you are right that if it existed we could probably figure out some very clever ways to use it.

         Cheers,

               Emily

John Tamplin

unread,
Feb 5, 2008, 6:00:08 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 5:54 PM, Emily Crutcher <e...@google.com> wrote:
I like the idea of GWT.create() with arguments, there are many reasons it would be very cool, but the last thing I want to do right now is distract our wonderful compiler team with the design for logging and I believe there are more compelling use cases out there to champion the feature. That being said, Ian, I think you are right that if it existed we could probably figure out some very clever ways to use it.

I agree that it should happen and that this could use it.  However, the basic problem is the generator API would need to be extended and there are thorny issues to carefully consider before committing to a new generator API that it isn't going to happen in 1.5 and therefore cannot be used by logging.

Ian Petersen

unread,
Feb 5, 2008, 6:27:31 PM2/5/08
to Google-Web-Tool...@googlegroups.com

If I'm understanding correctly, then I think you guys are saying that
GWT.create() will _eventually_ be extended and, when that happens,
setting the category for a logger via GWT.create() would be the right
way to go. If all that's true, then I think we should take a
forwards-compatible version of Fred's suggestion until create() gets
additional parameters. As discussed in another thread, adding
parameters to create() doesn't add power to create(), it just adds
convenience, so everything that could be done with extra create()
parameters can already be done today.

I'd suggest something like this:

/**
* @gwt.logCategory com.libmaker.gwt.foo.Foo
*/
public interface FooLogger extends Logger {
}

Logger log = GWT.create(com.libmaker.gwt.foo.FooLogger.class);

Once GWT.create() gets additional parameters, the Logger generator
could look first at a category passed to create(), and second at the
@gwt.logCategory annotation. Either way, the category is set at
compile time, which means the compiler could statically determine
which kind of logger to instantiate based on some kind of category ->
level configuration.

Also, I think I agree with Emily's earlier assertion that getting
library makers to learn how to configure deferred binding is too much
to ask, but now, instead of configuring it, they'd just be using
it--sort of like application writers who want to use RPC.

John Tamplin

unread,
Feb 5, 2008, 6:34:42 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 6:27 PM, Ian Petersen <ispe...@gmail.com> wrote:
If I'm understanding correctly, then I think you guys are saying that
GWT.create() will _eventually_ be extended and, when that happens,
setting the category for a logger via GWT.create() would be the right
way to go.  If all that's true, then I think we should take a
forwards-compatible version of Fred's suggestion until create() gets
additional parameters.  As discussed in another thread, adding
parameters to create() doesn't add power to create(), it just adds
convenience, so everything that could be done with extra create()
parameters can already be done today.

I am saying we have talked about adding parameters to GWT.create() and it will likely happen if we can find a reasonable way to address all the related issues.  I don't know what form that will take until we address those issues, so it may or may not work the way you describe (for example, it may not create additional deferred binding permutations).
 
I'd suggest something like this:

/**
 * @gwt.logCategory com.libmaker.gwt.foo.Foo
 */

Note that all comment metadata is being deprecated and replaced with Java annotations, so we would not add new metadata like this.  Instead it would be @LogCategory("foo") or @LogCategory(Foo.class) depending on what you wanted to do.

Henri Karapuu

unread,
Feb 5, 2008, 8:16:56 PM2/5/08
to Google Web Toolkit Contributors
On Feb 5, 7:20 pm, "John Tamplin" <j...@google.com> wrote:
> The point is that the different levels for GWT will be done at compile time
> with different deferred bindings.I could see having a "dynamic" deferred binding target for
> loglevel that produced that, but then the problem is what do you do with the
> ability to set dynamic levels for the staticly bound loggers?
> ...

John, thanks for the detailed description.

I believe it is perfectly acceptable that the lowest loggable level is
set statically at compile time, and the dead code elimination would
work just as you want.

What i'm proposing is that in addition there would be *extra* runtime
per category filtering. It could not be set to lower log levels than
has been compiled in, and thats okey. It would not do any extra dead
code elimination, and thats okey too. The runtime filtering would
exist only for making viewing of the log messages more manageable (to
prevent 'log blindness').

/Henri Karapuu

Henri Karapuu

unread,
Feb 5, 2008, 8:40:29 PM2/5/08
to Google Web Toolkit Contributors
> This is why, for all but
> temporary debugging support (in which case a debugger with conditional
> breakpoints is almost certainly better),

Let me elaborate a bit on the use cases.

1. Real-life application projects have employees with all different
skill levels, including junior programmers, interns, HTML designers
and functional testers. Most of these don't have a glue how to use
'debugger with conditional breakpoints'. Giving them simple option
'press ctrl-d' to see log console has been proven in practice to be
very valuable (if the log messages have been carefully crafted).

2. During normal application development many simple problems can be
immediately determined from the log messages, which is significantly
faster than firing debugging and setting correct breakpoints, even for
senior developers who can play jazz with debugger.

/Henri Karapuu

Emily Crutcher

unread,
Feb 5, 2008, 8:50:51 PM2/5/08
to Google-Web-Tool...@googlegroups.com
Both of those use cases seem perfectly reasonable to me, of course, as you could tell from earlier I was somewhat sold on the idea anyway, so might not be the most critical audience ;-).

Henri Karapuu

unread,
Feb 5, 2008, 8:52:03 PM2/5/08
to Google Web Toolkit Contributors
On Feb 5, 10:33 pm, "Emily Crutcher" <e...@google.com> wrote:
> Unfortunately we know of some applications that are waiting for this library
> that do not agree with you. They plan to also do something intelligent in
> the UI, but want to use the RPC handlers they are already going to have set
> up to actually log the error.

+1, This is hard requirement for us also.

Getting information back from client to server when 'things are not
fine' is absolutely critical. Basically i think the logging system
should just have configurable handlers, so that you could hook your
own handler implementation to any level you wish.

/Henri Karapuu

Ian Petersen

unread,
Feb 5, 2008, 8:54:05 PM2/5/08
to Google-Web-Tool...@googlegroups.com
On Feb 5, 2008 8:40 PM, Henri Karapuu <hkar...@gmail.com> wrote:
> 2. During normal application development many simple problems can be
> immediately determined from the log messages, which is significantly
> faster than firing debugging and setting correct breakpoints, even for
> senior developers who can play jazz with debugger.

I might be beating a dead horse here, but a wise man once told me that
instead of doing printf-style debugging, you should replace the
printfs with log statements. Then, in the future, when you have to
debug the same or similar problem all over again, you already have all
the debug output you need--you just have to turn it on. I think a
good logging framework, coupled with wise application thereof can
easily be better than a debugger in most cases and it's _always_ more
persistent, simply by definition. I hope the logging framework under
discussion will be the "good logging framework" half of that equation
(and I'm optimistic, what with all the lively discussion here).

Reply all
Reply to author
Forward
0 new messages