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

Java pipeline part of PR #11155 #11288

Closed

Conversation

andsel
Copy link
Contributor

@andsel andsel commented Oct 31, 2019

Abstract
This PR contains the implementation to expose through HTTP API the triple (file, line, column) source's config of every plugin. It contains also shared part with Ruby's one.

Description
This PR introduce the ground part to carry out some metadata from the configuration scripts, these metadata regards source file, line and column in which a specific plugin is defined inside the pipeline and associate it with its runtime generated uuid. These data is exposed inside the metrics of each plugin so that the connection between plugin UUID -> config file reference should be more walkable.

This PR is for java execution pipeline, so interest Java and Ruby plugins executed by the Java pipeline.

Changed PipelineCompiler to accept PipelineConfig instead of SourceWithMetadata array because in PipelineConfig has been introduced a remapping method from global line number (because SourceWithMeta comes with a string that's the join of all pipiline's config files, e.g. inputs in one file, filter in another etc, then before compile that files are merge din one big string) while a single SourceWithMetadata doesn't have visibility on all segments. This happen with help of ConfigSourceSegment.

After this remapping phase, done before the pipeline creation, we have to store the information related to the triple (source, line, column) into the AST Nod so that can be used during the instantiation of plugins, because every instance of a plugin has to carry this information because has to be exposed in the metrics.

Rest of the PR is to propagate and expose this information in the 4 kind of plugins we have, plus the fixing of tests.

@andsel andsel force-pushed the feature/exposing_config_ref_java_part branch from 9b15258 to 71728c9 Compare October 31, 2019 15:42
@andsel
Copy link
Contributor Author

andsel commented Nov 15, 2019

Jenkins test this please

@andsel andsel force-pushed the feature/exposing_config_ref_java_part branch from 71728c9 to 818eab4 Compare November 21, 2019 16:13
@andsel
Copy link
Contributor Author

andsel commented Nov 22, 2019

Jenkins test this please

@andsel andsel force-pushed the feature/exposing_config_ref_java_part branch from 818eab4 to 7d5b0c5 Compare November 27, 2019 12:46
@andsel
Copy link
Contributor Author

andsel commented Nov 28, 2019

Jenkins test this please

@elasticsearch-bot elasticsearch-bot self-assigned this Nov 28, 2019
end
end
end
# describe "applying protocol and id metadata" do
Copy link
Contributor

Choose a reason for hiding this comment

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

what's going on 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.

The motivation is that the method LogStash::Compiler::compile_sources before accepted an array sources_with_metadata and now accept a PipelineConfig object that contains the array.
The test before verified that the compile generated a list of tree respecting the order of pipelines string provided in input, but the compile method before was called in production code only with an Array of a single SourceWithMetadata. So test verified a thing that could never happen in production code, and now using a single SourceWithMetadata and not a list the test has no meaning.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you agree with the unusefulness of this code I remove it

Copy link
Contributor

Choose a reason for hiding this comment

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

okay I see ... if its not used I vote for removal.

if you really want to keep it (as its potentially to be resurrected later - which I really can not tell) than I would consider adding a comment (like you explained above) with a TODO/NOTE tag on why its commented out.

@andsel
Copy link
Contributor Author

andsel commented Nov 28, 2019

Jenkins test this please

@andsel andsel requested a review from kares December 3, 2019 13:28
qa/integration/specs/monitoring_api_spec.rb Outdated Show resolved Hide resolved
qa/integration/specs/monitoring_api_spec.rb Outdated Show resolved Hide resolved
String configRef = args.op_aref(context, configRefKey).asJavaString();
initMetrics(id, metric, configRef);

args.remove(configRefKey);
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe instead of args.op_aref() and than remove do a:
IRubyObject configRef = args.delete(context, configRefKey)
nitMetrics(id, metric, configRef.asJavaString());

NOTE: I am assuming the "config-ref" key is allways to be found in the map ...

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 don't know, it could be that value is null, in that case if I'm not wrong it compared as "null" string

Copy link
Contributor

Choose a reason for hiding this comment

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

okay, let's not worry about that - we could still avoid doing a hash lookup twice
for these 3 lines, doing something like:

IRubyObject configRef = args.delete(context, configRefKey)
nitMetrics(id, metric, configRef.asJavaString());

... do you feel its more confusing? (fine leaving it as is if you prefer)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sounds good

@@ -39,7 +39,7 @@ public AbstractFilterDelegatorExt(final Ruby runtime, final RubyClass metaClass)
super(runtime, metaClass);
}

