Skip to content
This repository has been archived by the owner on Dec 20, 2021. It is now read-only.

Upgrade to use OpenTelemetry version 0.13.0 #95

Merged
merged 1 commit into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 45 additions & 45 deletions example/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,37 @@ import (
"io/ioutil"
"log"
"net/http"
"net/http/httptrace"
"time"
"os"

"github.com/honeycombio/opentelemetry-exporter-go/honeycomb"

otelhttptrace "go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace"
otelhttp "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel/api/baggage"
"go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/trace"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/propagators"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/semconv"

"github.com/honeycombio/opentelemetry-exporter-go/honeycomb"
)

func initTracer(exporter *honeycomb.Exporter) {
// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
// In a production application, use sdktrace.ProbabilitySampler with a desired probability.
tp := sdktrace.NewTracerProvider(
sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
sdktrace.WithSyncer(exporter),
)
func initTracer(exporter *honeycomb.Exporter) func() {
bsp := sdktrace.NewBatchSpanProcessor(exporter)
tp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(bsp))
tp.ApplyConfig(
// The default takes parent sampler hints into account, which we don't need here.
sdktrace.Config{
// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
// In a production application, use sdktrace.ProbabilitySampler with a desired
// probability.
DefaultSampler: sdktrace.AlwaysSample(),
})
global.SetTracerProvider(tp)
global.SetTextMapPropagator(otel.NewCompositeTextMapPropagator(
propagators.TraceContext{},
propagators.Baggage{}))
return bsp.Shutdown
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See open-telemetry/opentelemetry-specification#1073 for how this situation might change soon. My comment open-telemetry/opentelemetry-specification#1073 (comment) addresses my use of NewBatchSpanProcessor above, as opposed to using WithBatcher.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open-telemetry/opentelemetry-go#1227 just merged, allowing shutting down a TracerProvider, in trun shutting down its registered span processors. Once we have release available that includes that new method, I'll propose an update to simplify this example.

}

func main() {
Expand All @@ -50,45 +58,37 @@ func main() {
log.Fatal(err)
}
defer exporter.Shutdown(context.Background())
defer initTracer(exporter)()
tr := global.Tracer("honeycomb/example/client")

initTracer(exporter)

url := flag.String("server", "http://localhost:7777/hello", "server url")
url := flag.String("server", "http://localhost:7777/hello", "server URL")
flag.Parse()

client := http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}

ctx := baggage.NewContext(context.Background(),
label.String("username", "donuts"),
)

ctx = httptrace.WithClientTrace(ctx, otelhttptrace.NewClientTrace(ctx))
ctx := otel.ContextWithBaggageValues(context.Background(),
label.String("username", "donuts"))

var body []byte

tr := global.Tracer("example/client")
err = func(ctx context.Context) error {
ctx, span := tr.Start(ctx, "say hello", trace.WithAttributes(semconv.PeerServiceKey.String("ExampleService")))
defer span.End()
req, _ := http.NewRequestWithContext(ctx, "GET", *url, nil)

fmt.Printf("Sending request...\n")
res, err := client.Do(req)
if err != nil {
panic(err)
}
body, err = ioutil.ReadAll(res.Body)
_ = res.Body.Close()
client := http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}

return err
}(ctx)
ctx, span := tr.Start(ctx, "say hello",
trace.WithAttributes(semconv.PeerServiceKey.String("ExampleService")))
defer span.End()

req, err := http.NewRequestWithContext(ctx, "GET", *url, nil)
if err != nil {
panic(err)
}
_, req = otelhttptrace.W3C(ctx, req)

fmt.Println("Sending request...")
res, err := client.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "HTTP request failed: %v\n", err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to read HTTP response body: %v\n", err)
}

fmt.Printf("Response Received: %s\n\n\n", body)
fmt.Printf("Waiting for few seconds to export spans ...\n\n")
time.Sleep(10 * time.Second)
fmt.Printf("Inspect traces on stdout\n")
fmt.Printf("Response received (HTTP status code %d): %s\n\n\n", res.StatusCode, body)
}
44 changes: 44 additions & 0 deletions example/server/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

import (
"io"
"net/http"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/trace"
"go.opentelemetry.io/otel/label"
)

func speakPlainTextTo(w http.ResponseWriter) {
w.Header().Add("Content-Type", "text/plain")
}

