Replies: 3 comments 1 reply
|
The global meter provider is not specific to one package. It is shared among the entire runtime of your application. If metrics are not exported properly, there must be another issue within your application. Are you able to setup a small reproduction example? |
|
Hi and Thanks @dmathieu! Follow an example showing. Here is a main package trying to acquire and use a meter. Otel is initializated in the package main
import (
"context"
"localtest/other"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
otm "go.opentelemetry.io/otel/metric"
)
func main() {
other.Test()
mainMeter := otel.GetMeterProvider().Meter("localtest/other/myTestMeter")
mainCounter, _ := mainMeter.Int64Counter(
"temporary.call",
otm.WithUnit("{call}"),
otm.WithDescription("car counter"),
)
mainCounter.Add(context.Background(), 1, otm.WithAttributes(
attribute.String("model", "Camaro"),
attribute.Bool("IsCar", true),
))
}package other
import (
"context"
"log"
"time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
otm "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
)
func Test() {
res, err := newResource()
if err != nil {
panic(err)
}
meterProvider, err := newMeterProvider(res)
if err != nil {
panic(err)
}
defer func() {
if err := meterProvider.Shutdown(context.Background()); err != nil {
log.Println(err)
}
}()
otel.SetMeterProvider(meterProvider)
Meter := otel.Meter("myTestMeter")
otherCounter, err := Meter.Int64Counter(
"temporary.call",
otm.WithUnit("{call}"),
otm.WithDescription("car counter"),
)
otherCounter.Add(context.Background(), 1, otm.WithAttributes(
attribute.String("model", "Monza"),
attribute.Bool("IsCar", true),
))
}
func newResource() (*resource.Resource, error) {
return resource.Merge(resource.Default(),
resource.NewWithAttributes(semconv.SchemaURL,
semconv.ServiceName("my-service"),
semconv.ServiceVersion("0.1.0"),
))
}
func newMeterProvider(res *resource.Resource) (*metric.MeterProvider, error) {
metricExporter, err := stdoutmetric.New()
if err != nil {
return nil, err
}
meterProvider := metric.NewMeterProvider(
metric.WithResource(res),
metric.WithReader(metric.NewPeriodicReader(metricExporter,
// Default is 1m. Set to 3s for demonstrative purposes.
metric.WithInterval(3*time.Second))),
)
return meterProvider, nil
}Here the output that show only the counter generated in the same package where otel is initializated: |
|
Hey @dmathieu i was able to reproduce this example and everything worked well! |
Uh oh!
There was an error while loading. Please reload this page.
Hi all!
searching for some help here! Sorry if this is not the best channel for this :)
According to docs, a meterProvider is essential to build instruments, and that's clear to me. Right after the initializing example of metric initialization, we have the topic aquiring a meter with this object.
Following this implementation in my tests i was note able to properly use
meterProvideroutside of the package where it's implemented (a package created to hold otel build and initialization code): I can acquire a meter withvar meter = otel.Meter("example.io/package/name")(for example in apackage main), build an instrument and call.Addmethod. But this metric were not been sent to my exporter (stdout)My goal is to keep build and initialization codes in their own package of the application, so that i cann call this and acquire a
meterin mypackage main. I guess that's a common situationIs there a way to receive in a package a
meterbuilded in another package or something in this line? Is this a nice practice? The doc brings that usually aMeterProvideris builded once and lives the time the app lives too. this has to be builded in the same package allways?All reactions