-
Notifications
You must be signed in to change notification settings - Fork 1.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
Support set flag for component configs #1640
Conversation
@tigrannajaryan @jrcamp could you please review and comment whether you agree with this approach? |
In |
The
|
Changing this to ready for review. |
Codecov Report
@@ Coverage Diff @@
## master #1640 +/- ##
==========================================
- Coverage 91.66% 90.75% -0.91%
==========================================
Files 261 262 +1
Lines 18532 15864 -2668
==========================================
- Hits 16987 14398 -2589
+ Misses 1114 1037 -77
+ Partials 431 429 -2
Continue to review full report at Codecov.
|
The test coverage is below, there are some parts of this PR that I am not sure how to cover (error of creating temp file, err for writing to a temp file, getting an error from ViperSubExtract) |
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 feel like this can be substantially simplified. See code here based on some of your changes:
config/config.go
Outdated
@@ -319,23 +310,6 @@ func loadService(v *viper.Viper) (configmodels.Service, error) { | |||
return service, nil | |||
} | |||
|
|||
// LoadReceiver loads a receiver config from componentConfig using the provided factories. | |||
func LoadReceiver(componentConfig *viper.Viper, typeStr configmodels.Type, fullName string, factory component.ReceiverFactory) (configmodels.Receiver, error) { |
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 used in receivercreator in contrib to create receivers at runtime. Does it need to be changed to support this feature?
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 wasn't sure why it is public since it is the only public load func for a component.
Maybe I am doing something wrong but it does not work as expected, the set flags are not being enforced. There are also error messages in the log
|
@jrcamp I made the suggested changes and also the simplification to remove the temp file (great catch!). Your impl does not seem to work properly, the merge config in viper is not working as we want (see my previous comment). |
I only did a quick test so there could be a bug. Can you share the config and command line params you used? |
The config is in the first comment. Then you can use |
@pavolloffay looks like viper |
@jrcamp does not seem to work either try the config from the first comment with
|
@pavolloffay I get the same startup error by adding the equivalent set command to the config file. Maybe you meant But there are still more issues even after changing that. See my latest changes (viper isn't very good at merging) https://github.com/jrcamp/opentelemetry-collector/tree/flags-review I didn't fix the tests for the stuff I refactored, just trying to find an approach that works. |
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
@jrcamp I have updated the PR with the workaround from your branch and added tests. Now it looks good to me. for _, k := range v.AllKeys() {
v.Set(k, v.Get(k))
} |
As part of my proposed implementation I also did some minor refactoring so that this isn't tied to |
I saw that the problem is that the factory should return the final config object. We use it to construct the default/hardcoded configuration in Jaeger (agent, collector...). This remains me that we should make the set flag public. EDIT: actually it's fine we can just use |
@jrcamp as I mentioned before the factory has to return the config object. I will document your concerns and make the |
Sounds good. Overall lgtm, can you just note (in the PR here) the reason patch is under target (95%). Looks like it's mostly error cases that would be hard to reach but they may ask before merging. |
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
Yes, the coverage dropped below the limit. I don't know how to cover error cases e.g. // b is &bytes.Buffer{}
if _, err := fmt.Fprintf(b, "%s\n", property); err != nil {
return err
} and if err := viperFlags.ReadConfig(b); err != nil {
return fmt.Errorf("failed to read set flag config: %v", err)
} |
@tigrannajaryan @bogdandrutu could you please have review/merge? |
Is this a silent noop? Can we make this an error instead of noop? Otherwise it will be difficult to understand why things don't work if you make a typo in the command line option. |
Can you add this description to some relevant place in the source code? We will also need it in the README, but it seems like we lost the basic running instructions after refactoring, so this can wait for now. I just want to make sure the usage instructions are captured at least somewhere. Perhaps we can print them when |
params := Parameters{ | ||
Factories: factories, | ||
} | ||
t.Run("unknown_component", func(t *testing.T) { |
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.
@tigrannajaryan have a look at this test.
If the flag references an unknown property the factory returns an error. However, if the flag references a valid component that is not in the config file e.g. batch/foo
then an error is not returned (see the next test) and a new component instance is created that is not enabled in the pipeline. I think that this behaviour is fine.
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.
However, if the flag references a valid component that is not in the config file e.g. batch/foo then an error is not returned (see the next test) and a new component instance is created that is not enabled in the pipeline. I
This is the part that I don't like. If I have a typo in my --set
flag and the name of the component is incorrect then it will have no effect and there will be no indication to the user that something went wrong.
Preferably in this case the startup should fail and tell that the component is not found. Is it possible to do?
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 cannot think of a simple solution. The same can happen with the config file a user can forget to add a component to a pipeline.
The ugly solution might be to parse the config in FileLoaderConfigFactory
then pass it into AddSetFlagProperties
which would parse it's own config and compare which components are not in the pipeline. Then parse the final config at the end of FileLoaderConfigFactory
with the final viper. This is a rather horrible solution :).
Maybe we could print a warning for not assigned components during the config validation?
for _, k := range v.AllKeys() { | ||
v.Set(k, v.Get(k)) | ||
} |
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.
Why do we do this? Code is not clear and looks suspect (we get and set all keys?). Add comment.
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 have added a comment
"go.opentelemetry.io/collector/processor/attributesprocessor" | ||
"go.opentelemetry.io/collector/processor/batchprocessor" | ||
"go.opentelemetry.io/collector/receiver/jaegerreceiver" | ||
"go.opentelemetry.io/collector/service/builder" |
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 am not sure I like how we depend on specific components from here. Can we use componenttest
and example components for testing instead?
I would prefer to minimize the coupling between this package and actual component packages.
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.
The test was already using "go.opentelemetry.io/collector/service/defaultcomponents"
. The components were parsed but not accessed directly. For instance this config was used by this test
receivers: |
for _, k := range viperFlags.AllKeys() { | ||
v.Set(k, viperFlags.Get(k)) | ||
} |
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.
Why do we build a properties file first? Can't we apply the flagProperties
directly to v
here? If there is a reason please add comments to explain.
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 have added a comment to the source file.
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
This is what the help command prints:
See the help command it says that the component has to be defined in the config file. I am not sure how to do this, nicely. We could iterate over components and see whether they are defined in a pipeline. The same issue is with a config file a user can forget to add a component to the pipeline. |
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
@tigrannajaryan could you please have another look? |
@tigrannajaryan any update on this one? |
This reverts commit 450fd93 to ensure empty objects as component config work. Temporarily fixes open-telemetry#1897
…y#1640)" (open-telemetry#1905)" This reverts commit 2efdb28.
…y#1640)" (open-telemetry#1905)" This reverts commit 2efdb28.
…y#1640) Bumps [boto3](https://github.com/boto/boto3) from 1.24.2 to 1.24.3. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](boto/boto3@1.24.2...1.24.3) --- updated-dependencies: - dependency-name: boto3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: Pavol Loffay ploffay@redhat.com
Creating as a draft to collect feedback. Once we agree I will clean it and add tests.
Description:
This patch adds support for configuring components (receivers, processors, exporters...) via
--set
flag. For example--set=processors.batch.timeout=12s
or--receivers.otlp.protocols.grpc.endpoint=123456
.--set=processor.queued_retry.queue_size=15
is noop if thequeued_retry
is not defined.--set=processors.batch/bar.timeout=3s
--set=processors.resource.attributes.key=key2
The implementation creates a new viper instance that is initialized with a temporary properties file that contains values passed via set flag. Then the new viper is used to apply changes to an existing configuration (loaded via the main config file).
Link to tracking Issue:
Resolves #873
Testing: < Describe what testing was performed and which tests were added.>
Tested locally
RUN_CONFIG=config.yaml make run
Documentation: < Describe the documentation added.>
None