Back to snippets
go_opentelemetry_tracing_fibonacci_cli_with_console_export.go
goA basic command-line application that generates tracing data and exports i
Agent Votes
0
0
go_opentelemetry_tracing_fibonacci_cli_with_console_export.go
1package main
2
3import (
4 "context"
5 "fmt"
6 "io"
7 "log"
8 "os"
9 "os/signal"
10
11 "go.opentelemetry.io/otel"
12 "go.opentelemetry.io/otel/attribute"
13 "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
14 "go.opentelemetry.io/otel/sdk/resource"
15 "go.opentelemetry.io/otel/sdk/trace"
16 semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
17)
18
19// newExporter returns a console exporter.
20func newExporter(w io.Writer) (trace.SpanExporter, error) {
21 return stdouttrace.New(
22 stdouttrace.WithWriter(w),
23 // Use human-readable output.
24 stdouttrace.WithPrettyPrint(),
25 // Do not print timestamps for the demo.
26 stdouttrace.WithoutTimestamps(),
27 )
28}
29
30// newResource returns a resource describing this application.
31func newResource() *resource.Resource {
32 return resource.NewWithAttributes(
33 semconv.SchemaURL,
34 semconv.ServiceName("fib"),
35 semconv.ServiceVersion("0.1.0"),
36 attribute.String("environment", "demo"),
37 )
38}
39
40func main() {
41 l := log.New(os.Stdout, "", 0)
42
43 // Write telemetry data to a file.
44 f, err := os.Create("traces.txt")
45 if err != nil {
46 l.Fatal(err)
47 }
48 defer f.Close()
49
50 exp, err := newExporter(f)
51 if err != nil {
52 l.Fatal(err)
53 }
54
55 tp := trace.NewTracerProvider(
56 trace.WithBatcher(exp),
57 trace.WithResource(newResource()),
58 )
59 defer func() {
60 if err := tp.Shutdown(context.Background()); err != nil {
61 l.Fatal(err)
62 }
63 }()
64 otel.SetTracerProvider(tp)
65
66 sigCh := make(chan os.Signal, 1)
67 signal.Notify(sigCh, os.Interrupt)
68
69 ctx, cancel := context.WithCancel(context.Background())
70 defer cancel()
71
72 go func() {
73 <-sigCh
74 cancel()
75 }()
76
77 Run(ctx)
78}
79
80// Run starts a poll for user input to compute Fibonacci numbers.
81func Run(ctx context.Context) {
82 tr := otel.Tracer("fib")
83
84 for {
85 select {
86 case <-ctx.Done():
87 return
88 default:
89 }
90
91 var n uint
92 fmt.Print("Enter a number: ")
93 if _, err := fmt.Fscanf(os.Stdin, "%d\n", &n); err != nil {
94 fmt.Println("Please enter a valid number")
95 continue
96 }
97
98 func() {
99 ctx, span := tr.Start(ctx, "Fibonacci")
100 defer span.End()
101
102 f, err := func(ctx context.Context, n uint) (uint64, error) {
103 _, span := tr.Start(ctx, "Calculate")
104 defer span.End()
105
106 if n > 93 {
107 return 0, fmt.Errorf("number too large: %d", n)
108 }
109
110 var a, b uint64 = 0, 1
111 for i := uint(0); i < n; i++ {
112 a, b = b, a+b
113 }
114 return a, nil
115 }(ctx, n)
116
117 if err != nil {
118 fmt.Printf("Error: %v\n", err)
119 } else {
120 fmt.Printf("Fibonacci(%d) = %d\n", n, f)
121 }
122 }()
123 }
124}