[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