Skip to content
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 an IndexSettingsProvider to inject logsdb index mode #113505

Conversation

salvatore-campagna
Copy link
Contributor

@salvatore-campagna salvatore-campagna commented Sep 25, 2024

Here we introduce a new implementation of IndexSettingProvider whose goal is to "inject" the
index.mode setting with value logsdb when a cluster setting cluster.logsdb.enabled is true.
We also make sure that:

  • the existing index.mode is not set
  • the datastream name matches the logs-*-* pattern
  • logs@settings component template is used

Resolves #113507

@salvatore-campagna salvatore-campagna added >non-issue auto-backport-and-merge Automatically create backport pull requests and merge when ready :StorageEngine/Logs You know, for Logs v8.16.0 v9.0.0 labels Sep 25, 2024
@salvatore-campagna salvatore-campagna self-assigned this Sep 25, 2024
private static final PatternMatcher logsNameMatcher = PatternMatcher.forLogs();

public static final Setting<Boolean> CLUSTER_INDEX_MODE_LOGSDB_ENABLED = Setting.boolSetting(
"cluster.index.mode.logsdb.enabled",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to use a different setting to avoid reusing an existing one. I think it would be better to remove the cluster.logsdb.enabled setting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is wrong with the existing setting? Maybe just move it to here?

Copy link
Contributor Author

@salvatore-campagna salvatore-campagna Sep 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I see the following issues:

  • if we use the existing one and keep the old behaviour we would have a single setting controlling two different things, the index setting provider injection logic and the logs@setting template injection
  • if we use the existing one and remove the old behaviour (from logs@settings) than the behaviour of the setting will change with elasticsearch version...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old mechanism doesn't work and I think we should remove it. Integrations can either hardcode index.mode=logsdb in index templates or they can rely on this index settings provider to enable logsdb.

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few comments. Like we discussed this index settings provider should move to do soon to be added logsdb xpack plugin.


import java.util.regex.Pattern;

public class PatternMatcher {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed. We already have logic that deals with pattern matches for index templates. I think just using is good enough: Regex.simpleMatch(logs-*-*, dataStreamName)`

return Settings.EMPTY;
}

final IndexMode indexMode = resolveIndexMode(settings.get("index.mode"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to overwrite index mode, even if index.mode=standard is set. I think we should only resolve it when it isn't defined. So maybe just check if index.mode is set and only then based on data stream name decide whether logsdb index mode should be used?

Copy link
Contributor Author

@salvatore-campagna salvatore-campagna Sep 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that the IndexSettingsProvier mechanism kicks in after template composition happens...if we do what you suggest and the template composition completes with index.mode: standard than we would not overwrite it with logsdb. Is this what we want?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we should only configure index.mode to logsdb when it hasn't been set already.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's only set index.mode to logsdb when no index mode has been provided?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final IndexMode indexMode = resolveIndexMode(settings.get("index.mode"));
        if (indexMode != null) {
            return Settings.EMPTY;
        }

This is what I do...I check it for null

private static final PatternMatcher logsNameMatcher = PatternMatcher.forLogs();

public static final Setting<Boolean> CLUSTER_INDEX_MODE_LOGSDB_ENABLED = Setting.boolSetting(
"cluster.index.mode.logsdb.enabled",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is wrong with the existing setting? Maybe just move it to here?

);
private boolean isLogsdbEnabled;

public LogsdbIndexModeSettingsProvider(final ClusterService clusterService) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the ClusterService dependency from this class? This would make unit testing this class easier.
We can do clusterService.getClusterSettings().addSettingsUpdateConsumer(...) from the plugin class. The setter is already defined here.

@salvatore-campagna salvatore-campagna requested a review from a team as a code owner September 25, 2024 22:43
Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the PR title based on a previous implementation? I do not see anything called an IndexSettingsProvider here?

@@ -514,7 +514,7 @@ private SettingsModule validateSettings(Settings envSettings, Settings settings,
// so we might be late here already
SettingsModule settingsModule = new SettingsModule(
settings,
additionalSettings,
additionalSettings.stream().distinct().collect(Collectors.toList()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? We should not have duplicate settings

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I don't think a change to this file is needed.

Copy link
Contributor Author

@salvatore-campagna salvatore-campagna Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a setting cluster.logsdb.enabedl which is used by StackPlugin and LogsDBPlugin, and which is returned by method getSettings by both. SO I have two options here:

  1. I deduplicate the additional settings as done here.
  2. I return the setting only from one of the plugins.

I saw the code in NodeConstruction passing these settings to the SettingsModule and I see the logic to register settings which does not allow duplicates. Some of my tests were failing before introducing this change because of the exception thrown while registering duplicate settings. I see the logic uses a list of settings rather than a set which tells me that for some reason duplicates are not expected.

For my understanding would be useful to know why duplicates are not expected. Of course it is clear to me that registering duplicate settings would be incorrect...but I don't see what is wrong in deduplicating them before registration happens. Probably because we would not know which one is registered and which one is removed...?

Also I wonder if it is possible to have multiple instances of the same plugin...which would result in duplicate settings too. I imagine not. (My knowledge here is a bit limited TBH).

@rjernst what is the right way to proceed? Is there any reason why we can't return the same settings from two different plugins and deduplicate. SHould I go for option 2 above and just return the setting from one of them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I return the setting only from one of the plugins.

This is the only option. Registering the same setting twice isn't allowed because this would allow for leniency.

@@ -514,7 +514,7 @@ private SettingsModule validateSettings(Settings envSettings, Settings settings,
// so we might be late here already
SettingsModule settingsModule = new SettingsModule(
settings,
additionalSettings,
additionalSettings.stream().distinct().collect(Collectors.toList()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I don't think a change to this file is needed.

@@ -0,0 +1,26 @@
{
Copy link
Member

@martijnvg martijnvg Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this template added?

Copy link
Contributor Author

@salvatore-campagna salvatore-campagna Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new logs@settings-logsdb template is required because we can have two cases:

  1. "mode": "logsdb" when logsdb is enabled
  2. no index.mode at all. In LogsdbIndexModeSettingsProvider the logic expects to have empty/null index.mode to inject the "logsdb" index mode.

The way it is the template now always assigns index.mode a value, "logsdb" or "standard". As a result injection would never work in LogsdbIndexModeSettingsProvider.

I believe if this setting does not work in StackTemplateRegistry is it better to remove it...despite requiring more work...especially because some tests might rely on it. If you agree I would do the removal in a separate PR to keep the scope of this one a bit more limited.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so we said we temporarily add this template file so the xpack.stack.template.logsdb.index.mode template variable can be removed. Otherwise standard would always be set as index mode and there is no way to know whether this was set specifically or a default.

After this PR is merged we will remove the cluster.logsdb.enable setting logic and this templayte from the stack module. Which makes reviewing that change easier to review.

}

private IndexMode resolveIndexMode(final String mode) {
return mode == null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is a need here to use streams api. Maybe just do:

 IndexMode indexMode = mode != null ? Enum.valueOf(IndexMode.class, mode(Locale.ROOT)) : null;

Since we read mode variable from settings, it can only have valid values.

if (composableIndexTemplate == null) {
return false;
}
return composableIndexTemplate.composedOf()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe replace this with a for loop?

}

public void updateClusterIndexModeLogsdbEnabled(boolean isLogsdbEnabled) {
logger.debug("LogsDB " + (isLogsdbEnabled ? "enabled" : "disabled"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe remove this debug log statement? The setting infrastructure already emits an info log when cluster settings are updated.

@@ -14,6 +14,8 @@
import java.util.Collection;
import java.util.List;

import static org.elasticsearch.xpack.cluster.settings.ClusterSettings.CLUSTER_LOGSDB_ENABLED;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe undo this change? It isn't needed and reduce that files this PR touches.

Copy link
Contributor Author

@salvatore-campagna salvatore-campagna Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I undo this I need to register the setting in LogsDBPlugin...is that what you are asking? I guess so if the plan is to remove it from StackTemplateRegistry.

return Settings.EMPTY;
}

final IndexMode indexMode = resolveIndexMode(settings.get("index.mode"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use IndexSetting.MODE.getKey() instead of index.mode directly?

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are three outstanding comments, otherwise LGTM.

List.of(new CompressedXContent(DEFAULT_MAPPING))
);

assertIndexMode(additionalIndexSettings, null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case the returned settings should be empty. Maybe assert whether additionalIndexSettings.isEmpty() is true instead?

Maybe all assertIndexMode(additionalIndexSettings, null); imstances can be replaced with assertTrue(additionalIndexSettings.isEmpty())

this.isLogsdbEnabled = CLUSTER_LOGSDB_ENABLED.get(settings);
}

public void updateClusterIndexModeLogsdbEnabled(boolean isLogsdbEnabled) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This methods visibility can also be package protected?

}

if (usesLogsAtSettingsComponentTemplate(metadata, dataStreamName) && matchesLogsPattern(dataStreamName)) {
return Settings.builder().put("index.mode", IndexMode.LOGSDB.getName()).build();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace "index.mode" with IndexSettings.MODE.getKey()`?

@salvatore-campagna
Copy link
Contributor Author

Is the PR title based on a previous implementation? I do not see anything called an IndexSettingsProvider here?

LogsdbIndexModeSettingsProvider implements IndexSettingProvider...there is no previous implementation.

@salvatore-campagna salvatore-campagna merged commit e2281a1 into elastic:main Sep 26, 2024
15 checks passed
@elasticsearchmachine
Copy link
Collaborator

💚 Backport successful

Status Branch Result
8.x

salvatore-campagna added a commit to salvatore-campagna/elasticsearch that referenced this pull request Sep 26, 2024
…stic#113505)

Here we introduce a new implementation of `IndexSettingProvider` whose goal is to "inject" the
`index.mode` setting with value `logsdb` when a cluster setting `cluster.logsdb.enabled` is `true`.
We also make sure that:
* the existing `index.mode` is not set
* the datastream name matches the `logs-*-*` pattern
* `logs@settings` component template is used
elasticsearchmachine pushed a commit that referenced this pull request Sep 26, 2024
…3505) (#113594)

Here we introduce a new implementation of `IndexSettingProvider` whose goal is to "inject" the
`index.mode` setting with value `logsdb` when a cluster setting `cluster.logsdb.enabled` is `true`.
We also make sure that:
* the existing `index.mode` is not set
* the datastream name matches the `logs-*-*` pattern
* `logs@settings` component template is used
salvatore-campagna added a commit that referenced this pull request Sep 30, 2024
After introducing #113505 we need to remove `cluster.logsdb.enabled` from
`StackPlugin` and `StackTemplateRegistry`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport-and-merge Automatically create backport pull requests and merge when ready >non-issue :StorageEngine/Logs You know, for Logs Team:StorageEngine v8.16.0 v9.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Change the mechanism to enable LogsDB
5 participants