Skip to content

Instantly share code, notes, and snippets.

@offlinehacker
Created August 13, 2024 12:19
Show Gist options
  • Save offlinehacker/426aa1c284167505956c4de03d14fe77 to your computer and use it in GitHub Desktop.
Save offlinehacker/426aa1c284167505956c4de03d14fe77 to your computer and use it in GitHub Desktop.
Example of otel golang metrics
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"os"
"sync"
"time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
)
type FileExporter struct {
mu sync.Mutex
shutdown bool
}
func (e *FileExporter) Temporality(k sdkmetric.InstrumentKind) metricdata.Temporality {
return metricdata.CumulativeTemporality
}
func (e *FileExporter) Aggregation(k sdkmetric.InstrumentKind) sdkmetric.Aggregation {
return sdkmetric.DefaultAggregationSelector(k)
}
func (e *FileExporter) Export(ctx context.Context, metrics *metricdata.ResourceMetrics) error {
e.mu.Lock()
defer e.mu.Unlock()
if e.shutdown {
return fmt.Errorf("exporter is shutdown")
}
fileName := fmt.Sprintf("metrics_%s.json", time.Now().Format("20060102_150405"))
file, err := os.Create(fileName)
if err != nil {
return err
}
defer file.Close()
jsonData, err := json.MarshalIndent(metrics, "", " ")
if err != nil {
return err
}
_, err = file.Write(jsonData)
return err
}
func (e *FileExporter) ForceFlush(ctx context.Context) error {
return nil
}
func (e *FileExporter) Shutdown(ctx context.Context) error {
e.mu.Lock()
defer e.mu.Unlock()
e.shutdown = true
return nil
}
func main() {
exporter := &FileExporter{}
reader := sdkmetric.NewPeriodicReader(exporter, sdkmetric.WithInterval(5*time.Second))
provider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))
otel.SetMeterProvider(provider)
meter := otel.Meter("example-meter")
counter, err := meter.Int64Counter(
"example-counter",
metric.WithDescription("An example counter"),
)
if err != nil {
log.Fatal(err)
}
gauge, err := meter.Float64UpDownCounter(
"example-gauge",
metric.WithDescription("An example gauge"),
)
if err != nil {
log.Fatal(err)
}
// Create an observable gauge
observableGauge, err := meter.Float64ObservableGauge(
"example-observable-gauge",
metric.WithDescription("An example observable gauge"),
)
if err != nil {
log.Fatal(err)
}
// Register the callback for the observable gauge
_, err = meter.RegisterCallback(
func(_ context.Context, o metric.Observer) error {
o.ObserveFloat64(observableGauge, float64(time.Now().Second()))
return nil
},
observableGauge,
)
if err != nil {
log.Fatal(err)
}
// Simulate some metrics
go func() {
for i := 0; i < 100; i++ {
counter.Add(context.Background(), 1, metric.WithAttributes(attribute.String("label", "value")))
gauge.Add(context.Background(), float64(i%10-5), metric.WithAttributes(attribute.String("label", "value")))
time.Sleep(1 * time.Second)
}
}()
// Run for a minute
time.Sleep(60 * time.Second)
// Shutdown the provider
if err := provider.Shutdown(context.Background()); err != nil {
log.Printf("Error shutting down provider: %v", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment