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

Feature/add pipeline id and plugin name to logs #11052

Closed
wants to merge 12 commits into from

Conversation

andsel
Copy link
Contributor

@andsel andsel commented Aug 16, 2019

No description provided.

@jsvd
Copy link
Member

jsvd commented Aug 16, 2019

@andsel can you rebase against master?

@andsel andsel force-pushed the feature/add_pipeline_id_to_logs branch from 6735ddc to b8a5fee Compare August 16, 2019 10:12
@jsvd
Copy link
Member

jsvd commented Aug 16, 2019

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?

@andsel
Copy link
Contributor Author

andsel commented Aug 16, 2019

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.

[2019-08-16T09:35:44,188][INFO ][logstash.javapipeline    ][another_test] Starting worker loop TODELETE
[2019-08-16T09:35:44,190][INFO ][logstash.javapipeline    ][another_test] Starting worker loop TODELETE
[2019-08-16T09:35:44,194][INFO ][logstash.javapipeline    ][another_test] Starting worker loop TODELETE
[2019-08-16T09:35:44,212][INFO ][logstash.javapipeline    ][another_test] Starting worker loop TODELETE
[2019-08-16T09:35:44,213][INFO ][logstash.javapipeline    ][test] Starting worker loop TODELETE
[2019-08-16T09:35:44,215][INFO ][logstash.javapipeline    ][test] Starting worker loop TODELETE

Copy link
Member

@robbavey robbavey left a 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)

@@ -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
Copy link
Member

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?

@andsel
Copy link
Contributor Author

andsel commented Aug 16, 2019

Fixes must be done also to another thread:

@thread = Thread.new do
begin
LogStash::Util.set_thread_name("pipeline.#{pipeline_id}")
run
@finished_run.make_true
rescue => e
close
logger.error("Pipeline aborted due to error", default_logging_keys(:exception => e, :backtrace => e.backtrace))
ensure
@finished_execution.make_true
end
end

@andsel andsel force-pushed the feature/add_pipeline_id_to_logs branch 2 times, most recently from 4b755c1 to 1edd49a Compare August 22, 2019 08:31
@andsel
Copy link
Contributor Author

andsel commented Aug 22, 2019

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
Copy link
Contributor

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?

Copy link
Contributor Author

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") + "]")
Copy link
Contributor

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?

Copy link
Contributor Author

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.

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 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) {
Copy link
Contributor

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?

Copy link
Contributor Author

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

@colinsurprenant
Copy link
Contributor

Great work @andsel 👏 - left a few inline minor comments.

Copy link
Member

@robbavey robbavey left a 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.

@@ -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
Copy link
Member

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

Copy link
Contributor Author

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

@@ -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
Copy link
Member

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

Copy link
Contributor Author

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),
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 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!)

Copy link
Contributor Author

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)
Copy link
Member

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?

@andsel andsel force-pushed the feature/add_pipeline_id_to_logs branch from d94463d to 8994e1e Compare August 23, 2019 06:59
@andsel andsel changed the title Feature/add pipeline id to logs Feature/add pipeline id and plugin name to logs Aug 23, 2019
@andsel
Copy link
Contributor Author

andsel commented Aug 23, 2019

@colinsurprenant @robbavey this PR going to split in 2, one for the pipeline.id and one for the plugin.id

pipeline.id PR: #11075
plugin.id (renamed to plugin.name) PR: #11078

@andsel
Copy link
Contributor Author

andsel commented Aug 23, 2019

I close this because it has been splitted in PR #11075 and PR #11078

@andsel andsel closed this Aug 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants