If there’s enough duplication in the lambdas, or in the code around the 
lambdas, extracting the duplication into methods would reduce the number of 
lambdas.

> On Sep 10, 2018, at 11:03 AM, Kirk Lund <kl...@apache.org> wrote:
> 
> Alright I'm more up-to-date on this thread. Some things to consider:
> 
> The lambdas look great, but we'd have to start splitting the Geode clasess.
> They're so big right now, that if you change a bunch of log statements to
> use lambdas you'll hit the max number of lambdas on many of our classes. We
> hit the lambda limit on a dunit test and it didn't really take that many
> lambdas to hit the limit (see
> https://issues.apache.org/jira/browse/GEODE-5485).
> 
> We could change FastLogger to override every Logger method instead of
> isDebugEnabled and isTraceEnabled. Then we could remove every single guard
> clause from the Geode log statements.
> 
> If Log4J2 changed their implementation of debug and trace to be comparable
> with hitting a volatile for disabled statements then we could delete
> FastLogger and every log statement guard clause.
> 
> On Mon, Sep 10, 2018 at 10:12 AM, Kirk Lund <kl...@apache.org> wrote:
> 
>> The reason we use these guards is that the Log4j2 implementation is more
>> expensive than hitting a volatile. Please don't change anything unless you
>> start writing lots of JMH benchmarks! The existing code went through lots
>> of iterations of perf testing that isn't part of Geode.
>> 
>> Every Log4j2 Logger used by Geode classes are wrapped inside a FastLogger
>> which uses a single volatile for those "isDebugEnabled" checks. If you
>> remove this, you will find that the performance of Geode will thank even at
>> higher log levels such as INFO. Geode is currently optimized for INFO level
>> logging. Without FastLogger, every log statement code path goes down into a
>> hot mess of checking filters and performing file checking against
>> log4j2.xml (based on a mod so that it only occurs every several log
>> statements) to see if it has changed.
>> 
>> Despite this, Log4J2 Core still out performs Logback for "disabled log
>> statements" and by this I mean the huge # of debug/trace level statements
>> in Geode when running at INFO level.
>> 
>> Unwrapping those "isDebugEnabled" checks will eliminate the optimization
>> provided by FastLogger. Without the guard clauses, FastLogger doesn't
>> improve anything because the Log4j2 code skips the "isDebugEnabled" checks
>> and goes into filter checking which also checks the log level but after
>> much more work. My recommendation is to work with Log4j2 project to fix
>> this performance problem when using log statements without the FastLogger
>> optimizations. For example, Log4j1 used a dedicated async thread for the
>> checking of the config file but for some reason they didn't go this route
>> in Log4J2.
>> 
>> PS: My Log4J2 code knowledge is a couple of years old so please feel free
>> to dig into their code to see if the above issues were fixed.
>> 
>> On Mon, Sep 10, 2018 at 9:35 AM, Galen O'Sullivan <gosulli...@pivotal.io>
>> wrote:
>> 
>>> I think that logging in hot paths/loops is probably something that should
>>> be avoided. And if it is necessary, I suspect that the JIT will
>>> short-circuit that call since debug levels don't generally change.
>>> 
>>> There probably are a few hot paths that need to optimize logging, but
>>> that's not the majority.
>>> 
>>> Can we agree to avoid this pattern in new code, since it adversely affects
>>> readability?
>>> 
>>> Galen
>>> 
>>> 
>>> On Fri, Sep 7, 2018 at 1:46 PM, Nicholas Vallely <nvall...@pivotal.io>
>>> wrote:
>>> 
>>>> I was just randomly looking into this a couple of days ago as a tangent
>>> to
>>>> 'observability' and came across this Stack Overflow:
>>>> https://stackoverflow.com/questions/6504407/is-there-a-need-
>>> to-do-a-iflog-
>>>> isdebugenabled-check
>>>> where the first answer is the most succinct in my opinion.
>>>> 
>>>> In the geode code that I searched, we are not consistent with our use of
>>>> the if(statement) wrapper for debug, though most do have the wrapper.
>>>> 
>>>> Nick
>>>> 
>>>> On Fri, Sep 7, 2018 at 11:35 AM Jacob Barrett <jbarr...@pivotal.io>
>>> wrote:
>>>> 
>>>>> Checking with logger.isDebugEnabled() it still a good practice for hot
>>>>> paths to avoid the construction of intermediate object arrays to hold
>>> the
>>>>> var-args. Some logging libraries have fixed argument optimizations for
>>>>> var-args up to a specific limit. In very hot paths it is nice to
>>>>> check logger.isDebugEnabled() once into a temp boolean value and then
>>>> check
>>>>> that in all the subsequent debug logging statements in the hot path.
>>>>> 
>>>>> -Jake
>>>>> 
>>>>> 
>>>>> On Fri, Sep 7, 2018 at 11:18 AM Dan Smith <dsm...@pivotal.io> wrote:
>>>>> 
>>>>>> I think this pattern is a holdover from using log4j 1. In that
>>> version,
>>>>> you
>>>>>> added an if check to avoid unnecessary string concatenation if debug
>>>> was
>>>>>> enabled.
>>>>>> 
>>>>>> 
>>>>>>   1. if (logger.isDebugEnabled()) {
>>>>>>   2.     logger.debug("Logging in user " + user.getName() + " with
>>>>>> birthday " + user.getBirthdayCalendar());
>>>>>>   3. }
>>>>>> 
>>>>>> 
>>>>>> Log4j2 lets you pass a format string, so you can just do this:
>>>>>> 
>>>>>> logger.debug("Logging in user {} with birthday {}", user.getName(),
>>>>>> user.getBirthdayCalendar());
>>>>>> 
>>>>>> 
>>>>>> These examples come from the log4j2 docs:
>>>>>> 
>>>>>> https://logging.apache.org/log4j/2.0/manual/api.html
>>>>>> 
>>>>>> -Dan
>>>>>> 
>>>>>> On Fri, Sep 7, 2018 at 10:50 AM, Galen O'Sullivan <
>>>> gosulli...@apache.org
>>>>>> 
>>>>>> wrote:
>>>>>> 
>>>>>>> Hi all,
>>>>>>> 
>>>>>>> I've noticed a pattern in Geode where we wrap a log call in a
>>> check
>>>> at
>>>>>> the
>>>>>>> same level, such as:
>>>>>>> 
>>>>>>>    if (logger.isDebugEnabled()) {
>>>>>>>          logger.debug("cleaning up incompletely started
>>>>>>> DistributionManager due to exception", r);
>>>>>>>        }
>>>>>>> 
>>>>>>> Is there any reason to do this? To my mind, it's an extra
>>> conditional
>>>>>> that
>>>>>>> should essentially be the first check inside `logger.debug(...)`
>>>>> anyways,
>>>>>>> and it complicates the code and makes it less readable. I've even
>>>> seen
>>>>>>> places in the code which have `if (logger.isDebugEnabled())
>>>>>>> logger.trace(...))` and such.
>>>>>>> 
>>>>>>> I would like to propose that unless there is a compelling reason
>>> to
>>>> use
>>>>>>> this pattern, we remove all extra checks entirely.
>>>>>>> 
>>>>>>> Galen
>>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>>> 
>> 
>> 

Reply via email to