Skip to main content

Send Telemetry to Lightstep from WebAssembly in Go

Observability in Lightstep from WebAssembly

Overview

Enables the extraction of traces/spans from Wasm modules executing in a Golang program/application and emits them to Lightstep.

Installation

Install the Lightstep adapter from GitHub:

go get github.com/dylibso/observe-sdk/go/adapter/lightstep@latest

Example

A basic Go program that loads a Wasm module and executes it using the Wazero WebAssembly runtime.

package main

import (
"context"
"log"
"os"
"time"

"github.com/dylibso/observe-sdk/go/adapter/lightstep"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
)

func main() {
// create a context
ctx := context.Background()

// create a new Lightstep adapter with config
conf := &lightstep.LightstepConfig{
ApiKey: os.Getenv("LIGHTSTEP_API_KEY"),
ServiceName: "golang",
EmitTracesInterval: time.Second * 1,
TraceBatchMax: 100,
Host: "https://ingest.lightstep.com",
}

adapter := lightstep.NewLightstepAdapter(conf)

// start the Observe SDK adapter
defer adapter.Stop(true)
adapter.Start(ctx)

// load some Wasm from disk
wasm, err := os.ReadFile(os.Args[1])
if err != nil {
log.Panicln(err)
}

// setup a new Wazero runtime with config
wacfg := wazero.NewRuntimeConfig().WithCustomSections(true)
rt := wazero.NewRuntimeWithConfig(ctx, wacfg)

// apply the Observe SDK adapter to the Wazero runtime
traceCtx, err := adapter.NewTraceCtx(ctx, rt, wasm, nil)
if err != nil {
log.Panicln(err)
}

wasi_snapshot_preview1.MustInstantiate(ctx, rt)

// create a new Wazero configuration
modconfig := wazero.NewModuleConfig().
WithStdin(os.Stdin).
WithStdout(os.Stdout).
WithStderr(os.Stderr).
WithArgs(os.Args[1:]...).
WithStartFunctions("_start")

// instantiate the Wasm module
mod, err := rt.InstantiateWithConfig(ctx, wasm, modconfig)
if err != nil {
log.Println("module instance error:", err)
return
}
defer mod.Close(ctx)

// associate some additional metadata with the trace
meta := map[string]string{
"http.url": "https://example.com/my-endpoint",
"http.status_code": "200",
"http.client_ip": "192.168.1.0",
}
traceCtx.Metadata(meta)

// stop the trace
traceCtx.Finish()
}

Adapter Configuration

You may modify the behavior of your adapter by passing in a configuration when initializing the adapter. A configuration has the following fields:

config := &LightstepConfig{
// the URL of your OpenTelemetry collector
Host: "https://ingest.lightstep.com",
// your Lightstep API key
ApiKey: os.Getenv("LIGHTSTEP_API_KEY"),
// the dataset to group your observability data under
Dataset: "golang",
// how often to send traces
EmitTracesInterval: time.Second * 1,
// the maximum number of traces to send per request
TraceBatchMax: 100,
}
adapter := NewLightstepAdapter(config)