Skip to content

Commit

Permalink
Enable feature-gates for otel subcommands (#4198)
Browse files Browse the repository at this point in the history
Added support for feature gates for otel and validate commands
How to test

- Build/Package agent
- run ./elastic-agent otel --feature-gates "-telemetry.useOtelForInternalMetrics" as this is stable feature gate, you should see error returned saying useOtelForInternalMetrics is stable and cannot be disabled
- running ./elastic-agent otel --feature-gates telemetry.useOtelForInternalMetrics (difference is - in front of a gate name) should result in a warning message in output saying it's stable and collector running normally
- running ./elastic-agent otel -h needs to include flag in help message
  • Loading branch information
michalpristas authored Feb 7, 2024
1 parent 4fa6bb6 commit e66ff9c
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 228 deletions.
424 changes: 212 additions & 212 deletions NOTICE.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ require (
go.opentelemetry.io/collector/exporter v0.93.0
go.opentelemetry.io/collector/exporter/debugexporter v0.93.0
go.opentelemetry.io/collector/exporter/otlpexporter v0.93.0
go.opentelemetry.io/collector/featuregate v1.0.1
go.opentelemetry.io/collector/otelcol v0.93.0
go.opentelemetry.io/collector/processor v0.93.0
go.opentelemetry.io/collector/processor/batchprocessor v0.93.0
Expand Down Expand Up @@ -214,7 +215,6 @@ require (
go.opentelemetry.io/collector/consumer v0.93.0 // indirect
go.opentelemetry.io/collector/extension v0.93.0 // indirect
go.opentelemetry.io/collector/extension/auth v0.93.0 // indirect
go.opentelemetry.io/collector/featuregate v1.0.1 // indirect
go.opentelemetry.io/collector/pdata v1.0.1 // indirect
go.opentelemetry.io/collector/semconv v0.93.0 // indirect
go.opentelemetry.io/collector/service v0.93.0 // indirect
Expand Down
8 changes: 5 additions & 3 deletions internal/pkg/agent/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ func NewCommandWithArgs(args []string, streams *cli.IOStreams) *cobra.Command {
}

// Init version information contained in package version file
err := version.InitVersionError()
if err != nil {
cmd.PrintErrf("Error initializing version information: %v\n", err)
if isOtel := len(args) > 1 && args[1] == "otel"; !isOtel {
err := version.InitVersionError()
if err != nil {
cmd.PrintErrf("Error initializing version information: %v\n", err)
}
}

// path flags
Expand Down
7 changes: 1 addition & 6 deletions internal/pkg/agent/cmd/otel.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,7 @@ func newOtelCommandWithArgs(args []string, streams *cli.IOStreams) *cobra.Comman
c.Root().HelpFunc()(c, s)
})

cmd.Flags().StringArray(configFlagName, []string{}, "Locations to the config file(s), note that only a"+
" single location can be set per flag entry e.g. `--config=file:/path/to/first --config=file:path/to/second`.")

cmd.Flags().StringArray(setFlagName, []string{}, "Set arbitrary component config property. The component has to be defined in the config file and the flag"+
" has a higher precedence. Array config properties are overridden and maps are joined. Example --set=processors.batch.timeout=2s")

setupOtelFlags(cmd.Flags())
cmd.AddCommand(newValidateCommandWithArgs(args, streams))

return cmd
Expand Down
16 changes: 16 additions & 0 deletions internal/pkg/agent/cmd/otel_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,30 @@
package cmd

import (
"flag"
"fmt"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/pflag"
"go.opentelemetry.io/collector/featuregate"

"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
)

func setupOtelFlags(flags *pflag.FlagSet) {
flags.StringArray(configFlagName, []string{}, "Locations to the config file(s), note that only a"+
" single location can be set per flag entry e.g. `--config=file:/path/to/first --config=file:path/to/second`.")

flags.StringArray(setFlagName, []string{}, "Set arbitrary component config property. The component has to be defined in the config file and the flag"+
" has a higher precedence. Array config properties are overridden and maps are joined. Example --set=processors.batch.timeout=2s")

goFlags := new(flag.FlagSet)
featuregate.GlobalRegistry().RegisterFlags(goFlags)

flags.AddGoFlagSet(goFlags)
}

func getConfigFiles(cmd *cobra.Command, useDefault bool) ([]string, error) {
configFiles, err := cmd.Flags().GetStringArray(configFlagName)
if err != nil {
Expand Down
16 changes: 16 additions & 0 deletions internal/pkg/agent/cmd/otel_flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,26 @@ package cmd
import (
"testing"

"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestOtelFlagsSetup(t *testing.T) {
fs := new(pflag.FlagSet)
setupOtelFlags(fs)

expectedFlags := []string{
configFlagName,
setFlagName,
"feature-gates",
}

for _, expectedFlag := range expectedFlags {
require.NotNil(t, fs.Lookup(expectedFlag), "Flag %q is not present", expectedFlag)
}
}

func TestGetSets(t *testing.T) {
testCases := []struct {
name string
Expand Down
7 changes: 1 addition & 6 deletions internal/pkg/agent/cmd/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@ func newValidateCommandWithArgs(_ []string, _ *cli.IOStreams) *cobra.Command {
},
}

cmd.Flags().StringArray(configFlagName, []string{}, "Locations to the config file(s), note that only a"+
" single location can be set per flag entry e.g. `--config=file:/path/to/first --config=file:path/to/second`.")

cmd.Flags().StringArray(setFlagName, []string{}, "Set arbitrary component config property. The component has to be defined in the config file and the flag"+
" has a higher precedence. Array config properties are overridden and maps are joined. Example --set=processors.batch.timeout=2s")

setupOtelFlags(cmd.Flags())
cmd.SetHelpFunc(func(c *cobra.Command, s []string) {
hideInheritedFlags(c)
c.Root().HelpFunc()(c, s)
Expand Down
5 changes: 5 additions & 0 deletions testing/integration/otel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ func validateCommandIsWorking(t *testing.T, ctx context.Context, fixture *aTesti
require.NoError(t, err)
require.Equal(t, 0, len(out)) // no error printed out

// check feature gate works
out, err = fixture.Exec(ctx, []string{"otel", "validate", "--config", cfgFilePath, "--feature-gates", "foo.bar"})
require.Error(t, err)
require.Contains(t, string(out), `no such feature gate "foo.bar"`)

// check `elastic-agent otel validate` command works for invalid otel config
cfgFilePath = filepath.Join(tempDir, "otel-invalid.yml")
require.NoError(t, os.WriteFile(cfgFilePath, []byte(fileInvalidOtelConfig), 0600))
Expand Down

0 comments on commit e66ff9c

Please sign in to comment.