diff --git a/internal/commands/diagnose/otelconfigcheck.go b/internal/commands/diagnose/otelconfigcheck.go index 72a6886ce..7d5071243 100644 --- a/internal/commands/diagnose/otelconfigcheck.go +++ b/internal/commands/diagnose/otelconfigcheck.go @@ -6,6 +6,7 @@ import ( "github.com/observeinc/observe-agent/internal/commands/start" logger "github.com/observeinc/observe-agent/internal/commands/util" + "github.com/observeinc/observe-agent/observecol" "github.com/spf13/viper" "go.opentelemetry.io/collector/otelcol" ) @@ -16,13 +17,14 @@ type OtelConfigTestResult struct { } func checkOtelConfig(_ *viper.Viper) (bool, any, error) { - colSettings, cleanup, err := start.SetupAndGenerateCollectorSettings(logger.WithCtx(context.Background(), logger.GetNop())) - if err != nil { - return false, nil, err - } + configFilePaths, cleanup, err := start.SetupAndGetConfigFiles(logger.WithCtx(context.Background(), logger.GetNop())) if cleanup != nil { defer cleanup() } + if err != nil { + return false, nil, err + } + colSettings := observecol.GenerateCollectorSettingsWithConfigFiles(configFilePaths) // These are the same checks as the `otelcol validate` command: // https://github.com/open-telemetry/opentelemetry-collector/blob/main/otelcol/command_validate.go col, err := otelcol.NewCollector(*colSettings) diff --git a/internal/commands/start/start.go b/internal/commands/start/start.go index cc635dd90..75f3f3816 100644 --- a/internal/commands/start/start.go +++ b/internal/commands/start/start.go @@ -12,8 +12,6 @@ import ( "github.com/observeinc/observe-agent/internal/root" "github.com/observeinc/observe-agent/observecol" "github.com/spf13/cobra" - "github.com/spf13/viper" - collector "go.opentelemetry.io/collector/otelcol" ) func SetupAndGetConfigFiles(ctx context.Context) ([]string, func(), error) { @@ -42,46 +40,38 @@ func DefaultLoggerCtx() context.Context { return logger.WithCtx(context.Background(), logger.Get()) } -func SetupAndGenerateCollectorSettings(ctx context.Context) (*collector.CollectorSettings, func(), error) { - configFilePaths, cleanup, err := SetupAndGetConfigFiles(ctx) - if err != nil { - return nil, cleanup, err - } - // Generate collector settings with all config files - colSettings := observecol.GenerateCollectorSettings(configFilePaths) - return colSettings, cleanup, nil -} +func MakeStartCommand() *cobra.Command { + // Create the start command from the otel collector command + settings := observecol.GenerateCollectorSettings() + otleCmd := observecol.GetOtelCollectorCommand(settings) + otleCmd.Use = "start" + otleCmd.Short = "Start the Observe agent process." + otleCmd.Long = `The Observe agent is based on the OpenTelemetry Collector. +This command reads in the local config and env vars and starts the +collector on the current host.` + // Drop the sub commands + otleCmd.ResetCommands() -var startCmd = &cobra.Command{ - Use: "start", - Short: "Start the Observe agent process.", - Long: `The Observe agent is based on the OpenTelemetry Collector. -This command reads in the local config and env vars and starts the -collector on the current host.`, - RunE: func(cmd *cobra.Command, args []string) error { - colSettings, cleanup, err := SetupAndGenerateCollectorSettings(DefaultLoggerCtx()) + // Modify the run function so we can pass in our packaged config files. + originalRunE := otleCmd.RunE + otleCmd.RunE = func(cmd *cobra.Command, args []string) error { + configFilePaths, cleanup, err := SetupAndGetConfigFiles(DefaultLoggerCtx()) + if cleanup != nil { + defer cleanup() + } if err != nil { return err } - if cleanup != nil { - defer cleanup() + configFlag := otleCmd.Flags().Lookup("config") + for _, path := range configFilePaths { + configFlag.Value.Set(path) } - otelCmd := observecol.GetOtelCollectorCommand(colSettings) - return otelCmd.RunE(cmd, args) - }, + return originalRunE(cmd, args) + } + return otleCmd } func init() { - startCmd.PersistentFlags().String("otel-config", "", "Path to additional otel configuration file") - viper.BindPFlag("otelConfigFile", startCmd.PersistentFlags().Lookup("otel-config")) + startCmd := MakeStartCommand() root.RootCmd.AddCommand(startCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // startCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } diff --git a/internal/connections/confighandler.go b/internal/connections/confighandler.go index 31b775a94..4165ae763 100644 --- a/internal/connections/confighandler.go +++ b/internal/connections/confighandler.go @@ -43,10 +43,6 @@ func GetAllOtelConfigFilePaths(ctx context.Context, tmpDir string) ([]string, er configFilePaths = append(configFilePaths, connectionPaths...) } } - // Read in otel-config flag and add to paths if set - if viper.IsSet("otelConfigFile") { - configFilePaths = append(configFilePaths, viper.GetString("otelConfigFile")) - } // Generate override file and include path if overrides provided if viper.IsSet(OTEL_OVERRIDE_YAML_KEY) { // GetStringMap is more lenient with respect to conversions than Sub, which only handles maps. diff --git a/internal/root/root.go b/internal/root/root.go index 6eeb847cd..c74ab248d 100644 --- a/internal/root/root.go +++ b/internal/root/root.go @@ -34,7 +34,7 @@ func Execute() { func init() { cobra.OnInitialize(InitConfig) - RootCmd.PersistentFlags().StringVar(&CfgFile, "config", "", "config file path") + RootCmd.PersistentFlags().StringVar(&CfgFile, "observe-config", "", "observe-agent config file path") } // InitConfig reads in config file and ENV variables if set. diff --git a/main_windows.go b/main_windows.go index f0c8fb7dc..5b946f00e 100644 --- a/main_windows.go +++ b/main_windows.go @@ -10,41 +10,44 @@ import ( "github.com/observeinc/observe-agent/internal/commands/start" "github.com/observeinc/observe-agent/internal/root" + "github.com/observeinc/observe-agent/observecol" "go.opentelemetry.io/collector/otelcol" "golang.org/x/sys/windows" "golang.org/x/sys/windows/svc" ) func run() error { - inService, err := svc.IsWindowsService() - if err != nil { + // If we're not running as a service, we run normally. + if inService, err := svc.IsWindowsService(); err != nil { log.Fatalf("failed to determine if we are running in service: %v", err) + } else if !inService { + return runInteractive() } - if inService { - if len(os.Args) != 2 { - log.Fatal("Expected to run svc as: observe-agent.exe ") - } - root.CfgFile = os.Args[1] - root.InitConfig() - colSettings, cleanup, err := start.SetupAndGenerateCollectorSettings(start.DefaultLoggerCtx()) - if err != nil { - return err - } - if cleanup != nil { - defer cleanup() - } - if err := svc.Run("", otelcol.NewSvcHandler(*colSettings)); err != nil { - if errors.Is(err, windows.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { - // Per https://learn.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-startservicectrldispatchera#return-value - // this means that the process is not running as a service, so run interactively. - return runInteractive() - } - - return fmt.Errorf("failed to start collector server: %w", err) + if len(os.Args) != 2 { + log.Fatal("Expected to run svc as: observe-agent.exe ") + } + root.CfgFile = os.Args[1] + root.InitConfig() + + // Get the collector settings along with our bundled config files. + configFilePaths, cleanup, err := start.SetupAndGetConfigFiles(start.DefaultLoggerCtx()) + if cleanup != nil { + defer cleanup() + } + if err != nil { + return err + } + colSettings := observecol.GenerateCollectorSettingsWithConfigFiles(configFilePaths) + + if err := svc.Run("", otelcol.NewSvcHandler(*colSettings)); err != nil { + if errors.Is(err, windows.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { + // Per https://learn.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-startservicectrldispatchera#return-value + // this means that the process is not running as a service, so run interactively. + return runInteractive() } - } else { - return runInteractive() + + return fmt.Errorf("failed to start collector server: %w", err) } return nil diff --git a/observecol/otelcollector.go b/observecol/otelcollector.go index cf0e9da8b..4a84aea91 100644 --- a/observecol/otelcollector.go +++ b/observecol/otelcollector.go @@ -14,15 +14,7 @@ import ( "go.opentelemetry.io/collector/otelcol" ) -func makeMapProvidersMap(providers ...confmap.Provider) map[string]confmap.Provider { - ret := make(map[string]confmap.Provider, len(providers)) - for _, provider := range providers { - ret[provider.Scheme()] = provider - } - return ret -} - -func GenerateCollectorSettings(URIs []string) *otelcol.CollectorSettings { +func GenerateCollectorSettings() *otelcol.CollectorSettings { buildInfo := component.BuildInfo{ Command: "observe-agent", Description: "Observe Distribution of Opentelemetry Collector", @@ -33,7 +25,6 @@ func GenerateCollectorSettings(URIs []string) *otelcol.CollectorSettings { Factories: components, ConfigProviderSettings: otelcol.ConfigProviderSettings{ ResolverSettings: confmap.ResolverSettings{ - URIs: URIs, ProviderFactories: []confmap.ProviderFactory{ fileprovider.NewFactory(), envprovider.NewFactory(), @@ -47,6 +38,12 @@ func GenerateCollectorSettings(URIs []string) *otelcol.CollectorSettings { return set } +func GenerateCollectorSettingsWithConfigFiles(configFiles []string) *otelcol.CollectorSettings { + set := GenerateCollectorSettings() + set.ConfigProviderSettings.ResolverSettings.URIs = configFiles + return set +} + func GetOtelCollectorCommand(otelconfig *otelcol.CollectorSettings) *cobra.Command { cmd := otelcol.NewCommand(*otelconfig) return cmd diff --git a/packaging/linux/config/observe-agent.service b/packaging/linux/config/observe-agent.service index 403480c8f..a20b87a2f 100644 --- a/packaging/linux/config/observe-agent.service +++ b/packaging/linux/config/observe-agent.service @@ -3,7 +3,7 @@ Description=Observe Agent After=network.target [Service] -ExecStart=/usr/bin/observe-agent start --config /etc/observe-agent/observe-agent.yaml +ExecStart=/usr/bin/observe-agent start --observe-config /etc/observe-agent/observe-agent.yaml KillMode=mixed Restart=on-failure Type=simple