protected void initMetrics(final String id, final AbstractNamespacedMetricExt namespacedMetric) {
protected void initMetrics(final String id, final AbstractNamespacedMetricExt namespacedMetric, String codeRef) {
Copy link
Contributor

Choose a reason for hiding this comment

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

hmm, seems like you will always convert this arg to a RubyString why not pass down a RubyString ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@kares kares Dec 9, 2019

Choose a reason for hiding this comment

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

yes but this PR is in charge of that change, I meant:
why not change String configRef -> RubyString configRef ?
and than initMetrics could also receive a RubyString what we're doing here on a few places is :
get a RubyString convert to a String (using asJavaString()) and than back RubyString.newString(...)

Copy link
Contributor

Choose a reason for hiding this comment

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

(might be missing some parts here - please let me know if its not feasible to do so)

res.put(v.getId(), pluginFactory.buildOutput(
RubyUtil.RUBY.newString(def.getName()), RubyUtil.RUBY.newFixnum(source.getLine()),
RubyUtil.RUBY.newFixnum(source.getColumn()), convertArgs(def), convertJavaArgs(def, cve)
RubyUtil.RUBY.newFixnum(source.getColumn()), sourceFile, sourceLine, convertArgs(def), convertJavaArgs(def, cve)
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't source.getLine() == sourceLine in which case we could be passing down less args?
maybe just Java args (we're changing the signature anyways) and do the Ruby wrapping in buildOutput
what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea to move string with the source, line and column already formatted into a more meaningful object was an improvement to propose later, maybe after the move of some code from Ruby to Java part (regarding the compilation of pipeline)

logstash-core/lib/logstash/compiler/lscl.rb Show resolved Hide resolved
@andsel andsel force-pushed the feature/exposing_config_ref_java_part branch from c347a1d to dca60d5 Compare December 6, 2019 15:00
initOutputCallsite(outputClass);

final RubyClass codecDelegatorClass = (RubyClass) RubyUtil.RUBY.executeScript(
"require 'logstash/codecs/delegator'\nLogStash::Codecs::Delegator",
Copy link
Contributor

Choose a reason for hiding this comment

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

regarding this pattern - its fine in tests but ideally should not be used in production code.
... there's seems to be a pattern of keeping RubyClass instances under RubyUtil // this is preferred, right?
2nd option would be to have the require happen once (elsewhere) and than just retrieve the constant
e.g. RUBY.getClassFromPath("LogStash::Codecs::Delegator")

@@ -1,7 +1,9 @@
module LogStash::Codecs
class Delegator < SimpleDelegator
def initialize(obj)
def initialize(obj, parent_plugin_name)
Copy link
Contributor

Choose a reason for hiding this comment

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

LS' Delegator seems to be gaining some more responsibilities ...
personally do not like it but do not want to block the PR due my preference
// someone please chime in e.g. @colinsurprenant was looking at this recently

@@ -70,7 +70,7 @@ def non_reloadable_plugins


def plugin(plugin_type, name, line, column, *args)
@plugin_factory.plugin(plugin_type, name, line, column, *args)
@plugin_factory.plugin(plugin_type, name, line, column, "", -1, *args)
Copy link
Contributor

Choose a reason for hiding this comment

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

looks really ugly and it feels like these should be optional params e.g. PluginFactory signature would look like:
plugin(plugin_type, name, line, column, *args, **opts) (will still get a bit ugly at the Java ext end)

but than from the def plugin signature this method was meant to be simply delegating down the line ...

what I am not sure about, can we really change the underlying signature non backwards-compatibly?

@jsvd
Copy link
Member

jsvd commented Dec 10, 2019

Hi @andsel, I haven't gone deeply into the code, but here are few remarks/questions:

  1. the PR description should have more context about the change, to help the reviewer. maybe some summary of what changed in what areas, and major reasons for it. I know this is a spin off PR, but if someone is coming into it fresh they’ll get discouraged at seeing 40 ish files changed and no explanations.
  2. the PR mentions java part and some ruby part too, could we narrow this down to just the minimum change to support this metadata for the java execution? Maybe a bit more explanation on what the “part” here means (i.e. “ruby part” means file/line support in ruby execution? or for ruby plugins?)
  3. the plugin adds two new properties to the Plugin < Node class for the line and file, was there no way to leverage the existing SourceWithMetadata class for this? or was this change because of the ruby part?

@robbavey robbavey self-assigned this Dec 10, 2019
@andsel
Copy link
Contributor Author

andsel commented Dec 11, 2019

@jsvd I've tried to describe better the PR, let me know if it's more meaningful and can help the PR reviwers

@robbavey
Copy link
Member

@andsel Before I dive too deeply into this, I have a couple of questions, what is the current state of #11155? There is a lot of code shared between this PR and that one. I see this comment from @yaauie - did anything come out of that?

@andsel
Copy link
Contributor Author

andsel commented Dec 11, 2019

@robbavey this PR is composed of the code from last snapshot of #11155 where tried to organize the commits in a more understandable way (I hope) regarding only the common parts for Ruby and Java pipeline and the Java pipeline and changes that made the things tick for the Java pipeline itself.
Regarding the comment from @yaauie no actions was taken

@andsel
Copy link
Contributor Author

andsel commented Jan 15, 2020

Close for same reason of #11497 (comment)

@andsel andsel closed this Jan 15, 2020
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