func makeHandler() http.Handler {
userNameKey := label.Key("username")
var mux http.ServeMux
mux.Handle("/hello",
http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
span := trace.SpanFromContext(ctx)

span.SetAttributes(label.String("ex.com/another", "yes"))

eventAttrs := make([]label.KeyValue, 1, 2)
eventAttrs[0] = label.Int("request-handled", 100)
userNameVal := otel.BaggageValue(ctx, userNameKey)
if userNameVal.Type() != label.INVALID {
attr := label.KeyValue{
Key: userNameKey,
Value: userNameVal,
}
span.SetAttributes(attr)
eventAttrs = append(eventAttrs, attr)
}
span.AddEvent(ctx, "handling this...", eventAttrs...)

speakPlainTextTo(w)
_, err := io.WriteString(w, "Hello, world!\n")
span.RecordError(ctx, err)
}))
return &mux
}
120 changes: 81 additions & 39 deletions example/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,94 @@ package main
import (
"context"
"flag"
"io"
"log"
"net"
"net/http"
"os"
"os/signal"
"sync"
"syscall"

"github.com/honeycombio/opentelemetry-exporter-go/honeycomb"

"go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace"
"go.opentelemetry.io/otel/api/baggage"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/trace"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/propagators"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

func initTracer(exporter *honeycomb.Exporter) {
// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
// In a production application, use sdktrace.ProbabilitySampler with a desired probability.
tp := sdktrace.NewTracerProvider(
sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
sdktrace.WithSyncer(exporter),
)
func initTracer(exporter *honeycomb.Exporter) func() {
bsp := sdktrace.NewBatchSpanProcessor(exporter)
tp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(bsp))
tp.ApplyConfig(
// The default takes parent sampler hints into account, which we don't need here.
sdktrace.Config{
// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
// In a production application, use sdktrace.ProbabilitySampler with a desired
// probability.
DefaultSampler: sdktrace.AlwaysSample(),
})
global.SetTracerProvider(tp)
global.SetTextMapPropagator(otel.NewCompositeTextMapPropagator(
propagators.TraceContext{},
propagators.Baggage{}))
return bsp.Shutdown
}

func joinIPAddressAndPort(address net.IP, port string) string {
var host string
var empty net.IP
if !address.Equal(empty) {
host = address.String()
}
return net.JoinHostPort(host, port)
}

func runHTTPServer(address net.IP, port string, handler http.Handler, stop <-chan struct{}) error {
server := &http.Server{
Addr: joinIPAddressAndPort(address, port),
Handler: handler,
}
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
<-stop
// Don't bother imposing a timeout here.
server.Shutdown(context.Background())
}()
if err := server.ListenAndServe(); err != http.ErrServerClosed {
return err
}
wg.Wait()
return nil
}

func handleSignals(term func()) {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
<-c
signal.Stop(c)
term()
}

func main() {
apikey := flag.String("apikey", "", "Your Honeycomb API Key")
dataset := flag.String("dataset", "opentelemetry", "Your Honeycomb dataset")
serverAddress := flag.String("server-address", "", "IP address on which to serve HTTP requests")
serverPort := flag.String("server-port", "7777", "Port on which to serve HTTP requests")
flag.Parse()

var serverIPAddress net.IP
if len(*serverAddress) > 0 {
if serverIPAddress = net.ParseIP(*serverAddress); serverIPAddress == nil {
log.Fatalf("server address %q is not a valid IP address", *serverAddress)
}
}

ctx := context.Background()

exporter, err := honeycomb.NewExporter(
honeycomb.Config{
APIKey: *apikey,
Expand All @@ -57,35 +116,18 @@ func main() {
log.Fatal(err)
}
defer exporter.Shutdown(context.Background())
defer initTracer(exporter)()

initTracer(exporter)

tr := global.Tracer("honeycomb/example/server")

helloHandler := func(w http.ResponseWriter, req *http.Request) {
attrs, tags, spanCtx := otelhttptrace.Extract(req.Context(), req)

req = req.WithContext(baggage.ContextWithMap(req.Context(), baggage.NewMap(baggage.MapUpdate{
MultiKV: tags,
})))
ctx, cancel := context.WithCancel(ctx)
defer cancel()

ctx, span := tr.Start(
trace.ContextWithRemoteSpanContext(req.Context(), spanCtx),
"hello",
trace.WithAttributes(attrs...),
trace.WithLinks(trace.Link{SpanContext: spanCtx, Attributes: attrs}),
)
defer span.End()
go handleSignals(cancel)
stop := ctx.Done()

span.SetAttributes(label.String("ex.com/another", "yes"))
span.AddEvent(ctx, "handling this...", label.Int("request-handled", 100))

_, _ = io.WriteString(w, "Hello, world!\n")
}

http.HandleFunc("/hello", helloHandler)
err = http.ListenAndServe(":7777", nil)
if err != nil {
log.Fatal(err)
handler := otelhttp.NewHandler(makeHandler(), "serve-http",
otelhttp.WithPublicEndpoint(),
otelhttp.WithMessageEvents(otelhttp.ReadEvents, otelhttp.WriteEvents))
if err := runHTTPServer(serverIPAddress, *serverPort, handler, stop); err != nil {
log.Fatalf("HTTP server failed: %v", err)
}
}
9 changes: 4 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ require (
github.com/klauspost/compress v1.10.10 // indirect
github.com/stretchr/testify v1.6.1
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.12.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.12.0
go.opentelemetry.io/otel v0.12.0
go.opentelemetry.io/otel/sdk v0.12.0
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.13.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.13.0
go.opentelemetry.io/otel v0.13.0
go.opentelemetry.io/otel/sdk v0.13.0
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/grpc v1.32.0
google.golang.org/protobuf v1.25.0 // indirect
)
Loading