Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collector example: add metrics and use official port #4466

Merged
merged 13 commits into from
Sep 7, 2023
13 changes: 12 additions & 1 deletion example/otel-collector/go.mod
Expand Up @@ -9,8 +9,11 @@ replace (

require (
go.opentelemetry.io/otel v1.17.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.40.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0
go.opentelemetry.io/otel/metric v1.17.0
go.opentelemetry.io/otel/sdk v1.17.0
go.opentelemetry.io/otel/sdk/metric v0.40.0
go.opentelemetry.io/otel/trace v1.17.0
google.golang.org/grpc v1.57.0
)
Expand All @@ -21,8 +24,8 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.40.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 // indirect
go.opentelemetry.io/otel/metric v1.17.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.11.0 // indirect
Expand All @@ -39,3 +42,11 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace => ../../exporters/otl
replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc => ../../exporters/otlp/otlptrace/otlptracegrpc

replace go.opentelemetry.io/otel/metric => ../../metric

replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../../exporters/otlp/otlpmetric/otlpmetricgrpc

replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../../exporters/otlp/otlpmetric

replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

replace go.opentelemetry.io/otel/exporters/otlp/internal/retry => ../../exporters/otlp/internal/retry
94 changes: 78 additions & 16 deletions example/otel-collector/main.go
Expand Up @@ -30,37 +30,30 @@ import (

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/propagation"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
"go.opentelemetry.io/otel/trace"
)

// Initializes an OTLP exporter, and configures the corresponding trace and
// metric providers.
func initProvider() (func(context.Context) error, error) {
// Initialize a gRPC connection to be used by both the tracer and meter
// providers.
func initConn() (*grpc.ClientConn, error) {
ctx := context.Background()

res, err := resource.New(ctx,
resource.WithAttributes(
// the service name used to display traces in backends
semconv.ServiceName("test-service"),
),
)
if err != nil {
return nil, fmt.Errorf("failed to create resource: %w", err)
}

// If the OpenTelemetry Collector is running on a local cluster (minikube or
// microk8s), it should be accessible through the NodePort service at the
// `localhost:30080` endpoint. Otherwise, replace `localhost` with the
// `localhost:4317` endpoint. Otherwise, replace `localhost` with the
// endpoint of your cluster. If you run the app inside k8s, then you can
// probably connect directly to the service through dns.
ctx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
conn, err := grpc.DialContext(ctx, "localhost:30080",
conn, err := grpc.DialContext(ctx, "localhost:4317",
// Note the use of insecure transport here. TLS is recommended in production.
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock(),
Expand All @@ -69,6 +62,24 @@ func initProvider() (func(context.Context) error, error) {
return nil, fmt.Errorf("failed to create gRPC connection to collector: %w", err)
}

return conn, err
}

// Initializes an OTLP exporter, and configures the corresponding trace
// provider.
func initTracerProvider(conn *grpc.ClientConn) (func(context.Context) error, error) {
ctx := context.Background()

res, err := resource.New(ctx,
resource.WithAttributes(
// the service name used to display traces in backends
semconv.ServiceName("test-service"),
),
)
if err != nil {
return nil, fmt.Errorf("failed to create resource: %w", err)
}

// Set up a trace exporter
traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithGRPCConn(conn))
if err != nil {
Expand All @@ -92,13 +103,47 @@ func initProvider() (func(context.Context) error, error) {
return tracerProvider.Shutdown, nil
}

// Initializes an OTLP exporter, and configures the corresponding meter
// provider.
func initMeterProvider(conn *grpc.ClientConn) (func(context.Context) error, error) {
ctx := context.Background()

res, err := resource.New(ctx,
resource.WithAttributes(
// the service name used to display traces in backends
semconv.ServiceName("test-service"),
),
)
if err != nil {
return nil, fmt.Errorf("failed to create resource: %w", err)
}

metricExporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithGRPCConn(conn))
if err != nil {
return nil, fmt.Errorf("failed to create metrics exporter: %w", err)
}

meterProvider := sdkmetric.NewMeterProvider(
sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExporter)),
sdkmetric.WithResource(res),
)
otel.SetMeterProvider(meterProvider)

return meterProvider.Shutdown, nil
}

func main() {
log.Printf("Waiting for connection...")

ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()

shutdown, err := initProvider()
conn, err := initConn()
if err != nil {
log.Fatal(err)
}

shutdown, err := initTracerProvider(conn)
if err != nil {
log.Fatal(err)
}
Expand All @@ -108,7 +153,18 @@ func main() {
}
}()

shutdown, err = initMeterProvider(conn)
if err != nil {
log.Fatal(err)
}
defer func() {
if err := shutdown(ctx); err != nil {
log.Fatal("failed to shutdown MeterProvider: %w", err)
}
}()

tracer := otel.Tracer("test-tracer")
meter := otel.Meter("test-meter")

// Attributes represent additional key-value descriptors that can be bound
// to a metric observer or recorder.
Expand All @@ -118,6 +174,11 @@ func main() {
attribute.String("attrC", "vanilla"),
}

runCount, err := meter.Int64Counter("run", metric.WithDescription("The number of times the iteration ran"))
if err != nil {
log.Fatal(err)
}

// work begins
ctx, span := tracer.Start(
ctx,
Expand All @@ -126,6 +187,7 @@ func main() {
defer span.End()
for i := 0; i < 10; i++ {
_, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i))
runCount.Add(ctx, 5, metric.WithAttributes(commonAttrs...))
dmathieu marked this conversation as resolved.
Show resolved Hide resolved
log.Printf("Doing really hard work (%d / 10)\n", i+1)

<-time.After(time.Second)
Expand Down