-
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
Add sub command to generate sample configuration for the collector #5943
Conversation
Codecov ReportBase: 91.76% // Head: 91.93% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #5943 +/- ##
==========================================
+ Coverage 91.76% 91.93% +0.16%
==========================================
Files 217 218 +1
Lines 13350 13770 +420
==========================================
+ Hits 12251 12659 +408
- Misses 870 875 +5
- Partials 229 236 +7
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
Hey @neelayu, thanks for creating this. That's much more than I expected when I raised #5654! I did not review the code, leaving that to the @open-telemetry/collector-approvers, but I tried out the functionality: I like the prompts! Two issues: If I skip all prompts I get the following YAML: exporters: {}
processors: {}
receivers: {}
extensions: {}
service:
# Specify extensions for the collector
extensions: []
pipelines: {} Is it possible to not have If I select all/some attributes it fails with
This seems to be a hard-coded file path, when I copy my compiled collector binary into a folder like "./bin/bin" within the forked repository things work. You may need to verify that the final collector works independent of the existence of these files. To mention that: I like that if I only provide the Regarding the copied comments: On the one hand I like them, on the other hand they can make a config extremely hard to read for a new-comer, e.g. |
@svrnm Thanks for going through this PR and giving it a try.
Yes. This is something which I want an opinion on. I'd like to add validations to check if the inputs were provided or not.
Will produce all fields with no comments.
Will produce only the configuration file with key headers? exporters:
otlp:
# For configuration params, refer https://pkg.go.dev/go.opentelemetry.io/collector/exporter/otlpexporter
As you can see, there are no attributes, but a single line comment indicating where the info on the configuration can be found. I believe pkg.go.dev will do the job. I think its difficult to get only "mandatory" or "minimal" configuration fields from the struct. So its either all or none. |
I personally think it's ok to leave them empty.
I like that, teaches people also where they can look for details! I am only wondering what should be the default (full details, only attributes, no comments&no attributes)?
That's an interesting one! What about something like:
gives you some of those attributes set (and skips the rest)? |
Hey @svrnm I have made a few changes. I didnt really get time this week to work on it.
otelcol config -p batch -e otlp,endpoint=https://mybackend/,entpoint.headers.apiKey=asdf,tls.insecure=true --no-attrs
I believe this is as good as knowing what params are present. So the user might as well use that and create a config file. |
@neelayu thank you, I am looking forward to have this feature. I am eventually just a consumer of that, as an end-user but also to simplify the Getting Started docs for the collector over at opentelemetry.io :) |
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 left a few comments, and while I think this feature would be useful, I think the current implementation might need some more attention. I ran the simplest command possible, $ go run ./ config -e otlp
, and I got a file that is full of options that are not needed while still not being very functional, given that the collector won't start due to missing values for required properties (endpoint, for instance).
Instead of having one command for all possible components, how about having an interface for components to implement? This way, component developers can decide what and how to ask users, potentially even running the validation in the process.
Concretely, OTLP Exporter would only ask for the "endpoint" property and ask users if they want to specify values for optional properties.
I have refactored the code. The basefactory essentially adds a SampleConfig() method. The authors are expected to return a configuration for the component. This is more or less what Telegraf agent does in its approach. Since I didnt want to introduce breaking changes across the contrib repo as well, I have added it as an option. Let me know if this approach works. @jpkrohling |
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
I am still a big fan of this and keen to see this happening, is there anything I can do to help this progressing? ty |
@jpkrohling is there anything needed 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.
Something about having all of the *.sample.yaml
files added here doesn't feel right to me. It seems like the structure of these files is dictated by the structure of the types they represent. The addition here is documentary comments and sample values. I wonder whether this could be accomplished with well-structured godoc comments that can be accessed with the reflection API. Doing so would avoid repeating information for types that are commonly embedded in other types and also minimize the risk of changes to the meaning, interpretation, or documentation of a field not being correctly propagated to all sample configurations where it appears.
@Aneurysm9 I did not add In that I used the configschema API from contrib repo to fetch the fields and doc info. The limitation of that approach is that we can't obtain sensible defaults for fields which are mandatory.(Eg endpoint) |
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 like where this is going, but I believe that:
- this needs a bit better code organization, as there's just too much happening on the configinit.go file
- if the sample YAML files are auto-generated, there should be a couple of make targets to generate the files on demand and CI checks to ensure that those files are not changed (or are changed when the base type changes). I believe a header stating that those files are auto-generated would also be warranted
unexportedFactoryFunc() | ||
} | ||
|
||
type baseFactory struct { | ||
cfgType config.Type | ||
cfgType config.Type | ||
sampleConfig string | ||
} | ||
|
||
func (baseFactory) unexportedFactoryFunc() {} |
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 believe this won't cause backward compatibility issues because we are forcing implementations to embed the base factory, right?
) | ||
|
||
const ( | ||
sampleConfigHeader = `Opentelemetry Collector sample configuration. Double check the pipeline configuration |
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.
sampleConfigHeader = `Opentelemetry Collector sample configuration. Double check the pipeline configuration | |
sampleConfigHeader = `OpenTelemetry Collector sample configuration. Double-check the pipeline configuration |
@@ -0,0 +1,546 @@ | |||
// Copyright The OpenTelemetry Authors |
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.
Not quite sure I agree this is the best package for this code.
var log *zap.Logger | ||
var opts = new(optionsSelected) | ||
|
||
func init() { |
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 don't see a strong reason to use an init function here. Perhaps name it differently and invoke it where the logger needs to be set?
} | ||
} | ||
|
||
exportersNode, err := getExportersNode(set.Factories, opts.Exporters) |
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.
Could you split the business from the plumbing? Plumbing would be setting up the logger, validating the user input, returning errors, printing the outcome, and so on. Assembling the list of components and their sample config would be the business.
Thanks @jpkrohling for the comments. I just want to ensure that this approach of sample config yaml makes sense. One other approach I can think of creating a web equivalent config creation which was discussed in SIG meeting in CLI. That is for every field we ask the user to input the value, the docstring will act as help text. If we stick to sample yaml approach, I am aware that the yaml files will have to be created via make targets. However, that would add too much code to review in this PR. So I can take it up in a separate task. Although there is one caveat here, the files will be auto-generated, but they would be bulky with many fields and large comment sections. So the onus lies on the developer(author of the component) to select(or not) which ones are relevant for a sample config. |
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
Sorry, I need to catch-up with the collector's current state before giving any meaningful input here. Perhaps @codeboten knows what's the state around this part, especially regarding the UI that was shown some weeks ago to help with the collector's config? |
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
Closed as inactive. Feel free to reopen if this PR is still being worked on. |
Description:
Adding a feature - Create a subcommand that generates a sample configuration for the collector. It has support for UI based options(like
npm init
), or via flags.Link to tracking Issue: #5654
Testing: Unit Tests
Documentation: Need suggestions
Waiting for suggestions to improve the code more and opinions on how we can improve the documentation.
Sample workflow:
If no flags are provided, use prompts
It uses
github.com/AlecAivazis/survey
go library.With flags
Output(only some parts for relevance)
As you can see, comments are also added for better understanding. This is achieved by
github.com/open-telemetry/opentelemetry-collector-contrib/cmd/configschema
Suggestions are welcome to improve this PR.
Thanks!