-
Notifications
You must be signed in to change notification settings - Fork 25.1k
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
Introduce Log4j 2 #20235
Introduce Log4j 2 #20235
Conversation
This commit disables the logger usage checks as they will not be compatible with Log4j 2. This disabling is temporary, they will return.
This commit introduces Log4j 2 to the stack.
@@ -59,7 +59,7 @@ class PrecommitTasks { | |||
* use the NamingConventionsCheck we break the circular dependency | |||
* here. | |||
*/ | |||
precommitTasks.add(configureLoggerUsage(project)) | |||
// precommitTasks.add(configureLoggerUsage(project)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you at least add a comment with this linking to a followup issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know why log4j2 doesn't offer the obvious overload here? If not, have we created an issue with them to add it? Logger#trace(String message, Throwable t, Object... params);
Logger#debug(String message, Throwable t, Object... params);
// etc rather than forcing practically every use with an exception to awkwardly construct a |
@@ -31,6 +34,12 @@ | |||
*/ | |||
public class DeprecationLogger { | |||
|
|||
private final Logger logger; | |||
|
|||
public Logger getLogger() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is probably worth documenting why it is ok to let this thing leak from inside DeprecationLogger
. I feel like we shouldn't let it be public at all so users have to go through the special purpose deprecation logging methods so we can curate how they are used and what they do more carefully.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like you've combined about 6 PRs worth of stuff into one. Ultimately we want the this but for the sake of all that is holy can you make smaller ones next time? Like:
|
++ @nik9000 |
log4j2 has support for |
} catch (IllegalStateException e) { | ||
// ignored; it should be removed shortly | ||
} | ||
} | ||
|
||
logger.debug(formattedMsg); | ||
logger.warn(formattedMessage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes the way that our deprecation logging works today. It used to default to being silent by using debug. I do prefer this change, but I'm not sure if we should be making it as part of this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I strongly disagree with deprecation logging not being visible out of the box but if we do not want it in this PR I will remove it. What do @clintongormley, @nik9000, and @rjernst think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it should be visible out of the box.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I also strongly disagree with it being hidden by default; I just didn't want that to slip into this PR as it's not really related)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with changing it to warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After #20254, we have consensus to do this out-of-the-box by default, and I will configure the deprecation logger to be size-limited.
Unless it parses the first param as the exception, which would be confusing, it's missing that overload. For loggers that don't have an exception, I strongly prefer that overload versus instantiating a |
I believe that can't work b/c the variant that supports an exception and varargs was removed in log4j2. However, I think instead we could use the Supplier+exception variant? |
I didn't catch that the first time around. Thanks for pointing that out. |
This commit modifies the call sites that allocate a parameterized message to use a supplier so that allocations are avoided unless the log level is fine enough to emit the corresponding log message.
This commit adds a missing cast to logging message supplier on a single invocation receiving a parameterized message parameter.
@@ -106,7 +107,7 @@ public void onNoLongerMaster(String source) { | |||
|
|||
@Override | |||
public void onFailure(String source, Exception e) { | |||
logger.error(new ParameterizedMessage("unexpected failure during [{}]", source), e); | |||
logger.error((Supplier<?>) () -> new ParameterizedMessage("unexpected failure during [{}]", source), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't help but wonder if we shouldn't have a static helper function that does this for us?
public static Supplier<ParameterizedMessage> message(String message, Object... params) {
return () -> new ParameterizedMessage(message, params);
}
EDIT: forgot the () ->
in the return
.
It's of course another import, but it will probably be better than staring at (Supplier<?>) () -> new ParameterizedMessage(...)
in so many places.
This commit fixes failing evil logger tests. The tests were failing after inadvertently configuring appenders on the parent and child logger.
@@ -105,7 +107,7 @@ public void onNoLongerMaster(String source) { | |||
|
|||
@Override | |||
public void onFailure(String source, Exception e) { | |||
logger.error("unexpected failure during [{}]", e, source); | |||
logger.error((Supplier<?>) () -> new ParameterizedMessage("unexpected failure during [{}]", source), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment got erased by the last commit. I can't help but wonder if we shouldn't have a static helper function that does this for us?
public static Supplier<ParameterizedMessage> message(String message, Object... params) {
return () -> new ParameterizedMessage(message, params);
}
It's of course another import, but it will probably be better than staring at (Supplier<?>) () -> new ParameterizedMessage(...)
in so many places and it removes both of those imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, but then we would want to at least have a lot of extra overrides to avoid allocating a varargs array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would be a lot cleaner than what it is here. It can probably be a secondary PR that happens in smaller waves though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that these overrides would then introduce boxing on any primitive arguments, and that is something that we want to avoid as well. I do not think it's feasible to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that's not any different than the current non-exception logging? log4j just creates a ton of overloads with Object
parameters too to avoid the params, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that's not any different than the current non-exception logging?
The whole point of going the org.apache.log4j.util.Supplier<?>
route was to avoid creating a new instance of ParameterizedMessage
if the log message is not going to be emitted. I don't think we want to go through this trouble to immediately turn around and trigger allocations from boxing and varargs (yes, the latter can be avoided with a lot of overrides but the former can not without adding silly overrides for every possible combination).
log4j just creates a ton of overloads with Object parameters too to avoid the params, right?
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which boxing are you referring to? I'm not seeing what would be boxed here (that would not have already been boxed with the old code)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rjernst The proposal from @pickypg is for a method
public static Supplier<ParameterizedMessage> message(String message, Object... params) {
return () -> new ParameterizedMessage(message, params);
}
This will cause an allocation of an Object[]
and all primitive arguments will be boxed to Object
s. Adding overrides like
public static Supplier<ParameterizedMessage> message(String message, Object p1, Object p2) {
return () -> new ParameterizedMessage(message, params);
}
removes the Object[]
allocation, but still any primitive arguments will be boxed to Object
s.
These allocations/boxing will occur regardless of whether or not the log level is fine enough to emit the corresponding log message.
With the (Supplier<?>) () -> new ParameterizedMessage("{}", o)
pattern (as in this PR) we avoid this boxing unless the log message is going to be emitted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but still any primitive arguments will be boxed to Objects.
But this would have been the case with the old methods as well (so nothing would be changing).
Having to do the cast makes logging a pain to use parameterized messages. While creatinga bunch of overloaded helpers may be a pain, maybe it is worth it. Or maybe having this pain will lead us to not depend on logging so much, so it could be good. :) I could go either way.
This commit fixes failing max map count check test due to the use of a logging message supplier.
This commit fixes failing evil logging configuration tests. The test for resolving multiple configuration files was failing after 9a58fc2 removed some of the configuration needed for this test. The solution is revert the removal of that configuration, but remove additivity from the test logger to prevent the evil logger tests from failing.
This commit adds comments linking to an open issue regarding updating the logger usage check for the Log4j 2 API.
This commit enables CLI tools to have console logging. For the CLI tools, we skip configuring the logging infrastructure via the config file, and instead set the level only via a system property.
* master: Increase visibility of deprecation logger Skip transport client plugin installed on JDK 9 Explicitly disable Netty key set replacement percolator: Fail indexing percolator queries containing either a has_child or has_parent query. Make it possible for Ingest Processors to access AnalysisRegistry Allow RestClient to send array-based headers Silence rest util tests until the bogusness can be simplified Remove unknown HttpContext-based test as it fails unpredictably on different JVMs Tests: Improve rest suite names and generated test names for docs tests Add support for a RestClient base path
This commit removes code references to logging.yml in TranslogToolCli and PluginCli.
This commit updates the logging docs for Elasticsearch to reflect the migration to Log4j 2.
This commit updates the packaging tests for Log4j 2. Namely, these tests make assertions about logging.yml that should now be about log4j2.properties.
@clintongormley Would you please review the docs in 750033d? |
* master: Avoid NPE in LoggingListener Randomly use Netty 3 plugin in some tests Skip smoke test client on JDK 9 Revert "Don't allow XContentBuilder#writeValue(TimeValue)" [docs] Remove coming in 2.0.0 Don't allow XContentBuilder#writeValue(TimeValue) [doc] Remove leftover from CONSOLE conversion Parameter improvements to Cluster Health API wait for shards (#20223) Add 2.4.0 to packaging tests list Docs: clarify scale is applied at origin+offest (#20242)
@nik9000 I've thought about this a lot since you left this comment and I've decided that I did the right thing here. What makes this PR so massive is the removal of |
@jasontedor Whether or not we decide to go with a helper for making parameterized messages, this change LGTM. I know this branch is a huge pain to maintain, so let's get it in, and have a followup discussion on whether/when/how to simplify logging pain points further? |
* master: Correct path.conf for integ-test-zip distribution
This commit modifies a pair of exception logging calls to use parameterized messages from Log4j.
LongGCDisruption simulates a Long GC by suspending all threads belonging to a node. That's fine, unless those threads hold shared locks that can prevent other nodes from running. Concretely the logging infrastructure, which is shared between the nodes, can cause some deadlocks. LongGCDisruption has protection for this, but it needs to be updated to point at log4j2 classes, introduced in elastic#20235 This commit also fixes improper handling of retry logic in LongGCDisruption and adds a protection against deadlocking the test code which activates the disruption (and uses logging too! :)). On top of that we have some new, evil and nasty tests.
LongGCDisruption simulates a Long GC by suspending all threads belonging to a node. That's fine, unless those threads hold shared locks that can prevent other nodes from running. Concretely the logging infrastructure, which is shared between the nodes, can cause some deadlocks. LongGCDisruption has protection for this, but it needs to be updated to point at log4j2 classes, introduced in #20235 This commit also fixes improper handling of retry logic in LongGCDisruption and adds a protection against deadlocking the test code which activates the disruption (and uses logging too! :)). On top of that we have some new, evil and nasty tests.
LongGCDisruption simulates a Long GC by suspending all threads belonging to a node. That's fine, unless those threads hold shared locks that can prevent other nodes from running. Concretely the logging infrastructure, which is shared between the nodes, can cause some deadlocks. LongGCDisruption has protection for this, but it needs to be updated to point at log4j2 classes, introduced in #20235 This commit also fixes improper handling of retry logic in LongGCDisruption and adds a protection against deadlocking the test code which activates the disruption (and uses logging too! :)). On top of that we have some new, evil and nasty tests.
LongGCDisruption simulates a Long GC by suspending all threads belonging to a node. That's fine, unless those threads hold shared locks that can prevent other nodes from running. Concretely the logging infrastructure, which is shared between the nodes, can cause some deadlocks. LongGCDisruption has protection for this, but it needs to be updated to point at log4j2 classes, introduced in #20235 This commit also fixes improper handling of retry logic in LongGCDisruption and adds a protection against deadlocking the test code which activates the disruption (and uses logging too! :)). On top of that we have some new, evil and nasty tests.
This pull request introduces Log4j 2, replacing the existing Log4j
implementation. With this pull request:
configuration directly
directly
There are two TODOs that I will address, but I think that reviews should
get started:
There is a follow-up item to update the logger usage checks to work
against Log4j 2, but that will be outside the scope of this PR.
Closes #16030, closes #17697