1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-01-03 22:52:30 +02:00
opentelemetry-go/sdk/metric/example_test.go
2024-05-19 07:16:33 +02:00

243 lines
6.8 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package metric_test
import (
"context"
"fmt"
"log"
"regexp"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
)
// To enable metrics in your application using the SDK,
// you'll need to have an initialized [MeterProvider]
// that will let you create a [go.opentelemetry.io/otel/metric.Meter].
//
// Here's how you might initialize a metrics provider.
func Example() {
// Create resource.
res, err := resource.Merge(resource.Default(),
resource.NewWithAttributes(semconv.SchemaURL,
semconv.ServiceName("my-service"),
semconv.ServiceVersion("0.1.0"),
))
if err != nil {
log.Fatalln(err)
}
// This reader is used as a stand-in for a reader that will actually export
// data. See https://pkg.go.dev/go.opentelemetry.io/otel/exporters for
// exporters that can be used as or with readers.
reader := metric.NewManualReader()
// Create a meter provider.
// You can pass this instance directly to your instrumented code if it
// accepts a MeterProvider instance.
meterProvider := metric.NewMeterProvider(
metric.WithResource(res),
metric.WithReader(reader),
)
// Handle shutdown properly so that nothing leaks.
defer func() {
err := meterProvider.Shutdown(context.Background())
if err != nil {
log.Fatalln(err)
}
}()
// Register as global meter provider so that it can be used via otel.Meter
// and accessed using otel.GetMeterProvider.
// Most instrumentation libraries use the global meter provider as default.
// If the global meter provider is not set then a no-op implementation
// is used, which fails to generate data.
otel.SetMeterProvider(meterProvider)
}
func ExampleView() {
// The NewView function provides convenient creation of common Views
// construction. However, it is limited in what it can create.
//
// When NewView is not able to provide the functionally needed, a custom
// View can be constructed directly. Here a custom View is constructed that
// uses Go's regular expression matching to ensure all data stream names
// have a suffix of the units it uses.
re := regexp.MustCompile(`[._](ms|byte)$`)
var view metric.View = func(i metric.Instrument) (metric.Stream, bool) {
// In a custom View function, you need to explicitly copy
// the name, description, and unit.
s := metric.Stream{Name: i.Name, Description: i.Description, Unit: i.Unit}
// Any instrument that does not have a unit suffix defined, but has a
// dimensional unit defined, update the name with a unit suffix.
if re.MatchString(i.Name) {
return s, false
}
switch i.Unit {
case "ms":
s.Name += ".ms"
case "By":
s.Name += ".byte"
default:
return s, false
}
return s, true
}
// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option.
_ = metric.NewMeterProvider(
metric.WithView(view),
)
// Below is an example of how the view will
// function in the SDK for certain instruments.
stream, _ := view(metric.Instrument{
Name: "computation.time.ms",
Unit: "ms",
})
fmt.Println("name:", stream.Name)
stream, _ = view(metric.Instrument{
Name: "heap.size",
Unit: "By",
})
fmt.Println("name:", stream.Name)
// Output:
// name: computation.time.ms
// name: heap.size.byte
}
func ExampleNewView() {
// Create a view that renames the "latency" instrument from the v0.34.0
// version of the "http" instrumentation library as "request.latency".
view := metric.NewView(metric.Instrument{
Name: "latency",
Scope: instrumentation.Scope{
Name: "http",
Version: "0.34.0",
},
}, metric.Stream{Name: "request.latency"})
// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option.
_ = metric.NewMeterProvider(
metric.WithView(view),
)
// Below is an example of how the view will
// function in the SDK for certain instruments.
stream, _ := view(metric.Instrument{
Name: "latency",
Description: "request latency",
Unit: "ms",
Kind: metric.InstrumentKindCounter,
Scope: instrumentation.Scope{
Name: "http",
Version: "0.34.0",
SchemaURL: "https://opentelemetry.io/schemas/1.0.0",
},
})
fmt.Println("name:", stream.Name)
fmt.Println("description:", stream.Description)
fmt.Println("unit:", stream.Unit)
// Output:
// name: request.latency
// description: request latency
// unit: ms
}
func ExampleNewView_wildcard() {
// Create a view that sets unit to milliseconds for any instrument with a
// name suffix of ".ms".
view := metric.NewView(
metric.Instrument{Name: "*.ms"},
metric.Stream{Unit: "ms"},
)
// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option.
_ = metric.NewMeterProvider(
metric.WithView(view),
)
// Below is an example of how the view will
// function in the SDK for certain instruments.
stream, _ := view(metric.Instrument{
Name: "computation.time.ms",
Unit: "1",
})
fmt.Println("name:", stream.Name)
fmt.Println("unit:", stream.Unit)
// Output:
// name: computation.time.ms
// unit: ms
}
func ExampleNewView_drop() {
// Create a view that drops the "latency" instrument from the "http"
// instrumentation library.
view := metric.NewView(
metric.Instrument{
Name: "latency",
Scope: instrumentation.Scope{Name: "http"},
},
metric.Stream{Aggregation: metric.AggregationDrop{}},
)
// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option.
_ = metric.NewMeterProvider(
metric.WithView(view),
)
}
func ExampleNewView_attributeFilter() {
// Create a view that removes the "http.request.method" attribute recorded
// by the "latency" instrument from the "http" instrumentation library.
view := metric.NewView(
metric.Instrument{
Name: "latency",
Scope: instrumentation.Scope{Name: "http"},
},
metric.Stream{AttributeFilter: attribute.NewDenyKeysFilter("http.request.method")},
)
// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option.
_ = metric.NewMeterProvider(
metric.WithView(view),
)
}
func ExampleNewView_exponentialHistogram() {
// Create a view that makes the "latency" instrument from the "http"
// instrumentation library to be reported as an exponential histogram.
view := metric.NewView(
metric.Instrument{
Name: "latency",
Scope: instrumentation.Scope{Name: "http"},
},
metric.Stream{
Aggregation: metric.AggregationBase2ExponentialHistogram{
MaxSize: 160,
MaxScale: 20,
},
},
)
// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option.
_ = metric.NewMeterProvider(
metric.WithView(view),
)
}