in example/metric/exponential_histogram/example.go [39:316]
func main() {
ctx := context.Background()
// Resource for GCP and SDK detectors
res, err := resource.New(ctx,
resource.WithDetectors(gcp.NewDetector()),
resource.WithTelemetrySDK(),
resource.WithAttributes(
semconv.ServiceNameKey.String("example-application"),
),
)
if err != nil {
log.Fatalf("resource.New: %v", err)
}
// Create exporter pipeline
exporter, err := mexporter.New()
if err != nil {
log.Fatalf("Failed to create exporter: %v", err)
}
clabels := []attribute.KeyValue{attribute.Key("key").String("value")}
defaultBuckets := []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 1000}
linearBuckets := make([]float64, 35)
for i := 0; i < 35; i++ {
linearBuckets[i] = float64(i*10 + 10)
}
viewLatencyA := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency",
},
sdkmetric.Stream{
Name: "latency_a",
Aggregation: sdkmetric.AggregationBase2ExponentialHistogram{
MaxSize: 160,
MaxScale: 20,
},
},
)
viewLatencyB := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency",
},
sdkmetric.Stream{
Name: "latency_b",
Aggregation: sdkmetric.AggregationExplicitBucketHistogram{
Boundaries: linearBuckets,
},
},
)
viewLatencyC := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency",
},
sdkmetric.Stream{
Name: "latency_c",
Aggregation: sdkmetric.AggregationExplicitBucketHistogram{
Boundaries: defaultBuckets,
},
},
)
viewLatencyShiftedA := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency_shifted",
},
sdkmetric.Stream{
Name: "latency_shifted_a",
Aggregation: sdkmetric.AggregationBase2ExponentialHistogram{
MaxSize: 160,
MaxScale: 20,
},
},
)
viewLatencyShiftedB := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency_shifted",
},
sdkmetric.Stream{
Name: "latency_shifted_b",
Aggregation: sdkmetric.AggregationExplicitBucketHistogram{
Boundaries: linearBuckets,
},
},
)
viewLatencyShiftedC := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency_shifted",
},
sdkmetric.Stream{
Name: "latency_shifted_c",
Aggregation: sdkmetric.AggregationExplicitBucketHistogram{
Boundaries: defaultBuckets,
},
},
)
viewLatencyMultimodalA := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency_multimodal",
},
sdkmetric.Stream{
Name: "latency_multimodal_a",
Aggregation: sdkmetric.AggregationBase2ExponentialHistogram{
MaxSize: 160,
MaxScale: 20,
},
},
)
viewLatencyMultimodalB := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency_multimodal",
},
sdkmetric.Stream{
Name: "latency_multimodal_b",
Aggregation: sdkmetric.AggregationExplicitBucketHistogram{
Boundaries: linearBuckets,
},
},
)
viewLatencyMultimodalC := sdkmetric.NewView(
sdkmetric.Instrument{
Name: "latency_multimodal",
},
sdkmetric.Stream{
Name: "latency_multimodal_c",
Aggregation: sdkmetric.AggregationExplicitBucketHistogram{
Boundaries: defaultBuckets,
},
},
)
// initialize a MeterProvider with that periodically exports to the GCP exporter.
provider := sdkmetric.NewMeterProvider(
sdkmetric.WithView(
viewLatencyA,
viewLatencyB,
viewLatencyC,
viewLatencyShiftedA,
viewLatencyShiftedB,
viewLatencyShiftedC,
viewLatencyMultimodalA,
viewLatencyMultimodalB,
viewLatencyMultimodalC,
),
sdkmetric.WithReader(
sdkmetric.NewPeriodicReader(
exporter,
sdkmetric.WithInterval(10*time.Second),
),
),
sdkmetric.WithResource(res),
)
defer func() {
if err = provider.Shutdown(ctx); err != nil {
log.Fatalf("failed to shutdown meter provider: %v", err)
}
}()
// Create a meter with which we will record metrics for our package.
meter := provider.Meter("github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/metric")
_, err = meter.Float64ObservableGauge(
"latency",
metric.WithDescription(
"Latency",
),
metric.WithUnit("s"),
metric.WithFloat64Callback(func(_ context.Context, o metric.Float64Observer) error {
points := 1000
// Create a log normal distribution to simulate latency
// from server response.
dist := distuv.LogNormal{
Mu: 3.5,
Sigma: .5,
}
data := make([]float64, points)
// Draw some random values from the log normal distribution
for i := range data {
data[i] = dist.Rand()
// Gauge metric observation
o.Observe(data[i], metric.WithAttributes(clabels...))
}
mean, std := stat.MeanStdDev(data, nil)
log.Printf("Sent Latency Data (Original Distribution): #points %d , mean %v, sdv %v", points, mean, std)
return nil
}),
)
_, err = meter.Float64ObservableGauge(
"latency_shifted",
metric.WithDescription(
"Latency Shifted",
),
metric.WithUnit("s"),
metric.WithFloat64Callback(func(_ context.Context, o metric.Float64Observer) error {
points := 1000
// Create a log normal distribution to simulate latency
// from server response.
dist := distuv.LogNormal{
Mu: 5.5,
Sigma: .5,
}
data := make([]float64, points)
// Draw some random values from the log normal distribution
for i := range data {
data[i] = dist.Rand()
// Gauge metric observation
o.Observe(data[i], metric.WithAttributes(clabels...))
}
mean, std := stat.MeanStdDev(data, nil)
log.Printf("Sent Latency Data (Shifted Distribution): #points %d , mean %v, sdv %v", points, mean, std)
return nil
}),
)
_, err = meter.Float64ObservableGauge(
"latency_multimodal",
metric.WithDescription(
"Latency Multimodal",
),
metric.WithUnit("s"),
metric.WithFloat64Callback(func(_ context.Context, o metric.Float64Observer) error {
points := 1000
// Create a multimodal normal
dist1 := distuv.LogNormal{
Mu: 3.5,
Sigma: .5,
}
dist2 := distuv.LogNormal{
Mu: 5.5,
Sigma: .5,
}
data := make([]float64, points)
// Draw some random values from the log normal distribution
for i := range data {
if rand.Float64() < .5 {
data[i] = dist1.Rand()
} else {
data[i] = dist2.Rand()
}
// Gauge metric observation
o.Observe(data[i], metric.WithAttributes(clabels...))
}
mean, std := stat.MeanStdDev(data, nil)
log.Printf("Sent Latency Data (Multimodal Distribution): #points %d , mean %v, sdv %v", points, mean, std)
return nil
}),
)
if err != nil {
log.Fatalf("Failed to create gauge: %v", err)
}
// Wait for interrupt
var stopChan = make(chan os.Signal, 2)
signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
<-stopChan
}