From f22b50473d27d52b5e50126424a05478c68d1552 Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Thu, 12 Feb 2026 00:04:47 -0600 Subject: [PATCH 1/3] feat: enable wasi-otel if available Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- README.md | 6 ++++-- cmd/root.go | 35 +++++++++++++++++++++++++++++++++++ cmd/up.go | 39 ++++++++++++++++++++++++++++++++------- go.mod | 1 + go.sum | 2 ++ otel-config/loki.yaml | 2 +- 6 files changed, 75 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a870bcc..85a8701 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This is a plugin that makes it easy to use OTel with Spin. ## Background -Spin applications have the ability to export metrics and trace data. This plugin provides dashboards for viewing the data. +Spin applications have the ability to export metrics, logs, and trace data. This plugin provides dashboards for viewing the data. ## Requirements @@ -71,7 +71,7 @@ spin otel setup --aspire ``` -## Run a Spin app that exports telemetry data +## Run a Spin app and exports telemetry data ```sh spin otel up @@ -83,6 +83,8 @@ Any flags that work with the `spin up` command, will work with the `spin otel up spin otel up -- --help ``` +Additionally, the `spin otel up` command enables the `wasi-otel` features in Spin, which means that users will be able to instrument their applications with OpenTelemetry using the [opentelemetry-wasi](github.com/bytecodealliance/opentelemetry-wasi) SDKs. + ## Open the dashboards in the default browser Depending on the chosen observability stack, you can use the sub-commands of `spin otel open` to open corresponding dashboards using your default browser. diff --git a/cmd/root.go b/cmd/root.go index 2e721d8..a5b323d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,6 +7,7 @@ import ( "path" "strings" + "github.com/Masterminds/semver" open "github.com/fermyon/otel-plugin/cmd/open" "github.com/spf13/cobra" ) @@ -83,6 +84,40 @@ func detectContainerRuntime() (string, error) { return runtime, nil } +func getSpinVersion() (*semver.Version, error) { + spin, err := getSpinPath() + if err != nil { + return nil, err + } + + cmd := exec.Command(spin, "--version") + output, err := cmd.CombinedOutput() + if err != nil { + return nil, err + } + + outputParts := strings.Split(string(output), " ") + if len(outputParts) < 2 { + return nil, fmt.Errorf("Spin appears to have changed how it formats its version flag output. Expected \"spin {{VERSION}}\", got %s", string(output)) + } + + semver, err := semver.NewVersion(outputParts[1]) + if err != nil { + return nil, fmt.Errorf("Spin version is not valid semver: %v", err) + } + + return semver, nil +} + +func getSpinPath() (string, error) { + pathToSpin := os.Getenv("SPIN_BIN_PATH") + if pathToSpin == "" { + return "", fmt.Errorf("Please ensure that you are running \"spin otel up\", rather than calling the OpenTelemetry plugin binary directly") + } + + return pathToSpin, nil +} + func Execute() { if err := setOtelConfigPath(); err != nil { fmt.Fprintln(os.Stderr, fmt.Errorf("Error finding the \"otel-config\" directory: %w", err)) diff --git a/cmd/up.go b/cmd/up.go index 340577e..89d1ce2 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -1,17 +1,23 @@ package cmd import ( - "fmt" "os" "os/exec" + "github.com/Masterminds/semver" "github.com/spf13/cobra" ) +var experimentalWasiOtel = false + +func init() { + upCmd.Flags().BoolVarP(&experimentalWasiOtel, "experimental-wasi-otel", "", false, "Enable the experimental wasi-otel feature in Spin") +} + var upCmd = &cobra.Command{ Use: "up", - Short: "Runs a Spin App with the default OpenTelemetry environment variables.", - Long: "Runs a Spin App with the default OpenTelemetry environment variables. Any flags that work with the \"spin up\" command, will work with the \"spin otel up\" command: \"spin otel up -- --help\"", + Short: "Runs a Spin App with the default OpenTelemetry environment variables and wasi-otel features enabled.", + Long: "Runs a Spin App with the default OpenTelemetry environment variables and wasi-otel features enabled. Any flags that work with the \"spin up\" command, will work with the \"spin otel up\" command: \"spin otel up -- --help\"", RunE: func(cmd *cobra.Command, args []string) error { if err := up(args); err != nil { return err @@ -22,13 +28,19 @@ var upCmd = &cobra.Command{ } func up(args []string) error { - pathToSpin := os.Getenv("SPIN_BIN_PATH") - if pathToSpin == "" { - return fmt.Errorf("Please ensure that you are running \"spin otel up\", rather than calling the OpenTelemetry plugin binary directly") + pathToSpin, err := getSpinPath() + if err != nil { + return err + } + + cmdArgs := []string{"up"} + + if spinHasWasiOtel() { + cmdArgs = append(cmdArgs, "--experimental-wasi-otel") } // Passing flags and args after the '--' - cmdArgs := append([]string{"up"}, args...) + cmdArgs = append(cmdArgs, args...) cmd := exec.Command(pathToSpin, cmdArgs...) cmd.Env = append( os.Environ(), @@ -41,3 +53,16 @@ func up(args []string) error { return cmd.Run() } + +func spinHasWasiOtel() bool { + spinVersion, err := getSpinVersion() + if err != nil { + // This means something is wrong with Spin + panic(err) + } + + // The "-0" suffix enables the use of a pre-release >= 3.6.0 + constraints, err := semver.NewConstraint(">= 3.6.0-0") + spinVersionHasWasiOtel, _ := constraints.Validate(spinVersion) + return spinVersionHasWasiOtel +} diff --git a/go.mod b/go.mod index b155107..f0951ad 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( ) require ( + github.com/Masterminds/semver v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/sys v0.1.0 // indirect diff --git a/go.sum b/go.sum index a656f1f..0085d2d 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= diff --git a/otel-config/loki.yaml b/otel-config/loki.yaml index 2426182..187b274 100644 --- a/otel-config/loki.yaml +++ b/otel-config/loki.yaml @@ -24,6 +24,6 @@ schema_config: storage_config: filesystem: directory: /tmp/loki/chunks - + analytics: reporting_enabled: false From 90391826b95860cb16bf19c3552cd747ee365718 Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:24:51 -0600 Subject: [PATCH 2/3] fix: use spin env vars to check version Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- cmd/root.go | 26 -------------------------- cmd/up.go | 27 +++++++++++++++++++-------- go.mod | 1 - go.sum | 2 -- 4 files changed, 19 insertions(+), 37 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index a5b323d..373f257 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,7 +7,6 @@ import ( "path" "strings" - "github.com/Masterminds/semver" open "github.com/fermyon/otel-plugin/cmd/open" "github.com/spf13/cobra" ) @@ -84,31 +83,6 @@ func detectContainerRuntime() (string, error) { return runtime, nil } -func getSpinVersion() (*semver.Version, error) { - spin, err := getSpinPath() - if err != nil { - return nil, err - } - - cmd := exec.Command(spin, "--version") - output, err := cmd.CombinedOutput() - if err != nil { - return nil, err - } - - outputParts := strings.Split(string(output), " ") - if len(outputParts) < 2 { - return nil, fmt.Errorf("Spin appears to have changed how it formats its version flag output. Expected \"spin {{VERSION}}\", got %s", string(output)) - } - - semver, err := semver.NewVersion(outputParts[1]) - if err != nil { - return nil, fmt.Errorf("Spin version is not valid semver: %v", err) - } - - return semver, nil -} - func getSpinPath() (string, error) { pathToSpin := os.Getenv("SPIN_BIN_PATH") if pathToSpin == "" { diff --git a/cmd/up.go b/cmd/up.go index 89d1ce2..00464d7 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -3,8 +3,8 @@ package cmd import ( "os" "os/exec" + "strconv" - "github.com/Masterminds/semver" "github.com/spf13/cobra" ) @@ -55,14 +55,25 @@ func up(args []string) error { } func spinHasWasiOtel() bool { - spinVersion, err := getSpinVersion() + major, err := strconv.Atoi(os.Getenv("SPIN_VERSION_MAJOR")) if err != nil { - // This means something is wrong with Spin - panic(err) + panic("Something went wrong parsing the SPIN_VERSION_MAJOR env var: " + err.Error()) } - // The "-0" suffix enables the use of a pre-release >= 3.6.0 - constraints, err := semver.NewConstraint(">= 3.6.0-0") - spinVersionHasWasiOtel, _ := constraints.Validate(spinVersion) - return spinVersionHasWasiOtel + minor, err := strconv.Atoi(os.Getenv("SPIN_VERSION_MINOR")) + if err != nil { + panic("Something went wrong parsing the SPIN_VERSION_MINOR env var: " + err.Error()) + } + + if major < 3 { + return false + } else if major > 3 { + return true + } else { // if major == 3 + if minor >= 6 { + return true + } else { + return false + } + } } diff --git a/go.mod b/go.mod index f0951ad..b155107 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ require ( ) require ( - github.com/Masterminds/semver v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/sys v0.1.0 // indirect diff --git a/go.sum b/go.sum index 0085d2d..a656f1f 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= From 3c7024ee7e6f808787ddbe69d58cb296067fdce2 Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Wed, 18 Feb 2026 18:07:35 -0600 Subject: [PATCH 3/3] fix: update readme Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 85a8701..acf54d4 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Any flags that work with the `spin up` command, will work with the `spin otel up spin otel up -- --help ``` -Additionally, the `spin otel up` command enables the `wasi-otel` features in Spin, which means that users will be able to instrument their applications with OpenTelemetry using the [opentelemetry-wasi](github.com/bytecodealliance/opentelemetry-wasi) SDKs. +Additionally, the `spin otel up` command enables the `wasi-otel` features in versions of Spin >= v3.6.0, which means that users will be able to instrument their applications with OpenTelemetry using the [opentelemetry-wasi](github.com/bytecodealliance/opentelemetry-wasi) SDKs. ## Open the dashboards in the default browser