Skip to content

Commit 5dd35ce

Browse files
yumosxMrAlias
andauthored
feat: logs SDK observability - otlploggrpc exporter metrics (#7353)
This PR adds support for experimental metrics in `otlploggrpc` - `otel.sdk.exporter.log.inflight` - `otel.sdk.exporter.log.exported` - `otel.sdk.exporter.operation.duration` References: - #7084 - #7019 - [Follow guidelines](https://github.com/open-telemetry/opentelemetry-go/blob/a5dcd68ebb2f3669f7685ac7b0f3f1624251a381/CONTRIBUTING.md#encapsulation). ----- ```txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc cpu: Apple M3 │ disabled.txt │ enabled.txt │ │ sec/op │ sec/op vs base │ ExporterExportLogs/Observability-8 681.5µ ± 3% 684.3µ ± 6% ~ (p=0.315 n=10) │ disabled.txt │ enabled.txt │ │ B/op │ B/op vs base │ ExporterExportLogs/Observability-8 672.8Ki ± 0% 673.6Ki ± 1% ~ (p=0.247 n=10) │ disabled.txt │ enabled.txt │ │ allocs/op │ allocs/op vs base │ ExporterExportLogs/Observability-8 9.224k ± 0% 9.232k ± 0% +0.09% (p=0.000 n=10) ``` ----- ```txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/observ cpu: Apple M3 │ bench.txt │ │ sec/op │ InstrumentationExportLogs/NoError-8 162.6n ± 3% InstrumentationExportLogs/PartialError-8 705.5n ± 5% InstrumentationExportLogs/FullError-8 592.1n ± 1% geomean 408.0n │ bench.txt │ │ B/op │ InstrumentationExportLogs/NoError-8 152.0 ± 0% InstrumentationExportLogs/PartialError-8 697.0 ± 0% InstrumentationExportLogs/FullError-8 616.0 ± 0% geomean 402.6 │ bench.txt │ │ allocs/op │ InstrumentationExportLogs/NoError-8 3.000 ± 0% InstrumentationExportLogs/PartialError-8 10.00 ± 0% InstrumentationExportLogs/FullError-8 8.000 ± 0% geomean 6.214 ``` ----- ```txt pkg: go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/observ cpu: Apple M3 │ parse_target.txt │ │ sec/op │ ParseTarget/HostName-8 38.00n ± ∞ ¹ ParseTarget/HostPort-8 51.33n ± ∞ ¹ ParseTarget/IPv4WithoutPort-8 44.74n ± ∞ ¹ ParseTarget/IPv4WithPort-8 62.56n ± ∞ ¹ ParseTarget/IPv6Bare-8 94.89n ± ∞ ¹ ParseTarget/IPv6Bracket-8 93.78n ± ∞ ¹ ParseTarget/IPv6WithPort-8 57.57n ± ∞ ¹ ParseTarget/UnixSocket-8 8.329n ± ∞ ¹ ParseTarget/UnixAbstractSocket-8 9.082n ± ∞ ¹ ParseTarget/Passthrough-8 58.06n ± ∞ ¹ geomean 40.64n ¹ need >= 6 samples for confidence interval at level 0.95 │ parse_target.txt │ │ B/op │ ParseTarget/HostName-8 48.00 ± ∞ ¹ ParseTarget/HostPort-8 48.00 ± ∞ ¹ ParseTarget/IPv4WithoutPort-8 16.00 ± ∞ ¹ ParseTarget/IPv4WithPort-8 48.00 ± ∞ ¹ ParseTarget/IPv6Bare-8 16.00 ± ∞ ¹ ParseTarget/IPv6Bracket-8 16.00 ± ∞ ¹ ParseTarget/IPv6WithPort-8 48.00 ± ∞ ¹ ParseTarget/UnixSocket-8 0.000 ± ∞ ¹ ParseTarget/UnixAbstractSocket-8 0.000 ± ∞ ¹ ParseTarget/Passthrough-8 48.00 ± ∞ ¹ geomean ² ¹ need >= 6 samples for confidence interval at level 0.95 ² summaries must be >0 to compute geomean │ parse_target.txt │ │ allocs/op │ ParseTarget/HostName-8 1.000 ± ∞ ¹ ParseTarget/HostPort-8 1.000 ± ∞ ¹ ParseTarget/IPv4WithoutPort-8 1.000 ± ∞ ¹ ParseTarget/IPv4WithPort-8 1.000 ± ∞ ¹ ParseTarget/IPv6Bare-8 1.000 ± ∞ ¹ ParseTarget/IPv6Bracket-8 1.000 ± ∞ ¹ ParseTarget/IPv6WithPort-8 1.000 ± ∞ ¹ ParseTarget/UnixSocket-8 0.000 ± ∞ ¹ ParseTarget/UnixAbstractSocket-8 0.000 ± ∞ ¹ ParseTarget/Passthrough-8 1.000 ± ∞ ¹ geomean ² ¹ need >= 6 samples for confidence interval at level 0.95 ² summaries must be >0 to compute geomean ``` --------- Co-authored-by: Tyler Yahn <[email protected]>
1 parent 4b9e111 commit 5dd35ce

File tree

19 files changed

+1986
-23
lines changed

19 files changed

+1986
-23
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1616
- Greatly reduce the cost of recording metrics in `go.opentelemetry.io/otel/sdk/metric` using hashing for map keys. (#7175)
1717
- Add experimental observability for the prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus`.
1818
Check the `go.opentelemetry.io/otel/exporters/prometheus/internal/x` package documentation for more information. (#7345)
19+
- Add experimental observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#7353)
1920

2021
### Fixed
2122

exporters/otlp/otlplog/otlploggrpc/client.go

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package otlploggrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlplog/o
66
import (
77
"context"
88
"errors"
9-
"fmt"
9+
"sync/atomic"
1010
"time"
1111

1212
collogpb "go.opentelemetry.io/proto/otlp/collector/logs/v1"
@@ -21,6 +21,8 @@ import (
2121
"google.golang.org/grpc/metadata"
2222
"google.golang.org/grpc/status"
2323

24+
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal"
25+
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/observ"
2426
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/retry"
2527
)
2628

@@ -37,6 +39,8 @@ type client struct {
3739
ourConn bool
3840
conn *grpc.ClientConn
3941
lsc collogpb.LogsServiceClient
42+
43+
instrumentation *observ.Instrumentation
4044
}
4145

4246
// Used for testing.
@@ -71,7 +75,18 @@ func newClient(cfg config) (*client, error) {
7175

7276
c.lsc = collogpb.NewLogsServiceClient(c.conn)
7377

74-
return c, nil
78+
var err error
79+
id := nextExporterID()
80+
c.instrumentation, err = observ.NewInstrumentation(id, c.conn.CanonicalTarget())
81+
return c, err
82+
}
83+
84+
var exporterN atomic.Int64
85+
86+
// nextExporterID returns the next unique ID for an exporter.
87+
func nextExporterID() int64 {
88+
const inc = 1
89+
return exporterN.Add(inc) - inc
7590
}
7691

7792
func newGRPCDialOptions(cfg config) []grpc.DialOption {
@@ -131,6 +146,14 @@ func (c *client) UploadLogs(ctx context.Context, rl []*logpb.ResourceLogs) (uplo
131146
ctx, cancel := c.exportContext(ctx)
132147
defer cancel()
133148

149+
count := int64(len(rl))
150+
if c.instrumentation != nil {
151+
eo := c.instrumentation.ExportLogs(ctx, count)
152+
defer func() {
153+
eo.End(uploadErr)
154+
}()
155+
}
156+
134157
return errors.Join(uploadErr, c.requestFunc(ctx, func(ctx context.Context) error {
135158
resp, err := c.lsc.Export(ctx, &collogpb.ExportLogsServiceRequest{
136159
ResourceLogs: rl,
@@ -139,7 +162,7 @@ func (c *client) UploadLogs(ctx context.Context, rl []*logpb.ResourceLogs) (uplo
139162
msg := resp.PartialSuccess.GetErrorMessage()
140163
n := resp.PartialSuccess.GetRejectedLogRecords()
141164
if n != 0 || msg != "" {
142-
err := errPartial{msg: msg, n: n}
165+
err := internal.LogPartialSuccessError(n, msg)
143166
uploadErr = errors.Join(uploadErr, err)
144167
}
145168
}
@@ -152,23 +175,6 @@ func (c *client) UploadLogs(ctx context.Context, rl []*logpb.ResourceLogs) (uplo
152175
}))
153176
}
154177

155-
type errPartial struct {
156-
msg string
157-
n int64
158-
}
159-
160-
var _ error = errPartial{}
161-
162-
func (e errPartial) Error() string {
163-
const form = "OTLP partial success: %s (%d log records rejected)"
164-
return fmt.Sprintf(form, e.msg, e.n)
165-
}
166-
167-
func (errPartial) Is(target error) bool {
168-
_, ok := target.(errPartial)
169-
return ok
170-
}
171-
172178
// Shutdown shuts down the client, freeing all resources.
173179
//
174180
// Any active connections to a remote endpoint are closed if they were created

0 commit comments

Comments
 (0)