[hibernate-dev] Obtaining loggers

Steve Ebersole steve at hibernate.org
Wed May 22 08:57:50 EDT 2013


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