[hibernate-dev] Obtaining loggers
Steve Ebersole
steve at hibernate.org
Wed May 22 09:36:43 EDT 2013
I am not a fan of what goes on inside LoggerFactory.make(). That's
just my opinion.
On Wed 22 May 2013 08:05:51 AM CDT, Sanne Grinovero wrote:
> 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