-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Feature/add pipeline id and plugin name to logs #11052
Conversation
@andsel can you rebase against master? |
6735ddc
to
b8a5fee
Compare
I've tested this locally, and I can only see the pipeline id when running the ruby execution and not the default java execution, can you confirm that? |
I've tested locally with java execution engine and I've seen the log line with the id. I've added some test log lines (then not committed) into the java_pipeline.rb when the workers are fired up.
|
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.
Tested locally, this works as advertised, but as it stands will not set pipeline.id
for log entries produced in threads created by a plugin - eg the beats plugin has entries like:
[2019-08-16T11:51:12,811][DEBUG][org.logstash.beats.BeatsHandler] [local: 0:0:0:0:0:0:0:1:5044, remote: 0:0:0:0:0:0:0:1:57963] Received a new payload
This can be remedied by setting the system property -Dlog4j2.isThreadContextMapInheritable
to TRUE
which uses InheritableThreadLocal
for the ThreadContext
Thoughts? (cc @jsvd)
config/log4j2.properties
Outdated
@@ -4,7 +4,7 @@ name = LogstashPropertiesConfig | |||
appender.console.type = Console | |||
appender.console.name = plain_console | |||
appender.console.layout.type = PatternLayout | |||
appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %m%n | |||
appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-15c{1.}]%notEmpty{[%X{pipeline.id}]} %m%n |
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.
Is the change to the logging category from -25c
to -15c{1.}
something we want to add, add just to console, or leave to another PR?
Fixes must be done also to another thread: logstash/logstash-core/lib/logstash/java_pipeline.rb Lines 104 to 115 in b8a5fee
|
4b755c1
to
1edd49a
Compare
jenkins test this please |
@@ -338,6 +341,8 @@ def worker_loop(batch_size, batch_delay) | |||
end | |||
flush_filters_to_batch(batch, :final => false) if signal.flush? | |||
if batch.filteredSize > 0 | |||
|
|||
java_import org.apache.logging.log4j.ThreadContext |
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.
any reason to have this java_import
here?
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.
no, was my typo, the import is already on top of the file
@@ -15,6 +15,7 @@ def register | |||
end | |||
|
|||
def run(queue) | |||
@logger.debug("check log4j fish tagging: [" + ThreadContext.get("plugin.id") + "]") |
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.
are these debug lines in the spec still necessary or useful?
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.
yes it is need to prove that the ThreadContext contains the fish tag for the plugin, so inside the plugin I log the tag and then in the expect
verify that the log contains the tag.
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.
Probably you are right, I can remove the "compiler way" that insert java code so set/unset the value in the ThreadContext, and move into the doOutput
of AbstractOutputDelegatorExt
(from OutputDelegatorExt
), having a uniform way to set the plugin name for Ruby and Java plugins. What do you think?
return () -> "org.apache.logging.log4j.ThreadContext.put(\"plugin.id\", \"" + configName + "\")"; | ||
} | ||
|
||
private static MethodLevelSyntaxElement setPluginIdForLog4j(final AbstractOutputDelegatorExt plugin) { |
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 code can probably be DRY'ed up for both method signatures?
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.
You are right, I try lower the repetition, the two methods are identical but one work on AbstractFilterDelegatorExt
and the other on AbstractOutputDelegatorExt
and the two classes hasn't got any common ancestor
Great work @andsel 👏 - left a few inline minor comments. |
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 is awesome @andsel, some really cool stuff in here. I've left a few comments in the code, and also, before committing, can you please update the commit header stating that the plugin is also going to be added, and a commit message giving a little more detail on the changes?
Also, I notice that the plugin.id
is only enabled for the Java execution - is this intentional? If so, please add a comment stating that in the commit message.
config/log4j2.properties
Outdated
@@ -21,7 +21,7 @@ appender.rolling.policies.time.type = TimeBasedTriggeringPolicy | |||
appender.rolling.policies.time.interval = 1 | |||
appender.rolling.policies.time.modulate = true | |||
appender.rolling.layout.type = PatternLayout | |||
appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %-.10000m%n | |||
appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c]%notEmpty{[%X{pipeline.id}]} %-.10000m%n |
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.
plugin.id
missing from the file appender
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.
Added, thanks I missed to add to ConsoleAppender
config/jvm.options
Outdated
@@ -76,3 +76,6 @@ | |||
|
|||
# Entropy source for randomness | |||
-Djava.security.egd=file:/dev/urandom | |||
|
|||
# Copy the logging context from parent threads to children | |||
-Dlog4j2.isThreadContextMapInheritable |
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 this needs to be set to =true
to apply - I ran locally and the thread context wasn't inherited unless =true
was 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.
You are right, fixed
@@ -196,12 +200,13 @@ private static Closure filterBody(final ValueSyntaxElement outputBuffer, | |||
final ValueSyntaxElement inputBuffer, final ClassFields fields, | |||
final AbstractFilterDelegatorExt plugin) { | |||
final ValueSyntaxElement filterField = fields.add(plugin); | |||
final Closure body = Closure.wrap( | |||
final Closure body = Closure.wrap(setPluginIdForLog4j(plugin), |
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.
What is the use case for settingplugin.Id
here as well as in the filter and output delegators?
(Genuine question! I played around with the code a little, and changing values here didn't seem to affect the log entries, but I wasn't exhaustive, so I probably missed something!)
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.
Because method filterDataset
invokes filterBody
and filterBody sets and unsets the plugin.id in the context, while outputDataset
create directly the statements creators, without invoking the filterBody.
So in filterBody, I need to set to make working in filters while in outputDataset for output.
@@ -305,6 +309,8 @@ def start_input(plugin) | |||
|
|||
def inputworker(plugin) | |||
Util::set_thread_name("[#{pipeline_id}]<#{plugin.class.config_name}") | |||
ThreadContext.put("pipeline.id", pipeline_id) | |||
ThreadContext.put("plugin.id", plugin.config_name) |
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 here in terms of that we want to populate the plugin.id
variable with, I think we might want to have the actual id either instead of, or as well as config_name
. Only putting the configName here means that we cannot disambiguate between plugins of the same type in the same pipeline configuration. It be worth including the config name and the plugin.id in the logs - the plugin.id
is often not set and may not be particularly illuminating. Thoughts @jsvd?
d94463d
to
8994e1e
Compare
@colinsurprenant @robbavey this PR going to split in 2, one for the pipeline.id PR: #11075 |
No description provided.