-
Notifications
You must be signed in to change notification settings - Fork 25k
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
Write deprecation logs to a data stream #58924
Closed
pugnascotia
wants to merge
66
commits into
elastic:master
from
pugnascotia:index-deprecation-logs-v2
Closed
Changes from 7 commits
Commits
Show all changes
66 commits
Select commit
Hold shift + click to select a range
36ac092
Introduce DeprecationIndexingService
pugnascotia cf5a677
First go at ensuring the data stream template is loaded
pugnascotia 86c3d7d
Tweaks index name
pugnascotia d74dc9a
WIP - Adding tests for DeprecationIndexingService
pugnascotia 6457f97
More tests
pugnascotia f0e0192
Fix template index pattern
pugnascotia 581be1f
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 14c929a
Rework deprecation code so that log handlers are more generic
pugnascotia e902fb9
Move DeprecationIndexingService to x-pack depreacation plugin
pugnascotia 40bea2c
Don't need a custom template any more :tada:
pugnascotia 013bf55
Remove unused import
pugnascotia 4c189da
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia d61b145
License header fix
pugnascotia ae62d06
Remove unused imports
pugnascotia 32d8316
Add Javadoc
pugnascotia 25ea88f
Silence log checker error
pugnascotia dce2a5d
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 3482d31
Subtitute log message params, simplify things
pugnascotia 34e5529
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia f7f9ea7
Fixes
pugnascotia 46c5aca
Use BulkProcessor in DeprecationIndexingService
pugnascotia c8d8086
Use the opaque ID from the EsLogMessage
pugnascotia 4bf9b34
Record cluster and node IDs
pugnascotia 75eac35
Tweaks
pugnascotia abd8381
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 8e4339f
WIP - trying a log4j implementation
pugnascotia d33b72b
Reimplement deprecation logging using log4j
pugnascotia 379ca5d
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 4aead94
Reimplement using log4j abstractions
pugnascotia e8d246b
Polishing
pugnascotia 31ff5fe
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 95e3fc3
More polishing
pugnascotia c0b8f65
Include key in DeprecatedMessage.of(...)
pugnascotia 07c34cc
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia d6a75bd
Strip out UnionFilter
pugnascotia 074ef8d
Build deprecation msg docs using EcsJsonLayout
pugnascotia 516ce6d
Checkstyle
pugnascotia a750f49
Update docker log4j configs
pugnascotia 2352a20
Fix libs tests
pugnascotia 3b80fdd
Configure HeaderWarningAppender in ESTestCase
pugnascotia 1a3f2da
Fix docker log4j deprecation levels
pugnascotia 3db6c7a
Test fixes
pugnascotia edd0466
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 0d70f53
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 5529912
WIP - trying to write an integration test
pugnascotia 3452367
Implement indexing test
pugnascotia d17a5e8
WIP - trying to rewrite DeprecationHttpIT as a rest test
pugnascotia 8f70584
Tests execute against custom plugin, but need fixed
pugnascotia 4f6f501
Rework deprecation HTTP tests
pugnascotia 98def13
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 97f4934
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 26a3495
Tweaks
pugnascotia c070571
Merge branch 'index-deprecation-logs-v2-tests' into index-deprecation…
pugnascotia 022793e
Fix tests finally, by resetting the rate limiting filter
pugnascotia d8eee69
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia afc4dcf
Add test
pugnascotia 2d1d3fb
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 3c8069b
Fix license checks
pugnascotia 2dac9a3
Formatting
pugnascotia f0f3edb
Remove redundant line
pugnascotia 9877d57
Merge branch 'master' into index-deprecation-logs-v2
elasticmachine 1309355
Remove unused import
pugnascotia bd8e3c9
Merge remote-tracking branch 'upstream/master' into index-deprecation…
pugnascotia 76993c9
Add warning headers solely through the log4j appender
pugnascotia e695753
Merge branch 'master' into index-deprecation-logs-v2
elasticmachine 3ff1015
Fixes to JsonLoggerTest
pugnascotia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
154 changes: 154 additions & 0 deletions
154
server/src/main/java/org/elasticsearch/common/logging/DeprecationIndexingService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package org.elasticsearch.common.logging; | ||
|
||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.elasticsearch.action.ActionListener; | ||
import org.elasticsearch.action.DocWriteRequest; | ||
import org.elasticsearch.action.admin.indices.template.put.PutComposableIndexTemplateAction; | ||
import org.elasticsearch.action.index.IndexAction; | ||
import org.elasticsearch.action.index.IndexRequestBuilder; | ||
import org.elasticsearch.action.index.IndexResponse; | ||
import org.elasticsearch.action.support.master.AcknowledgedResponse; | ||
import org.elasticsearch.client.Client; | ||
import org.elasticsearch.client.OriginSettingClient; | ||
import org.elasticsearch.cluster.ClusterChangedEvent; | ||
import org.elasticsearch.cluster.ClusterStateListener; | ||
import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; | ||
import org.elasticsearch.cluster.service.ClusterService; | ||
import org.elasticsearch.common.settings.Setting; | ||
import org.elasticsearch.common.xcontent.NamedXContentRegistry; | ||
import org.elasticsearch.common.xcontent.XContentParser; | ||
import org.elasticsearch.common.xcontent.json.JsonXContent; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.time.Instant; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static org.elasticsearch.common.Strings.isNullOrEmpty; | ||
|
||
/** | ||
* This service is responsible for writing deprecation messages to a data stream. It also creates | ||
* the data stream if necessary. The writing of messages can be toggled using the | ||
* {@link #WRITE_DEPRECATION_LOGS_TO_INDEX} setting. | ||
*/ | ||
public class DeprecationIndexingService implements ClusterStateListener { | ||
private static final Logger LOGGER = LogManager.getLogger(DeprecationIndexingService.class); | ||
|
||
private static final String DATA_STREAM_NAME = "logs-deprecation-elasticsearch"; | ||
private static final String TEMPLATE_NAME = DATA_STREAM_NAME + "-template"; | ||
private static final String TEMPLATE_MAPPING = TEMPLATE_NAME + ".json"; | ||
|
||
private static final String DEPRECATION_ORIGIN = "deprecation"; | ||
|
||
public static final Setting<Boolean> WRITE_DEPRECATION_LOGS_TO_INDEX = Setting.boolSetting( | ||
"cluster.deprecation_indexing.enabled", | ||
true, | ||
Setting.Property.NodeScope, | ||
Setting.Property.Dynamic | ||
); | ||
|
||
private final Client client; | ||
private boolean hasTriedToLoadTemplate = false; | ||
private volatile boolean isEnabled = false; | ||
|
||
public DeprecationIndexingService(ClusterService clusterService, Client client) { | ||
this.client = new OriginSettingClient(client, DEPRECATION_ORIGIN); | ||
|
||
clusterService.addListener(this); | ||
} | ||
|
||
/** | ||
* Indexes a deprecation message. | ||
* @param key the key that was used to determine if this deprecation should have been be logged. | ||
* Useful when aggregating the recorded messages. | ||
* @param message the message to log | ||
* @param xOpaqueId the associated "X-Opaque-ID" header value if any, or <code>null</code> | ||
* @param params parameters to the message, if any | ||
*/ | ||
public void writeMessage(String key, String message, String xOpaqueId, Object[] params) { | ||
if (this.isEnabled == false) { | ||
return; | ||
} | ||
|
||
Map<String, Object> payload = new HashMap<>(); | ||
pugnascotia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
payload.put("@timestamp", Instant.now().toString()); | ||
payload.put("key", key); | ||
payload.put("message", message); | ||
pugnascotia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (isNullOrEmpty(xOpaqueId) == false) { | ||
payload.put("x-opaque-id", xOpaqueId); | ||
} | ||
|
||
if (params != null && params.length > 0) { | ||
payload.put("params", params); | ||
} | ||
|
||
new IndexRequestBuilder(client, IndexAction.INSTANCE).setIndex(DATA_STREAM_NAME) | ||
pugnascotia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.setOpType(DocWriteRequest.OpType.CREATE) | ||
.setSource(payload) | ||
.execute(new ActionListener<>() { | ||
@Override | ||
public void onResponse(IndexResponse indexResponse) { | ||
// Nothing to do | ||
} | ||
|
||
@Override | ||
public void onFailure(Exception e) { | ||
LOGGER.error("Failed to index deprecation message", e); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Listens for changes to the cluster state, in order to know whether to toggle indexing. | ||
*/ | ||
@Override | ||
public void clusterChanged(ClusterChangedEvent event) { | ||
this.isEnabled = WRITE_DEPRECATION_LOGS_TO_INDEX.get(event.state().getMetadata().settings()); | ||
|
||
if (this.isEnabled == false || this.hasTriedToLoadTemplate == true) { | ||
return; | ||
} | ||
|
||
// We only ever try to load the template once, because if there's a problem, we'll spam | ||
// the log with the failure on every cluster state update | ||
this.hasTriedToLoadTemplate = true; | ||
|
||
if (event.state().getMetadata().templatesV2().containsKey(TEMPLATE_NAME)) { | ||
return; | ||
} | ||
|
||
loadTemplate(); | ||
} | ||
|
||
/* | ||
* Attempts to load a template for the deprecation logs data stream | ||
*/ | ||
private void loadTemplate() { | ||
pugnascotia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
try (InputStream is = getClass().getResourceAsStream(TEMPLATE_MAPPING)) { | ||
final XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, null, is); | ||
|
||
PutComposableIndexTemplateAction.Request request = new PutComposableIndexTemplateAction.Request(TEMPLATE_NAME); | ||
request.cause("auto (deprecation indexing service)"); | ||
request.indexTemplate(ComposableIndexTemplate.parse(parser)); | ||
|
||
this.client.execute(PutComposableIndexTemplateAction.INSTANCE, request, new ActionListener<>() { | ||
@Override | ||
public void onResponse(AcknowledgedResponse acknowledgedResponse) { | ||
if (acknowledgedResponse.isAcknowledged() == false) { | ||
LOGGER.error("The attempt to create a deprecations index template was not acknowledged."); | ||
} | ||
} | ||
|
||
@Override | ||
public void onFailure(Exception e) { | ||
LOGGER.error("Failed to create the deprecations index template: " + e.getMessage(), e); | ||
} | ||
}); | ||
} catch (IOException e) { | ||
LOGGER.error("Failed to load " + TEMPLATE_MAPPING + ": " + e.getMessage(), e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
server/src/main/java/org/elasticsearch/common/logging/RateLimiter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Licensed to Elasticsearch under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
package org.elasticsearch.common.logging; | ||
|
||
import java.util.Collections; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* <p> | ||
* This class limits the number of times that actions are carried out. | ||
* <p> | ||
* The throttling algorithm relies on a LRU set of keys, which evicts entries when its size exceeds 128. | ||
* When a {@code key} is seen for the first time, the {@code runnable} will be executed, but then will not be | ||
* executed again for that key until the key is removed from the set. | ||
*/ | ||
class RateLimiter { | ||
|
||
// LRU set of keys used to determine if a message should be emitted to the logs | ||
private final Set<String> keys = Collections.newSetFromMap(Collections.synchronizedMap(new LinkedHashMap<>() { | ||
@Override | ||
protected boolean removeEldestEntry(final Map.Entry<String, Boolean> eldest) { | ||
return size() > 128; | ||
} | ||
})); | ||
|
||
void limit(String key, Runnable runnable) { | ||
boolean shouldRun = keys.add(key); | ||
if (shouldRun) { | ||
runnable.run(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 0 additions & 79 deletions
79
server/src/main/java/org/elasticsearch/common/logging/ThrottlingLogger.java
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Should the setting allow to flex between writing to a log, an index, or both ?