Skip to content

Commit

Permalink
Replace default collector command line args with custom ones (#98)
Browse files Browse the repository at this point in the history
Closes #85, closes #87

- Allows us to easily set http, grpc, and browser endpoints via the
command line
- Replaces the default collector commands, since we are hardcoding our
`ConfigProvider` settings anyway
- Works on Windows!
  • Loading branch information
CtrlSpice authored Mar 7, 2023
1 parent 4938a6c commit 167efb4
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 53 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
include:
- os: windows-latest
env:
NO_WINDOWS_SERVICE: 0


steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: 1.19

- name: Build
run: go build -v
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.DS_Store
otel-desktop-viewer
desktop-exporter/node_modules
.vscode
.vscode/*
106 changes: 64 additions & 42 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,58 @@ package main

import (
"log"
"strconv"

"github.com/spf13/cobra"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/confmap"
"go.opentelemetry.io/collector/confmap/provider/yamlprovider"
"go.opentelemetry.io/collector/otelcol"
)

func main() {
// We want this to be as easy to use as possible
// so we don't need the user to include a config
configContents := `yaml:
info := component.BuildInfo{
Command: "otel-desktop-viewer",
Description: "Basic OTel with Custom Desktop Exporter",
Version: "0.1.1",
}

if err := run(info); err != nil {
log.Fatal(err)
}
}

func runInteractive(buildInfo component.BuildInfo) error {
cmd := newCommand(buildInfo)
if err := cmd.Execute(); err != nil {
log.Fatalf("collector server run finished with error: %v", err)
}

return nil
}

func newCommand(info component.BuildInfo) *cobra.Command {
var httpPortFlag, grpcPortFlag, browserPortFlag int

rootCmd := &cobra.Command{
Use: info.Command,
Version: info.Version,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
configContents := `yaml:
receivers:
otlp:
protocols:
http:
endpoint: localhost:4318
endpoint: localhost:` + strconv.Itoa(httpPortFlag) + `
grpc:
endpoint: localhost:4317
endpoint: localhost:` + strconv.Itoa(grpcPortFlag) + `
processors:
exporters:
desktop:
endpoint: localhost:8000
endpoint: localhost:` + strconv.Itoa(browserPortFlag) + `
service:
pipelines:
Expand All @@ -36,46 +64,40 @@ service:
exporters:
- desktop`

factories, err := components()
if err != nil {
log.Fatalf("failed to build components: %v", err)
}

info := component.BuildInfo{
Command: "otel-desktop-viewer",
Description: "Basic OTel with Custom Desktop Exporter",
Version: "0.0.2",
}
factories, err := components()
if err != nil {
log.Fatalf("failed to build components: %v", err)
}

provider := yamlprovider.New()
set := otelcol.ConfigProviderSettings{
ResolverSettings: confmap.ResolverSettings{
URIs: []string{configContents},
Providers: map[string]confmap.Provider{provider.Scheme(): provider},
},
}

configProvider, err := otelcol.NewConfigProvider(set)
if err != nil {
log.Fatal(err)
}
provider := yamlprovider.New()
configProviderSettings := otelcol.ConfigProviderSettings{
ResolverSettings: confmap.ResolverSettings{
URIs: []string{configContents},
Providers: map[string]confmap.Provider{provider.Scheme(): provider},
},
}

settings := otelcol.CollectorSettings{
BuildInfo: info,
Factories: factories,
ConfigProvider: configProvider,
}
configProvider, err := otelcol.NewConfigProvider(configProviderSettings)
if err != nil {
log.Fatal(err)
}

if err := run(settings); err != nil {
log.Fatal(err)
}
}
collectorSettings := otelcol.CollectorSettings{
BuildInfo: info,
Factories: factories,
ConfigProvider: configProvider,
}

func runInteractive(params otelcol.CollectorSettings) error {
cmd := otelcol.NewCommand(params)
if err := cmd.Execute(); err != nil {
log.Fatalf("collector server run finished with error: %v", err)
col, err := otelcol.NewCollector(collectorSettings)
if err != nil {
return err
}
return col.Run(cmd.Context())
},
}

return nil
rootCmd.Flags().IntVar(&httpPortFlag, "http", 4318, "The port number on which we listen for OTLP http payloads")
rootCmd.Flags().IntVar(&grpcPortFlag, "grpc", 4317, "The port number on which we listen for OTLP grpc payloads")
rootCmd.Flags().IntVar(&browserPortFlag, "browser", 8000, "The port number where we expose our data")
return rootCmd
}
6 changes: 3 additions & 3 deletions main_others.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 58 additions & 7 deletions main_windows.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
// Code generated by "go.opentelemetry.io/collector/cmd/builder". DO NOT EDIT.

// go:build windows
//go:build windows
// +build windows

package main

import (
"fmt"
"log"
"os"

"golang.org/x/sys/windows/svc"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/confmap"
"go.opentelemetry.io/collector/confmap/provider/yamlprovider"
"go.opentelemetry.io/collector/otelcol"
)

func run(params otelcol.CollectorSettings) error {
func run(buildInfo component.BuildInfo) error {
if useInteractiveMode, err := checkUseInteractiveMode(); err != nil {
return err
} else if useInteractiveMode {
return runInteractive(params)
return runInteractive(buildInfo)
} else {
return runService(params)
return runService(buildInfo)
}
}

Expand All @@ -40,9 +43,57 @@ func checkUseInteractiveMode() (bool, error) {
return !isWindowsService, nil
}

func runService(params otelcol.CollectorSettings) error {
func runService(buildInfo component.BuildInfo) error {
configContents := `yaml:
receivers:
otlp:
protocols:
http:
endpoint: localhost:4318
grpc:
endpoint: localhost:4317
processors:
exporters:
desktop:
endpoint: localhost:8000
service:
pipelines:
traces:
receivers:
- otlp
processors: []
exporters:
- desktop`

factories, err := components()
if err != nil {
log.Fatalf("failed to build components: %v", err)
}

provider := yamlprovider.New()
configProviderSettings := otelcol.ConfigProviderSettings{
ResolverSettings: confmap.ResolverSettings{
URIs: []string{configContents},
Providers: map[string]confmap.Provider{provider.Scheme(): provider},
},
}

configProvider, err := otelcol.NewConfigProvider(configProviderSettings)
if err != nil {
log.Fatal(err)
}

collectorSettings := otelcol.CollectorSettings{
BuildInfo: buildInfo,
Factories: factories,
ConfigProvider: configProvider,
}

// do not need to supply service name when startup is invoked through Service Control Manager directly
if err := svc.Run("", otelcol.NewSvcHandler(params)); err != nil {
if err := svc.Run("", otelcol.NewSvcHandler(collectorSettings)); err != nil {
return fmt.Errorf("failed to start collector server: %w", err)
}

Expand Down

0 comments on commit 167efb4

Please sign in to comment.