-
Notifications
You must be signed in to change notification settings - Fork 25.7k
Fix test clusters to respect user-provided ordering of settings. #137179
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
Conversation
This is necessary when configuring dependent settings, such as loggers.
|
Pinging @elastic/es-core-infra (Team:Core/Infra) |
|
Isn't the framework just writing out the settings to |
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.
We can certainly make this change but as you say, relying on this implicit behavior isn't ideal. Also, you're going to get unexpected results if you mix different APIs here since we evaluate SettingsProviders late and then merge the results so in an example like this, you might not get the ordering you expect:
.setting("my.other.setting", "bar")
.setting("my.setting", () -> "foo") // deferred
|
Actually looks like it's even more complicated since you can mix settings at the cluster or node level. Here's how the order of precedence works. Keep in mind this is primarily in terms of which settings (if overriden) actually make it to Line 247 in 664a604
|
@rjernst Yes, and there's the issue. When writing the map entries that happens in a stable, but from a users's perspective random order. I'm not sure if there's other dependent settings where ordering could be a problem as well.
ES looks at these one by one in isolation, in the provided (random) order. Currently we're not able to influence that order in tests due to the way elasticsearch.yml is written. We could of course track the loggers we've already applied to avoid overwriting these. Or alternatively sort them and apply in the right order here elasticsearch/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java Lines 196 to 215 in 5e61b1e
|
Thanks @mark-vieira, I think that makes this an invalid approach. This needs to be done in ES as @rjernst said. I'll open a PR to propose another approach. |
| Loggers.LOG_LEVEL_SETTING.getAllConcreteSettings(settings) | ||
| // do not set a log level for a logger named level (from the default log setting) | ||
| .filter(s -> s.getKey().equals(Loggers.LOG_DEFAULT_LEVEL_SETTING.getKey()) == false) | ||
| .sorted(Comparator.comparing(Setting::getKey)) |
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.
Just for demonstration, currently we'd have to do something like this. This is unfortunate, internally everything is already sorted, but that's lost when generating the keySet.
Something similar would need to be done in ClusterSettings.LoggingSettingUpdater. The code there however doesn't use concrete settings and follows a different strategy. Very easy to get inconsistent behavior that way :/
This could benefit a lot from a more through redesign
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.
Instead of ordering these, could we keep track of whether a particular logger has an overridden level, or inherits it? Then regardless of which order we process updating, we can decide only to apply/descend into a logger if it is inheriting. Concretely imagine we are setting two log levels:
logger.foo.bar.baz: TRACE
logger.foo.bar: DEBUG
With the current code we would first set foo.bar.baz to trace, but then incorrectly override it to debug when processing the second logging setting. This happens because we blindly descend from foo.bar to set debug level. Ideally we could just look at the logger to see if it has an explicit level. Unfortunately we set the level at each part of the hierarchy, see #20463.
My thought is if we could keep track of something like the explicit level (but that knows about our descent when setting levels), we could skip by that part of the hierarchy, eg foo.bar.baz if we see an explicit level already set.
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.
Another relevant past issue/discussion I found: #65208
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 came up in #137149 after migrating ILM REST tests away from the legacy framework.
If configuring dependent loggers, it's important to respect the provided ordering. If
logger.org.elasticsearch.xpack.ilmis applied afterlogger.org.elasticsearch.xpack.ilm.history.ILMHistoryStore, the latter will be removed / overwritten:I'm a bit torn, relying on ordering is always a bit fragile. But at the same time I see the value of being able to do the above easily.