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

Header warning logging refactoring #55941

Merged
merged 33 commits into from
Jun 1, 2020
Merged

Conversation

pgomulka
Copy link
Contributor

@pgomulka pgomulka commented Apr 29, 2020

Splitting DeprecationLogger into two. HeaderWarningLogger - responsible for adding a response warning headers and ThrottlingLogger - responsible for limiting the duplicated log entries for the same key (previously deprecateAndMaybeLog).
Introducing A ThrottlingAndHeaderWarningLogger which is a base for other common logging usages where both response warning header and logging throttling was needed.

relates #55699
relates #52369

@pgomulka pgomulka added WIP :Core/Infra/Logging Log management and logging utilities labels Apr 29, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (:Core/Infra/Logging)

@elasticmachine elasticmachine added the Team:Core/Infra Meta label for core/infra team label Apr 29, 2020
@pgomulka pgomulka removed the WIP label May 4, 2020
@pgomulka pgomulka changed the title WIP Header warning logging refactoring Header warning logging refactoring May 4, 2020
@pgomulka pgomulka marked this pull request as ready for review May 4, 2020 12:45
/**
* Logs a message, adding a formatted warning message as a response header on the thread context.
*/
public void headerWarnAndLog(String msg, Object... params) {
Copy link
Contributor

@jakelandis jakelandis May 5, 2020

Choose a reason for hiding this comment

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

can we make this just logAndHeader I think that is different enough from info, warn etc. and you can always look up at the type of logger.

Copy link
Contributor

@jakelandis jakelandis May 5, 2020

Choose a reason for hiding this comment

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

can we also expose a log and a header method ? log = logfile, warn = header

Copy link
Contributor

Choose a reason for hiding this comment

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

ninja edit - s/warn/header (in case the comments here don't line up with the contents in the email updates)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agree - log and header method will be useful too. Not sure about the header method name though #55941 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hm at the same time there is no usage for just log/header on its own at the moment.
maybe let's keep that class small for now and add methods as the need arise?

}
}

public void log(String msg, Object... params) {
Copy link
Contributor

@jakelandis jakelandis May 5, 2020

Choose a reason for hiding this comment

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

can this be header instead of log ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hm not sure about this one. Wouldn't some verb be better here? addHeader? addHeaderWarning?
or maybe simply log as it is now. The class name and the field name should express the intent

} else {
return ch;
}
public void deprecatedAndMaybeLog(final String key, final String msg, final Object... params) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jakelandis I am also considering renaming these as deprecatedAndMaybe is not clear enough
I think this should be just throttleLogAndWarnOnHeader and logAndWarnOnHeader
the destination -deprecation log - is clear from the name of the field and class

@jakelandis
Copy link
Contributor

We discussed this a bit more in person and came to the following conclusions. This refactoring servers two purposes a) expose the ability to emit HTTP warnings back to the client outside of deprecations e.g. #55699 b) provide a means to expose compatibility logging which is very similar to deprecation logging, but slightly different.

a) This PR will pull apart the HTTP warming emitter code and allow users to use it separately from the deprecation logger. Something like httpWarning.addEntry("http warning"); This will not go to the log file. We discussed possibly allowing this also go to the normal server log file, but throttled. However, there are some concerns about throttling messages messages to the main server log file since it could easily get lost and the server log and deprecation log server different purposes. We could at some future point introduce a throttled log message to the server, but will need more consideration then simply re-using what we have for the deprecation logger.

b) Deprecation logs and compatibility logs and highly related. A deprecation message might say [DELETE /_xpack/watcher/watch/{id}] is deprecated! Use [DELETE /_watcher/watch/{id}] instead, and compatibility log may say API request /_xpack/watcher/watch/{id} has been converted to /_watcher/watch/{id}. The deprecation tells you what is deprecated and what to do to fix, and the compatibility tells you what done by using the API compatibility. After some discussion we plan to represent both of these in the deprecation logfile, but with different types. For example:

