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? |
Beta Was this translation helpful? Give feedback.
-
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:
|
Beta Was this translation helpful? Give feedback.
-
Hey @dmathieu i was able to reproduce this example and everything worked well! |
Beta Was this translation helpful? Give feedback.
-
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
meterProvider
outside 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.Add
method. 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
meter
in mypackage main
. I guess that's a common situationIs there a way to receive in a package a
meter
builded in another package or something in this line? Is this a nice practice? The doc brings that usually aMeterProvider
is builded once and lives the time the app lives too. this has to be builded in the same package allways?Beta Was this translation helpful? Give feedback.
All reactions