Log'n Guice is like Rock'n Roll :)

13 views
Skip to first unread message

Anthony MULLER

unread,
Jul 31, 2008, 5:34:36 AM7/31/08
to google...@googlegroups.com
Hello,

I'm trying to use Guice to inject Logger into my objects... The main problem is that I didn't know which class is being injected. So, I can't build a logger with the convenient class.

Other 'little' problem is that the traditional way to use Logger is to have a static field into class... And Guice doesn't like this (I mean use of static)... Even if it is possible to inject them with a special Guice method.

So, I'd like to know if somebody already think to this (and have a proposal to solve it).

What I've done:

1) I create a class ILogger which have traditional looger méthods (like isWarnEnabled(), warn(String msg))
2) I had an extra parameter to this method to take as argument the object where log operation occured

This is how I use it:

public class MyObject {

    // Note: field in NOT static
    @Inject
    private final ILogger LOGGER = null;

    public void myMethod() {
            //...
            // Note the "this" parameter
            if (LOGGER.isWarnEnabled(this)) {
                LOGGER.warn(this, "My message to log");
            }
            //...
    }
}

The ILogger implementation looks like:

@Singleton
public class LoggerImpl implements ILogger {

    // Cache to store already created logger: one logger per class strategy
    private final Map<Class<?>, Logger> loggers = new HashMap<Class<?>, Logger>();

    /**
     * {@inheritDoc}
     */
    public void debug(Object src, String msg) {
        getLogger(src).debug(msg);
    }

    // ... other traditional log methods

    /**
     * Return a logger instance or get it from cache.
     *
     * @param src
     * @return Logger
     */
    private Logger getLogger(Object src) {
        Class<?> clazz = null;
        if (src instanceof Class<?>) {
            clazz = (Class<?>) src;
        } else {
            clazz = src.getClass();
        }
        Logger logger = loggers.get(clazz);
        if (logger == null) {
            logger = Logger.getInstance(clazz.getName());
            loggers.put(src.getClass(), logger);
        }
        return logger;
    }
}

What do you think about this?

Is it a good way to deal with logging issue ?

Thanks!

Anthony MÜLLER

Stuart McCulloch

unread,
Jul 31, 2008, 5:44:02 AM7/31/08
to google...@googlegroups.com
2008/7/31 Anthony MULLER <anthony...@gmail.com>
Hello,

I'm trying to use Guice to inject Logger into my objects... The main problem is that I didn't know which class is being injected. So, I can't build a logger with the convenient class.

FYI, Guice has a default "java.util.logging.Logger" binding for each class being injected

so you can do this:

   import java.util.logging.Logger;

   @Inject
   Logger logger;

and it will automatically use the correct name - however this is only for java.util.logging.




--
Cheers, Stuart

Anthony MULLER

unread,
Jul 31, 2008, 5:48:29 AM7/31/08
to google...@googlegroups.com
Hmm hmm, thanks for reply!

I didn't know this tip :)

In fact, I didn't use java.util.logging... So, is it possible:

1) to specify my own Logger implementation (internal) through 'java.util.logging' (i don't know this class alot... I need to learn about it)

or

2) overload Guice mecanism somewhere to tell it to inject my logger rather than java.util.logging

Regards,
Anthony MÜLLER


2008/7/31 Stuart McCulloch <mcc...@gmail.com>

Anthony MULLER

unread,
Jul 31, 2008, 10:01:30 AM7/31/08
to google...@googlegroups.com
Any reponses on this issue please?

I tried to add an handler on the logger automatically injected by Guice, but it is not really fine...

I believed java.util.logging was only an API and I could change the underlying implementation but I was wrong :(

Are there alternative to my primary solution?

will Guice 2.0 help me anymore?

Cheers,

Anthony MÜLLER


2008/7/31 Anthony MULLER <anthony...@gmail.com>

jordi

unread,
Aug 1, 2008, 2:32:37 AM8/1/08
to google...@googlegroups.com
i used a @Log annotation at type level to intercept all classes i wanted to log, with an optional attribute logger if you want to specify the name of the logger.

Then i used Matchers from Guice to find all that classes and intercept them. The only thing that interceptor does is to manually set the Logger field in your logged class.

I'll tune this @Log thing and write a post somewhere...

jordi

Dhanji R. Prasanna

unread,
Aug 1, 2008, 2:36:26 AM8/1/08
to google...@googlegroups.com
What's wrong with:

private final Logger log = Logger.getLogger();
//log4j/slf4j/logback/jlog/clogging.....

Dhanji. =)

Dhanji R. Prasanna

unread,
Aug 1, 2008, 2:37:33 AM8/1/08
to google...@googlegroups.com
On Fri, Aug 1, 2008 at 4:36 PM, Dhanji R. Prasanna <dha...@gmail.com> wrote:
> What's wrong with:
>
> private final Logger log = Logger.getLogger();

=> Logger.getLogger(MyClass.class);

jordi

unread,
Aug 1, 2008, 2:48:47 AM8/1/08
to google...@googlegroups.com
lol

i guess it's the Annotation / Interceptor fever and we are lazy people

