-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
logger.isTraceEnabled() is returning true in native mode, regardless of log level defined #2223
Comments
I will check if I see the same issue if I configure the root logger, and not just the console logger |
The |
@dmlloyd what is the default log category? I have tried setting |
Can you share your whole configuration? |
|
Normally the log level is inherited from enclosing category to enclosed category. However the log configuration that is actually used at run time is an accumulation of log levels set by configuration and by extensions. In particular there is a possibility that some log categories are being overridden for some reason. Another possibility is that there is simply a bug, in logging or in SVM itself. I'm working on a code change that will allow us to easily examine the complete run time logging configuration. Hopefully it will only take me an hour or two to put it together. |
@johnaohara can you build with #2228 included, then set |
I ran with a build of #2228 and this is the output; https://gist.github.com/johnaohara/e0877d60118a4393135b1a9eda7cacbd I also ran a simple byteman rule;
In JVM mode, the rule logged;
In Native mode, the rule logged;
|
@dmlloyd Have been debugging another native image issue today, and have logged these exceptions during a native image build;
When I start the process in JVM mode, I do not see those NoSuchMethodException java.util.logging.* classes |
That's very interesting, especially considering that:
This tells us that |
That's pretty normal I think. Native image mode aggressively initializes classes that might not be initialized in JVM mode, so it's possible that extra probing is happening; based on the methods reported I'd say that it's probably MP-config probing the classes to establish implicit converters. Though the |
Just to get into a little more detail here - this field was probably created to avoid repeated calls of |
hi @dmlloyd , allow me to confirm a bit of history. My knowledge might be out of date, happy to change things but I'd be careful with that. we have witnessed some performance issues with The decision back then (maybe it's out of date?) for both the Hibernate and Infinispan project was to not consider "trace" as a level that could be changed at runtime. Essentially, the alternative in these cases was to just get rid of the logging message altogether - we decided for this tradeoff as they are useful during development. |
I'd say it's out of date, probably. The level checks should normally be inlined by JIT as they are monomorphic and below even small thresholds for size; it should boil down to a single volatile field read. In any event, it's definitely a performance problem now, so... :) |
@Sanne @dmlloyd I currently have a 5.4.2 build with isTraceEnabled() caching removed. I am running a native test atm, which is showing an improvement in throughput. I will run a JVM test comparing 5.4.2 with caching and 5.4.2 without caching. I can also double check that calls to isTraceEnebaled() are being inlined. |
well Quarkus is not the only runtime we have to support, and also Quarkus will need to support other libraries which might want to do similar things, so I don't think "dodging" such a problem by having ORM change its code is the right approach.
we know that, still this problem we had wasn't too old, maybe just one year ago, so there's more to it. Anyhow: this is a widespread practice in several libraries. If we decide it's time to revert such ideas, it's going to take some time to spot all such cases. |
@stalep remembers more details maybe ? ^ |
Maybe. Hopefully John will turn up some more information.
It will have to be, unfortunately. Caching these in static fields will never work in GraalVM due to its class initialization rules. Even if it were moved to runtime init, the log level isn't decided until after logging is initialized, which happens after the configuration is read. So it would still have the same problem in this case, because AFAIK class init isn't lazy even if it's deferred to runtime with GraalVM. If we want to have some kind of support for constant-folded level checking, we could possibly reestablish the |
good point re class initialization. I'm happy to merge @johnaohara fixes to ORM upstream, just keep in mind that we'll eventually find many more of such cases (and not exclusive to Hibernate) so if you all find a better solution in the future that would rock. In particular, we could set Log categories to silent during native-image build? I know it's not correct in the general sense, but AFAIK all such cases are to disable the lowest levels only so it would be a good help with general perf. |
Have chatted with Will Reichert on the perf team. Back in 2014, running specj Enterprise 2010, we observed
There were also a large number of calls to This was the PR that was opened to track the hibernate changes: https://hibernate.atlassian.net/browse/HHH-8942 Unfortunately, we do not have the jfr profiles any longer that showed this issue at the time. It is probably worth analysing the cost/benefit to directly call isXXXEnabled() under load again. |
I'm a bit late to this thread, I remember we added static booleans for logging in hibernate since the |
@gsmet are you going to create a PR to upgrade hibernate and link to this issue? thanks |
Yes. I haven’t started the ORM release yet. I have a personal emergency. I’ll do it tomorrow but sure I will upgrade for 0.16.0. |
Re-opening: #2672 didn't fix the problem, we simply avoid it affecting Hibernate ORM but there's several more libraries (and possibly user code) that could be affected. |
Perhaps we need a feature which registers an error during image build if any |
Isn't it very common to invoke such methods? we do it all the time.. |
IMHO these methods should only be used rarely, e.g. to fix some performance issue in a critical path or when it's expensive to create a log message. Because it's error prone - you need to keep those invocations in sync - e.g. |
I was thinking only of image build time - during static initialization - but I guess these methods could legitimately be called at that time as well. What we'd have to detect is one of these methods called during static init, whose value was also immediately stored into a final field. Maybe a substrate feature would be more effective - and in this case we could maybe automatically inline these fields... |
Is this still an issue? It looks like it was solved in #13376 |
I am pretty sure this has been fixed so I'll close it. |
I have found that native for native applications logger.isTraceEnabled() returns true regardless of logging level defined in application.properties
For example;
I had configured logging to INFO level,
we should not have reached this method call; : https://github.com/hibernate/hibernate-orm/blob/5.4.2/hibernate-core/src/main/java/org/hibernate/loader/entity/CacheEntityLoaderHelper.java#L281
The trace message is not written to the console, but we have the overhead of generating the trace messages.
I do not see this behaviour in JVM mode, in JVM profiling these calls do not appear
The text was updated successfully, but these errors were encountered: