Skip to content

Commit

Permalink
Add otel components command
Browse files Browse the repository at this point in the history
Signed-off-by: ChrsMark <chrismarkou92@gmail.com>
  • Loading branch information
ChrsMark committed Jan 17, 2025
1 parent 7ee581e commit 5c51c6d
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 0 deletions.
33 changes: 33 additions & 0 deletions internal/pkg/agent/cmd/command_components.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.

package cmd

import (
"github.com/spf13/cobra"

"github.com/elastic/elastic-agent/internal/pkg/cli"
"github.com/elastic/elastic-agent/internal/pkg/otel"
)

func newComponentsCommandWithArgs(_ []string, _ *cli.IOStreams) *cobra.Command {
cmd := &cobra.Command{
Use: "components",
Short: "Outputs available components in this collector distribution",
Long: "Outputs available components in this collector distribution including their stability levels. The output format is not stable and can change between releases.",
SilenceUsage: true, // do not display usage on error
SilenceErrors: true,
RunE: func(cmd *cobra.Command, _ []string) error {
return otel.Components(cmd)
},
}

setupOtelFlags(cmd.Flags())
cmd.SetHelpFunc(func(c *cobra.Command, s []string) {
hideInheritedFlags(c)
c.Root().HelpFunc()(c, s)
})

return cmd
}
1 change: 1 addition & 0 deletions internal/pkg/agent/cmd/otel.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func newOtelCommandWithArgs(args []string, streams *cli.IOStreams) *cobra.Comman

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

return cmd
}
Expand Down
137 changes: 137 additions & 0 deletions internal/pkg/otel/command_components.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.

package otel

import (
"fmt"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"sort"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/connector"
"go.opentelemetry.io/collector/exporter"
"go.opentelemetry.io/collector/extension"
"go.opentelemetry.io/collector/processor"
"go.opentelemetry.io/collector/receiver"

"github.com/elastic/elastic-agent/internal/pkg/release"
)

type componentWithStability struct {
Name component.Type
Module string
Stability map[string]string
}

type componentsOutput struct {
BuildInfo component.BuildInfo
Receivers []componentWithStability
Processors []componentWithStability
Exporters []componentWithStability
Connectors []componentWithStability
Extensions []componentWithStability
}

func Components(cmd *cobra.Command) error {
set := NewSettings(release.Version(), []string{})

factories, err := set.Factories()
if err != nil {
return fmt.Errorf("failed to initialize factories: %w", err)
}

components := componentsOutput{}
for _, con := range sortFactoriesByType[connector.Factory](factories.Connectors) {
components.Connectors = append(components.Connectors, componentWithStability{
Name: con.Type(),
Module: factories.ConnectorModules[con.Type()],
Stability: map[string]string{
"logs-to-logs": con.LogsToLogsStability().String(),
"logs-to-metrics": con.LogsToMetricsStability().String(),
"logs-to-traces": con.LogsToTracesStability().String(),

"metrics-to-logs": con.MetricsToLogsStability().String(),
"metrics-to-metrics": con.MetricsToMetricsStability().String(),
"metrics-to-traces": con.MetricsToTracesStability().String(),

"traces-to-logs": con.TracesToLogsStability().String(),
"traces-to-metrics": con.TracesToMetricsStability().String(),
"traces-to-traces": con.TracesToTracesStability().String(),
},
})
}
for _, ext := range sortFactoriesByType[extension.Factory](factories.Extensions) {
components.Extensions = append(components.Extensions, componentWithStability{
Name: ext.Type(),
Module: factories.ExtensionModules[ext.Type()],
Stability: map[string]string{
"extension": ext.Stability().String(),
},
})
}
for _, prs := range sortFactoriesByType[processor.Factory](factories.Processors) {
components.Processors = append(components.Processors, componentWithStability{
Name: prs.Type(),
Module: factories.ProcessorModules[prs.Type()],
Stability: map[string]string{
"logs": prs.LogsStability().String(),
"metrics": prs.MetricsStability().String(),
"traces": prs.TracesStability().String(),
},
})
}
for _, rcv := range sortFactoriesByType[receiver.Factory](factories.Receivers) {
components.Receivers = append(components.Receivers, componentWithStability{
Name: rcv.Type(),
Module: factories.ReceiverModules[rcv.Type()],
Stability: map[string]string{
"logs": rcv.LogsStability().String(),
"metrics": rcv.MetricsStability().String(),
"traces": rcv.TracesStability().String(),
},
})
}
for _, exp := range sortFactoriesByType[exporter.Factory](factories.Exporters) {
components.Exporters = append(components.Exporters, componentWithStability{
Name: exp.Type(),
Module: factories.ExporterModules[exp.Type()],
Stability: map[string]string{
"logs": exp.LogsStability().String(),
"metrics": exp.MetricsStability().String(),
"traces": exp.TracesStability().String(),
},
})
}
components.BuildInfo = set.BuildInfo

yamlData, err := yaml.Marshal(components)
if err != nil {
return err
}
fmt.Fprint(cmd.OutOrStdout(), string(yamlData))
return nil
}

func sortFactoriesByType[T component.Factory](factories map[component.Type]T) []T {
// Gather component types (factories map keys)
componentTypes := make([]component.Type, 0, len(factories))
for componentType := range factories {
componentTypes = append(componentTypes, componentType)
}

// Sort component types as strings
sort.Slice(componentTypes, func(i, j int) bool {
return componentTypes[i].String() < componentTypes[j].String()
})

// Build and return list of factories, sorted by component types
sortedFactories := make([]T, 0, len(factories))
for _, componentType := range componentTypes {
sortedFactories = append(sortedFactories, factories[componentType])
}

return sortedFactories
}

0 comments on commit 5c51c6d

Please sign in to comment.