{"type": "deprecation", x-opaque-id: "asfsdafsadfsdf", timestamp": "2020-05-05T15:43:44,034Z", "level": "INFO", "component": "o.e.d.x.w.r.a.RestDeleteWatchAction", "cluster.name": "monitor-cluster", "node.name": "es_monitor", "message": "[DELETE /_xpack/watcher/watch/{id}] is deprecated! Use [DELETE /_watcher/watch/{id}] instead.", "cluster.uuid": "XAfLzlIbTlqqEr4oT2W5QA", "node.id": "rCdN080aRoy94UcE7IT7KQ"  }
{"type": "compatibility", x-opaque-id: "asfsdafsadfsdf", "timestamp": "2020-05-05T15:43:44,034Z", "level": "INFO", "component": "o.e.d.x.w.r.a.RestDeleteWatchAction", "cluster.name": "monitor-cluster", "node.name": "es_monitor", "message": "API request /_xpack/watcher/watch/{id} has been converted to /_watcher/watch/{id}", "cluster.uuid": "XAfLzlIbTlqqEr4oT2W5QA", "node.id": "rCdN080aRoy94UcE7IT7KQ"  }

This allow for easy separation of the messages (as opposed to smashing the two texts to the same message), and does not occur any additional over head of managing yet another log file. To help developers introduce a compatibility message into the deprecation we plan to introduce a fluent api similar to :

deprecationLogger
	.deprecate("[DELETE /_xpack/watcher/watch/{id}] is deprecated! Use [DELETE /_watcher/watch/{id}] instead")
	.compatibility("API request /_xpack/watcher/watch/{id} has been converted to /_watcher/watch/{id}")
	.log(Logger.INFO)

So when a developer needs to add a compatibility message, it is easy as adding to the existing deprecrationLogger .

note - The above is a proposal and the final outcome may deviate

@@ -367,8 +366,7 @@ public ClusterState addIndexTemplateV2(final ClusterState currentState, final bo
.map(e -> e.getKey() + " => " + e.getValue())
.collect(Collectors.joining(",")),
name);
logger.warn(warning);
deprecationLogger.deprecatedAndMaybeLog("index_template_pattern_overlap", warning);
warningLogger.logAndAddWarning(warning);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is the usage of the refactoring from this PR.
this log line always log - to server - and adds a warning.
The type might be a bit confusing. Maybe this should 2 lines:

  1. to log to a server file - regular logger
  2. add a warning to a headers
    @jakelandis wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

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

++ for 2 lines. We should also probably make ThrottlingAndHeaderWarningLogger package private.

Copy link
Contributor

@jakelandis jakelandis left a comment

Choose a reason for hiding this comment

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

Changes are looking good. A couple minor comments.

@@ -67,6 +67,7 @@

@Override
public void setUp() throws Exception {
assert "false".equals(System.getProperty("tests.security.manager")) : "-Dtests.security.manager=false has to be set";
Copy link
Contributor

Choose a reason for hiding this comment

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

did this slip in, or is it intentional ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably not directly related to the refactoring, but it is useful when running this test from intellij to get that reminder. not obvious from just a failure message why the test failed

@@ -367,8 +366,7 @@ public ClusterState addIndexTemplateV2(final ClusterState currentState, final bo
.map(e -> e.getKey() + " => " + e.getValue())
.collect(Collectors.joining(",")),
name);
logger.warn(warning);
deprecationLogger.deprecatedAndMaybeLog("index_template_pattern_overlap", warning);
warningLogger.logAndAddWarning(warning);
Copy link
Contributor

Choose a reason for hiding this comment

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

++ for 2 lines. We should also probably make ThrottlingAndHeaderWarningLogger package private.

* This class wraps both <code>HeaderWarningLogger</code> and <code>ThrottlingLogger</code>
* which is a common use case across Elasticsearch
*/
public class ThrottlingAndHeaderWarningLogger {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we make this package private ?

*/
//TODO fix this
@SuppressLoggerChecks(reason = "safely delegates to logger")
public void logAndAddWarning(String msg, Object... params) {
Copy link
Contributor

Choose a reason for hiding this comment

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

as discussed in person, i think this can be removed since we only want to expose the Deprecation logger and the Header warning logger. We want to avoid general usaage of this class and if a user wants to always header warn they can use that method and throttling to the main server log is something that that requires more consideration.

}
}

void log(Message message) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think with the following comment: https://github.com/elastic/elasticsearch/pull/55941/files#r421840660 we can make this private.

args = new Object[] { "world", 43, "another argument" };
}
logger.info(message, args);
// public void checkArgumentsProvidedInConstructor() {
Copy link
Contributor

Choose a reason for hiding this comment

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

don't forget to uncomment :)

@pgomulka
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/2

@pgomulka
Copy link
Contributor Author

pgomulka commented May 14, 2020

@jakelandis I updated the PR as per comments. Re discussion on test cases - The additional throttling test cases for throttling are in JsonLoggerTests - they all pass now.
I made a note to myself with future refactoring (eliminating the key by caching call site and considering reducing garbage creation within fluent builder) on #49087

Copy link
Contributor

@jakelandis jakelandis left a comment

Choose a reason for hiding this comment

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

LGTM ( a couple optional minor doc comments )


/**
* This is a simplistic logger that adds warning messages to HTTP headers.
* It uses ThreadContext - which is assumed to be one per JVM (except for tests) - to store warning headers.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment (uses ThreadContext ...) is abit confusing. What do I need to do with that knowledge ?

Can you add a usage section to the doc ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agree, ThreadContext is an implementation detail. I will reword that javadoc

throw new IllegalStateException("Removing unknown ThreadContext not allowed!");
}
}
private final ThrottlingAndHeaderWarningLogger deprecationLogger;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you beef up the class level doc a little bit ? Just a quick mention that it does a throttle log (and what it throttling ..or link to the throttling class) and a warning message. Also a small usage in the description would be great.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good idea, added usage and more detailed javadoc.

@pgomulka pgomulka merged commit 4d6dc51 into elastic:master Jun 1, 2020
pgomulka added a commit to pgomulka/elasticsearch that referenced this pull request Aug 25, 2020
Splitting DeprecationLogger into two. HeaderWarningLogger - responsible for adding a response warning headers and ThrottlingLogger - responsible for limiting the duplicated log entries for the same key (previously deprecateAndMaybeLog).
Introducing A ThrottlingAndHeaderWarningLogger which is a base for other common logging usages where both response warning header and logging throttling was needed.

relates elastic#55699
relates elastic#52369
pgomulka added a commit that referenced this pull request Aug 25, 2020
Splitting DeprecationLogger into two. HeaderWarningLogger - responsible for adding a response warning headers and ThrottlingLogger - responsible for limiting the duplicated log entries for the same key (previously deprecateAndMaybeLog).
Introducing A ThrottlingAndHeaderWarningLogger which is a base for other common logging usages where both response warning header and logging throttling was needed.

relates #55699
relates #52369
backports #55941
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Logging Log management and logging utilities >enhancement Team:Core/Infra Meta label for core/infra team v7.10.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants