diff --git a/internal/pkg/otel/README.md b/internal/pkg/otel/README.md new file mode 100644 index 00000000000..eeac70dc574 --- /dev/null +++ b/internal/pkg/otel/README.md @@ -0,0 +1,58 @@ +# Elastic Distribution for OpenTelemetry Collector + +This is an Elastic supported distribution of the [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector). + +## Running the Elastic Distribution for OpenTelemetry Collector + +To run the Elastic Distribution for OpenTelemetry Collector you can use Elastic-Agent binary downloaded for your OS and architecture. +Running command + +```bash +./elastic-agent -c otel.yml run +``` + +from unpacked Elastic Agent package will run Elastic-Agent as an OpenTelemetry Collector. The `-c` flag needs to point to [OpenTelemetry Collector Configuration file](https://opentelemetry.io/docs/collector/configuration/) named `otel`, `otlp` or `otelcol`. +Both `yaml` and `yml` suffixes are supported. + +> In case this condition is not met, Elastic Agent will run in its default mode and will not behave as OpenTelemetry Collector. + +Note that `validate` subcommand and [feature gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md#controlling-gates) are not supported yet. + +## Components + +This section provides a summary of components included in the Elastic Distribution for OpenTelemetry Collector. + + +### Receivers + +| Component | Version | +|---|---| +| filelogreceiver | v0.89.0| +| otlpreceiver | v0.89.0| + + + + +### Exporters + +| Component | Version | +|---|---| +| fileexporter | v0.89.0| +| debugexporter | v0.89.0| +| otlpexporter | v0.89.0| + + + + +### Processors + +| Component | Version | +|---|---| +| attributesprocessor | v0.89.0| +| resourceprocessor | v0.89.0| +| transformprocessor | v0.89.0| +| batchprocessor | v0.89.0| +| memorylimiterprocessor | v0.89.0| + + + diff --git a/internal/pkg/otel/templates/README.md.tmpl b/internal/pkg/otel/templates/README.md.tmpl new file mode 100644 index 00000000000..0470c57a012 --- /dev/null +++ b/internal/pkg/otel/templates/README.md.tmpl @@ -0,0 +1,59 @@ +# Elastic Distribution for OpenTelemetry Collector + +This is an Elastic supported distribution of the [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector). + +## Running the Elastic Distribution for OpenTelemetry Collector + +To run the Elastic Distribution for OpenTelemetry Collector you can use Elastic-Agent binary downloaded for your OS and architecture. +Running command + +```bash +./elastic-agent -c otel.yml run +``` + +from unpacked Elastic Agent package will run Elastic-Agent as an OpenTelemetry Collector. The `-c` flag needs to point to [OpenTelemetry Collector Configuration file](https://opentelemetry.io/docs/collector/configuration/) named `otel`, `otlp` or `otelcol`. +Both `yaml` and `yml` suffixes are supported. + +> In case this condition is not met, Elastic Agent will run in its default mode and will not behave as OpenTelemetry Collector. + +Note that `validate` subcommand and [feature gates](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md#controlling-gates) are not supported yet. + +## Components + +This section provides a summary of components included in the Elastic Distribution for OpenTelemetry Collector. + +{{ if .Receivers }} +### Receivers + +| Component | Version | +|---|---| +{{ range .Receivers }}| {{ .Name }} | {{ .Version -}} | +{{ end }} +{{ end }} + +{{ if .Exporters }} +### Exporters + +| Component | Version | +|---|---| +{{ range .Exporters }}| {{ .Name }} | {{ .Version -}} | +{{ end }} +{{ end }} + +{{ if .Processors }} +### Processors + +| Component | Version | +|---|---| +{{ range .Processors }}| {{ .Name }} | {{ .Version -}} | +{{ end }} +{{ end }} + +{{ if .Extensions }} +### Extensions + +| Component | Version | +|---|---| +{{ range .Extensions }}| {{ .Name }} | {{ .Version -}} | +{{ end }} +{{ end }} \ No newline at end of file diff --git a/magefile.go b/magefile.go index 6853d82ea3b..edfb9391c3d 100644 --- a/magefile.go +++ b/magefile.go @@ -12,6 +12,7 @@ import ( "encoding/json" "errors" "fmt" + "html/template" "log" "os" "os/exec" @@ -120,6 +121,9 @@ type Cloud mg.Namespace // Integration namespace contains tasks related to operating and running integration tests. type Integration mg.Namespace +// Otel namespace contains Open Telemetry related tasks. +type Otel mg.Namespace + func CheckNoChanges() error { fmt.Println(">> fmt - go run") err := sh.RunV("go", "mod", "tidy", "-v") @@ -550,7 +554,7 @@ func commitID() string { // Update is an alias for executing control protocol, configs, and specs. func Update() { - mg.SerialDeps(Config, BuildPGP, BuildFleetCfg) + mg.SerialDeps(Config, BuildPGP, BuildFleetCfg, Otel.Readme) } // CrossBuild cross-builds the beat for all target platforms. @@ -2243,3 +2247,118 @@ func hasCleanOnExit() bool { b, _ := strconv.ParseBool(clean) return b } + +type dependency struct { + Name string + Version string +} + +type dependencies struct { + Receivers []dependency + Exporters []dependency + Processors []dependency + Extensions []dependency +} + +func (d dependency) Clean(sep string) dependency { + cleanFn := func(dep, sep string) string { + chunks := strings.SplitN(dep, sep, 2) + if len(chunks) == 2 { + return chunks[1] + } + + return dep + } + + return dependency{ + Name: cleanFn(d.Name, sep), + Version: d.Version, + } +} + +func (Otel) Readme() error { + fmt.Println(">> Building internal/pkg/otel/README.md") + + readmeTmpl := filepath.Join("internal", "pkg", "otel", "templates", "README.md.tmpl") + readmeOut := filepath.Join("internal", "pkg", "otel", "README.md") + + // read README template + tmpl, err := template.ParseFiles(readmeTmpl) + if err != nil { + return fmt.Errorf("failed to parse README template: %w", err) + } + + data, err := getOtelDependencies() + if err != nil { + return fmt.Errorf("Failed to get OTel dependencies: %w", err) + } + + // resolve template + out, err := os.OpenFile(readmeOut, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) + if err != nil { + return fmt.Errorf("failed to open file %s: %w", readmeOut, err) + } + defer out.Close() + + return tmpl.Execute(out, data) +} + +func getOtelDependencies() (*dependencies, error) { + // read go.mod + readFile, err := os.Open("go.mod") + if err != nil { + return nil, err + } + defer readFile.Close() + + scanner := bufio.NewScanner(readFile) + + scanner.Split(bufio.ScanLines) + var receivers, extensions, exporters, processors []dependency + // process imports + for scanner.Scan() { + l := strings.TrimSpace(scanner.Text()) + // is otel + if !strings.Contains(l, "go.opentelemetry.io/") && + !strings.Contains(l, "github.com/open-telemetry/") { + continue + } + + if strings.Contains(l, "// indirect") { + continue + } + + parseLine := func(line string) (dependency, error) { + chunks := strings.SplitN(line, " ", 2) + if len(chunks) != 2 { + return dependency{}, fmt.Errorf("incorrect format for line %q", line) + } + return dependency{ + Name: chunks[0], + Version: chunks[1], + }, nil + } + + d, err := parseLine(l) + if err != nil { + return nil, err + } + + if strings.Contains(l, "/receiver/") { + receivers = append(receivers, d.Clean("/receiver/")) + } else if strings.Contains(l, "/processor/") { + processors = append(processors, d.Clean("/processor/")) + } else if strings.Contains(l, "/exporter/") { + exporters = append(exporters, d.Clean("/exporter/")) + } else if strings.Contains(l, "/extension/") { + extensions = append(extensions, d.Clean("/extension/")) + } + } + + return &dependencies{ + Receivers: receivers, + Exporters: exporters, + Processors: processors, + Extensions: extensions, + }, nil +}