[hibernate-dev] Obtaining loggers

Sanne Grinovero sanne at hibernate.org
Wed May 22 09:05:51 EDT 2013


Let's simplify my reply to address verbosity only then:
Search does:

   private static final Log log = LoggerFactory.make();

Looks good?

Sanne

On 22 May 2013 13:57, Steve Ebersole <steve at hibernate.org> wrote:
> Y'all are trying to solve a different problem imo.
>
> The "problem" I am looking to solve is simply verbosity.  Both the problem
> and the solution have an equal possibility for copy-paste errors.
>
> Whereas y'all are trying to remove the possibility of these copy-paste
> problems.  BTW, I use IntelliJ IDEA "Live templates" to deal with that. I
> have a template named log; so I simply type "log"+TAB and get a proper log
> statement.
>
>
> On Wed 22 May 2013 02:51:03 AM CDT, Gunnar Morling wrote:
>>
>> 2013/5/21 Sanne Grinovero <sanne at hibernate.org
>> <mailto:sanne at hibernate.org>>
>>
>>
>>     Have you seen how Search does it?
>>
>>         private static final Log log = LoggerFactory.make();
>>
>>     The implementation of LoggerFactory#make is:
>>
>>        public static Log make() {
>>             Throwable t = new Throwable();
>>             StackTraceElement directCaller = t.getStackTrace()[1];
>>             return Logger.getMessageLogger( Log.class,
>>     directCaller.getClassName() );
>>         }
>>
>>     We introduced this a while back after having spotted some copy/paste
>>     mistakes which had lead to have the wrong logger; however there is a
>>     catch:
>>     each class initialization triggers a stacktrace initialization. Sure
>>     it's an initialization cost only, but still I wonder how large the
>>     cost is, adding up all classes: maybe we should just replace it with a
>>     checkstyle rule to verify its correctness.
>>
>>
>> An alternative implementation of LoggerFactory could be this (based on
>> [1]):
>>
>>     public final class LoggerFactory {
>>
>> private static CallerProvider callerProvider = new CallerProvider();
>>
>>         public static Log make() {
>>             return Logger.getMessageLogger( Log.class,
>> callerProvider.getCallerClass().getCanonicalName() );
>>         }
>>
>>         private static class CallerProvider extends SecurityManager {
>>             public Class<?> getCallerClass() {
>>                 return getClassContext()[2];
>>         }
>>     }
>>
>> SecurityManager#getClassContext() is a native method, so one doesn't
>> know how it is implemented, but I guess it's faster than initializing
>> a stack trace, while still allowing for the concise
>> LoggerFactory.make(); usage.
>>
>> Btw. another copy-and-paste safe pattern enabled by Java 7 is this
>> (suggested in "The Well-Grounded Java Developer"):
>>
>>     Logger logger = Logger.getMessageLogger(
>>         Log.class,
>> MethodHandles.lookup().lookupClass().getCanonicalName() );
>>
>> This can't be pushed into a factory class, though, making more verbose
>> than the factory approach.
>>
>> --Gunnar
>>
>> [1]
>>
>> http://beust.com/weblog/2011/07/15/accessing-the-class-object-in-a-static-context/
>>
>>
>>     Also, each module needs to have its own copy of the LoggerFactory to
>>     hardwire the correct Log.class interface, so you could still import
>>     the LoggerFactory from an alien module by mistake, but that's likely
>>     spotted by the typesafety of it as you wouldn't have the expected
>>     logger methods.
>>
>>     Sanne
>>
>>
>>     On 21 May 2013 22:24, Steve Ebersole <steve at hibernate.org
>>     <mailto:steve at hibernate.org>> wrote:
>>     > Forgot...  So really this just allows more conciseness in
>>     obtaining the
>>     > logger.  So from:
>>     >
>>     > private static final CoreMessageLogger LOG =
>>     Logger.getMessageLogger(
>>     > CoreMessageLogger.class, CollectionLoadContext.class.getName() );
>>     >
>>     > to:
>>     >
>>     > private static final CoreMessageLogger LOG =
>>     CoreLogging.messageLogger(
>>     > CollectionLoadContext.class );
>>     >
>>     >
>>     > On 05/21/2013 04:21 PM, Steve Ebersole wrote:
>>     >> I was getting tired of statements in the source code to get logger
>>     >> instances that spread across sometimes 4 lines because of JBoss
>>     >> Logging's verbose means of acquiring a message logger.  So I
>>     created a
>>     >> more concise form for this for hibernate-core,
>>     hibernate-entitymanager
>>     >> and hibernate-envers.  I mainly limited it to these projects
>>     because
>>     >> they have lots of these calls, whereas the others do not.  Feel
>>     free
>>     >> to copy the approach to the other projects if someone wants.
>>     >>
>>     >> Essentially each of those projects define a class with 4 static
>>     >> methods.  Taking the hibernate-core one as an example:
>>     >>
>>     >>
>>     >> import org.jboss.logging.Logger;
>>     >>
>>     >> /**
>>     >>  * Quite sad, really, when you need helpers for generating
>>     loggers...
>>     >>  *
>>     >>  * @author Steve Ebersole
>>     >>  */
>>     >> public class CoreLogging {
>>     >>     /**
>>     >>      * Disallow instantiation
>>     >>      */
>>     >>     private CoreLogging() {
>>     >>     }
>>     >>
>>     >>     public static CoreMessageLogger messageLogger(Class
>>     >> classNeedingLogging) {
>>     >>         return messageLogger( classNeedingLogging.getName() );
>>     >>     }
>>     >>
>>     >>     public static CoreMessageLogger messageLogger(String
>>     loggerName) {
>>     >>         return Logger.getMessageLogger( CoreMessageLogger.class,
>>     >> loggerName );
>>     >>     }
>>     >>
>>     >>     public static Logger logger(Class classNeedingLogging) {
>>     >>         return Logger.getLogger( classNeedingLogging );
>>     >>     }
>>     >>
>>     >>     public static Logger logger(String loggerName) {
>>     >>         return Logger.getLogger( loggerName );
>>     >>     }
>>     >> }
>>     >>
>>     >> I just plan on replacing these calls as opportunities arise, rather
>>     >> than all in one fell swoop.
>>     >
>>     > _______________________________________________
>>     > hibernate-dev mailing list
>>     > hibernate-dev at lists.jboss.org <mailto:hibernate-dev at lists.jboss.org>
>>
>>     > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>     _______________________________________________
>>     hibernate-dev mailing list
>>     hibernate-dev at lists.jboss.org <mailto:hibernate-dev at lists.jboss.org>
>>     https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>
>>
>


More information about the hibernate-dev mailing list