Skip to content

Commit

Permalink
Remove special validation error handling (#250)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmacd committed Dec 9, 2022
1 parent 233832f commit 8d6b79e
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 101 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## Unreleased

- Update to OTel-Go 1.11.x and OTel-Go metrics 0.34.
[#333](https://github.com/lightstep/otel-launcher-go/pull/333)
- Remove Lightstep-specific partial-success error handling, now using upstream.
[#250](https://github.com/lightstep/otel-launcher-go/pull/250)

## [1.11.1](https://github.com/lightstep/otel-launcher-go/releases/tag/v1.11.0) - 2022-10-05

### Bug fixes
Expand Down
20 changes: 0 additions & 20 deletions README.md
Expand Up @@ -195,26 +195,6 @@ Lightstep users are recommended to select either the "cumulative" or
"stateless" preference. The OpenTelemetry-specified "delta"
temporality preference is not recommended for Lightstep users.

### Metrics validation errors

Lightstep performs a number of validation steps over metrics data
before accepting it. When an OTLP Metrics export request is
successful but data is completely or partially rejected for any
reason, the outcome is detailed using Lightstep-specific response
headers.

These headers predate [work in OpenTelemetry on returning partial
success](https://github.com/open-telemetry/opentelemetry-proto/pull/390).
Lightstep expects to use standard OTLP fields to convey these
partially-successful outcomes in the future.

Validation errors are generally repetitive. Lightstep limits the size
of each partial-success response to lower the overhead associated with
these responses using random selection.

The launcher contains special code to interpret these headers and
direct them to the standard OpenTelemetry-Go error handler.

------

*Made with*
Expand Down
82 changes: 1 addition & 81 deletions pipelines/metrics.go
Expand Up @@ -16,9 +16,7 @@ package pipelines

import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"

Expand All @@ -39,6 +37,7 @@ import (
contribHost "go.opentelemetry.io/contrib/instrumentation/host"
contribRuntime "go.opentelemetry.io/contrib/instrumentation/runtime"

// OTel APIs
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/metric"
metricglobal "go.opentelemetry.io/otel/metric/global"
Expand All @@ -47,9 +46,7 @@ import (
otelotlpmetricgrpc "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
otelsdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
"google.golang.org/grpc"
"google.golang.org/grpc/encoding/gzip"
"google.golang.org/grpc/metadata"
)

func prestableHostMetrics(provider metric.MeterProvider) error {
Expand Down Expand Up @@ -193,87 +190,13 @@ func NewMetricsPipeline(c PipelineConfig) (func() error, error) {
return shutdown, nil
}

var errNoSingleCount = fmt.Errorf("no count")

func singleCount(values []string) (int, error) {
if len(values) != 1 {
return 0, errNoSingleCount
}
return strconv.Atoi(values[0])
}

type dropExample struct {
Reason string `json:"reason"`
Names []string `json:"names"`
}

type dropSummary struct {
Dropped struct {
Points int `json:"points,omitempty"`
Metrics int `json:"metrics,omitempty"`
} `json:"dropped,omitempty"`
Examples []dropExample `json:"examples,omitempty"`
}

func (ds *dropSummary) Empty() bool {
return len(ds.Examples) == 0 && ds.Dropped.Points == 0 && ds.Dropped.Metrics == 0
}

func interceptor(
ctx context.Context,
method string,
req, reply interface{},
cc *grpc.ClientConn,
invoker grpc.UnaryInvoker,
opts ...grpc.CallOption,
) error {
const invalidTrailerPrefix = "otlp-invalid-"

var md metadata.MD
err := invoker(ctx, method, req, reply, cc, append(opts, grpc.Trailer(&md))...)
if err == nil && md != nil {
var ds dropSummary
for key, values := range md {
key = strings.ToLower(key)
if !strings.HasPrefix(key, "otlp-") {
continue
}

if key == "otlp-points-dropped" {
if points, err := singleCount(values); err == nil {
ds.Dropped.Points = points
}
} else if key == "otlp-metrics-dropped" {
if metrics, err := singleCount(values); err == nil {
ds.Dropped.Metrics = metrics
}
} else if strings.HasPrefix(key, invalidTrailerPrefix) {
key = key[len(invalidTrailerPrefix):]
key = strings.ReplaceAll(key, "-", " ")
ds.Examples = append(ds.Examples, dropExample{
Reason: key,
Names: values,
})
}
}
if !ds.Empty() {
data, _ := json.Marshal(ds)
otel.Handle(fmt.Errorf("metrics partial failure: %v", string(data)))
}
}
return err
}

func (c PipelineConfig) newClient(secure otlpmetricgrpc.Option) (otlpmetric.Client, error) {
return otlpmetricgrpc.NewClient(
context.Background(),
secure,
otlpmetricgrpc.WithEndpoint(c.Endpoint),
otlpmetricgrpc.WithHeaders(c.Headers),
otlpmetricgrpc.WithCompressor(gzip.Name),
otlpmetricgrpc.WithDialOption(
grpc.WithUnaryInterceptor(interceptor),
),
)
}

Expand All @@ -293,9 +216,6 @@ func (c PipelineConfig) newOtelMetricsExporter(temporality otelsdkmetric.Tempora
otelotlpmetricgrpc.WithEndpoint(c.Endpoint),
otelotlpmetricgrpc.WithHeaders(c.Headers),
otelotlpmetricgrpc.WithCompressor(gzip.Name),
otelotlpmetricgrpc.WithDialOption(
grpc.WithUnaryInterceptor(interceptor),
),
)
}

Expand Down

0 comments on commit 8d6b79e

Please sign in to comment.