Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
250de6b
exporter/metric: Add support to export Distribution with Exemplars.
franciscovalentecastro Dec 11, 2023
fef5b26
example/metric: Add expoential histogram example.
franciscovalentecastro Dec 11, 2023
0cda63a
Update example.go.
franciscovalentecastro Dec 12, 2023
168b5a8
exporter/metric: Transform ExponentialHistogram to Distribution.
franciscovalentecastro Dec 12, 2023
29786bb
example: Update date.
franciscovalentecastro Dec 12, 2023
0a7ce9f
example: Use views for histogram.
franciscovalentecastro Dec 14, 2023
bb3c563
Fixed ExponentialHist to Distribution translation.
franciscovalentecastro Dec 15, 2023
3a14acb
Add more distribution metric views to example.go.
franciscovalentecastro Feb 23, 2024
e56a3b8
Fix typo.
franciscovalentecastro Feb 23, 2024
20d8ec7
Remove local dev artifacts.
franciscovalentecastro Feb 23, 2024
13c65c3
Tidy go.mod.
franciscovalentecastro Feb 23, 2024
aa41056
Update dependencies.
franciscovalentecastro Feb 23, 2024
a4b0389
Further update dependencies.
franciscovalentecastro Feb 23, 2024
76347ce
Go mod tidy.
franciscovalentecastro Feb 23, 2024
3ca23f0
Removed debuggin and unused code.
franciscovalentecastro Feb 23, 2024
f396d98
Fix example parameters and logs.
franciscovalentecastro Feb 23, 2024
83a6e6f
Use `positiveBucketCounts` for mean calculation.
franciscovalentecastro Feb 23, 2024
079b8bd
Fix linter errors.
franciscovalentecastro Feb 26, 2024
760fafa
Use `s` units instead of `ms`.
franciscovalentecastro Feb 29, 2024
ac6ebe5
Use `collector/metric.go` implementation of `exponentialHistogramPoin…
franciscovalentecastro Feb 29, 2024
047c379
Write to `workload.googleapis.com` instead of `custom.googleapis.com`
franciscovalentecastro Feb 29, 2024
f7dd87d
Add `dashboard.json` to visualize `example.go`
franciscovalentecastro Feb 29, 2024
3579361
Fix `expHistToDistribution`
franciscovalentecastro Feb 29, 2024
c4e9fd4
Use correct type `ExponentialHistogramDataPoint`.
franciscovalentecastro Feb 29, 2024
3274232
Fix usage of `math.IsNan`
franciscovalentecastro Feb 29, 2024
8eb2406
Add `TODO` for missing `[]attachments` to exemplars exporting.
franciscovalentecastro Mar 1, 2024
2d54159
Set copyright year to `2024`
franciscovalentecastro Mar 1, 2024
9a732fd
Update example/metric/exponential_histogram/example.go
franciscovalentecastro Mar 4, 2024
604f5b0
Add support for `int64` ExponentialHistogram.
franciscovalentecastro Mar 4, 2024
0bd8a8d
Pass all views once to `WithView`.
franciscovalentecastro Mar 4, 2024
1590aff
Remove `workloadMetricsPrefixFormatter`.
franciscovalentecastro Mar 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
322 changes: 322 additions & 0 deletions example/metric/exponential_histogram/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"context"
"fmt"
"log"
"math/rand"
"os"
"os/signal"
"syscall"
"time"

"gonum.org/v1/gonum/stat"
"gonum.org/v1/gonum/stat/distuv"

mexporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric"

"go.opentelemetry.io/contrib/detectors/gcp"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
)

func workloadMetricsPrefixFormatter(d metricdata.Metrics) string {
return fmt.Sprintf("custom.googleapis.com/%s", d.Name)
Comment thread
dashpole marked this conversation as resolved.
Outdated
}

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(
mexporter.WithMetricDescriptorTypeFormatter(workloadMetricsPrefixFormatter),
)
Comment thread
franciscovalentecastro marked this conversation as resolved.
Outdated
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),
Comment thread
dashpole marked this conversation as resolved.
Outdated
sdkmetric.WithView(viewLatencyB),
sdkmetric.WithView(viewLatencyC),
sdkmetric.WithView(viewLatencyShiftedA),
sdkmetric.WithView(viewLatencyShiftedB),
sdkmetric.WithView(viewLatencyShiftedC),
sdkmetric.WithView(viewLatencyMultimodalA),
sdkmetric.WithView(viewLatencyMultimodalB),
sdkmetric.WithView(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("ms"),
Comment thread
dashpole marked this conversation as resolved.
Outdated
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("ms"),
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("ms"),
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
}
47 changes: 47 additions & 0 deletions example/metric/exponential_histogram/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module github.com/GoogleCloudPlatform/opentelemetry-operations-go/example/metric/sdk

go 1.20

require (
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.45.0
go.opentelemetry.io/contrib/detectors/gcp v1.24.0
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/metric v1.24.0
go.opentelemetry.io/otel/sdk v1.24.0
go.opentelemetry.io/otel/sdk/metric v1.24.0
gonum.org/v1/gonum v0.14.0
)

require (
cloud.google.com/go/compute v1.23.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/monitoring v1.15.1 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.21.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.45.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.10.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/api v0.126.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230731193218-e0aa005b6bdf // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.58.3 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)

replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric => ../../../exporter/metric
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this to pick current changes (before merging) to metric.go.

Loading