btw my Log annotation does some more automatic logging that most of the time i don't wanna be aware of

but there's nothing wrong with Logger.getLogger(MyClass.class) ;D

Anthony MULLER

unread,
Aug 1, 2008, 3:47:33 AM8/1/08
to google...@googlegroups.com
Yes, I do the same but at method level and... In fact, my need is to log all methods call BUT only methods defined in my public interfaces of my objects, not other internal methods... So, I have to do some extra efforts to guess if a method is defined in a "public" interface or not...

I think I will keep my first solution because the one with java.util.logging is not good for me... I use another logger... But, I hoped to use the same mechanism: if Guice can inject a such logger, that means it knows the type of the injectee... And it is what I need!

Regards

Anthony



2008/8/1 jordi <jo...@donky.org>

David Morash

unread,
Aug 1, 2008, 11:09:33 AM8/1/08
to google...@googlegroups.com
We used a logger factory approach as it allowed us to mock it out for testing.
>>>>>> if (LOGGER.isWarnEnabled(*this*)) {
>>>>>> LOGGER.warn(*this*, "My message to log");
--
Sent from Gmail for mobile | mobile.google.com

jhulford

unread,
Aug 1, 2008, 12:03:57 PM8/1/08
to google-guice
I'd think I'd have to agree w/ Dhanji. There's already 4-5 different
logging wrappers that handle the logging implementation abstraction
for you. Cramming another way into Guice seems a little like using
the wrong tool for the job. As far as I know, you're not really
gaining anything by using Guice to provide/instantiate your logging
implementations because for all of the logging methods you still need
pretty much need config files elsewhere to do all your log output
routings, so you're just adding another point in the process that
needs to be maintained.

Kamil Demecki

unread,
Aug 13, 2008, 3:37:08 PM8/13/08
to google-guice


On Aug 1, 8:36 am, "Dhanji R. Prasanna" <dha...@gmail.com> wrote:
> What's wrong with:
>
> private final Logger log = Logger.getLogger();
> //log4j/slf4j/logback/jlog/clogging.....
>
> Dhanji. =)
>

It is generic problem. IoC framework should permit to lately override
some specific behavior. At first time I dont now which log/something
implementation is good, In case of Logger.getLogger you are tied with
one solution. If you wont introduce fasade
youloggingfacase.getLogger() and then you must change logging/
something funtionality you have two solutions:

1) find all occurencess Log.getLogger()
2) write you own Log.getLogger and push it first on classpath

I would like IoC framework give nice solution ;)

jhulford

unread,
Aug 14, 2008, 10:45:59 AM8/14/08
to google-guice
On Aug 13, 3:37 pm, Kamil Demecki <skajo...@gmail.com> wrote:
> It is generic problem. IoC framework should permit to lately override
> some specific behavior. At first time I dont now which log/something
> implementation is good, In case of Logger.getLogger you are tied with
> one solution. If you wont introduce fasade
> youloggingfacase.getLogger() and then you must change logging/
> something funtionality you have two solutions:
>
> 1) find all occurencess Log.getLogger()
> 2) write you own Log.getLogger and push it first on classpath
>
> I would like IoC framework give nice solution ;)

Log.getLogger() is already providing a way to utilize several
different logging implementations - it's essentially doing injection
already. The inherent problem is that none of these logging
structures implement identical interfaces for doing logging, therefore
to inject them you need to either inject a wrapper interface like
Commons Logging or slf4j or write your own (blech). If you're using
the wrapper directly you're already getting the ability to swap
implementations in and out and all you're adding by doing an injection
step is another maintenance point, adding the logging to your Guice
modules AND maintaining the wrapper configs.

Kamil Demecki

unread,
Aug 16, 2008, 8:19:33 AM8/16/08
to google-guice
When Log.getLogger is not enough, you are stuck and remains solutions
marked above. IoC is more flexible and powerful. IoC frameworks should
allow you resolve such dependencies. In my wrapper config it would be
written in Guice and you maintain only one solution ;)

Anthony MULLER

unread,
Aug 26, 2008, 9:54:06 AM8/26/08
to google...@googlegroups.com
Hello !

Is there a way to say once to Guice: inject any static fields named LOGGER?

Regards,
Anthony


2008/8/1 Anthony MULLER <anthony...@gmail.com>

Anthony MULLER

unread,
Sep 2, 2008, 7:47:19 AM9/2/08
to google...@googlegroups.com
Hmmm.... is there a way to configure Guice to inject any static fields with @Inject annotations ? :-(

Anthony, desesperate developer


2008/8/26 Anthony MULLER <anthony...@gmail.com>

Robbie Vanbrabant

unread,
Sep 2, 2008, 8:46:46 AM9/2/08
to google...@googlegroups.com
Binder#requestStaticInjection (from inside a module)

Cheers
Robbie

Anthony MULLER

unread,
Sep 2, 2008, 8:59:29 AM9/2/08
to google...@googlegroups.com
I meant for any objects... I can't enumerate all types into a module...

2008/9/2 Robbie Vanbrabant <robbie.v...@gmail.com>
Reply all
Reply to author
Forward
0 new messages