Skip to content

Commit

Permalink
Add OTLP benchmarking with copied telemetrygen files (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
carsonip authored Mar 26, 2024
1 parent 0497fdf commit a8d35be
Show file tree
Hide file tree
Showing 37 changed files with 2,967 additions and 89 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ MODULE_DEPS=$(sort $(shell go list -deps -tags=darwin,linux,windows -f "{{with .
all: test

fmt: tools/go.mod
@go run -modfile=tools/go.mod github.com/elastic/go-licenser -license=Elasticv2 .
@go run -modfile=tools/go.mod github.com/elastic/go-licenser -license=Elasticv2 -exclude internal/telemetrygen .
@go run -modfile=tools/go.mod golang.org/x/tools/cmd/goimports -local github.com/elastic/ -w .

lint: tools/go.mod
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ Note that the managed service will use API key based auth and one soaktest can t
```sh
./apmsoak run --scenario=fairness --api-keys="project_1:key-to-project_1,project_2:key-to-project_2"
```

## internal/telemetrygen

This package is from https://github.com/open-telemetry/opentelemetry-collector-contrib but slightly modified so that it can be used within apm-perf.
82 changes: 2 additions & 80 deletions cmd/apmbench/bench.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,20 @@ package main

import (
"context"
"crypto/tls"
"fmt"
"net/url"
"strings"
"testing"
"time"

"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.elastic.co/apm/v2"
"go.elastic.co/apm/v2/transport"
"go.uber.org/zap"
"golang.org/x/time/rate"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"

"github.com/elastic/apm-perf/internal/loadgen"
loadgencfg "github.com/elastic/apm-perf/internal/loadgen/config"
"github.com/elastic/apm-perf/internal/loadgen/eventhandler"

"go.elastic.co/apm/v2"
"go.elastic.co/apm/v2/transport"
)

func Benchmark1000Transactions(b *testing.B, l *rate.Limiter) {
Expand All @@ -50,27 +43,6 @@ func Benchmark1000Transactions(b *testing.B, l *rate.Limiter) {
})
}

func BenchmarkOTLPTraces(b *testing.B, l *rate.Limiter) {
b.RunParallel(func(pb *testing.PB) {
exporter := newOTLPExporter(b)
tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.AlwaysSample()),
sdktrace.WithBatcher(exporter, sdktrace.WithBlocking()),
)
tracer := tracerProvider.Tracer("tracer")
for pb.Next() {
if err := l.Wait(context.Background()); err != nil {
// panicing ensures that the error is reported
// see: https://github.com/golang/go/issues/32066
panic(err)
}
_, span := tracer.Start(context.Background(), "name")
span.End()
}
tracerProvider.ForceFlush(context.Background())
})
}

func BenchmarkAgentAll(b *testing.B, l *rate.Limiter) {
benchmarkAgent(b, l, `apm-*.ndjson`)
}
Expand Down Expand Up @@ -147,56 +119,6 @@ func newTracer(tb testing.TB) *apm.Tracer {
return tracer
}

func newOTLPExporter(tb testing.TB) *otlptrace.Exporter {
serverURL := loadgencfg.Config.ServerURL
secretToken := loadgencfg.Config.SecretToken
apiKey := loadgencfg.Config.APIKey
endpoint := serverURL.Host
if serverURL.Port() == "" {
switch serverURL.Scheme {
case "http":
endpoint += ":80"
case "https":
endpoint += ":443"
}
}

headers := make(map[string]string)
for k, v := range loadgencfg.Config.Headers {
headers[k] = v
}
if secretToken != "" || apiKey != "" {
if apiKey != "" {
// higher priority to APIKey auth
headers["Authorization"] = "ApiKey " + apiKey
} else {
headers["Authorization"] = "Bearer " + secretToken
}
}

opts := []otlptracegrpc.Option{
otlptracegrpc.WithEndpoint(endpoint),
otlptracegrpc.WithDialOption(grpc.WithBlock()),
otlptracegrpc.WithHeaders(headers),
}
if serverURL.Scheme == "http" {
opts = append(opts, otlptracegrpc.WithInsecure())
} else {
tlsCredentials := credentials.NewTLS(&tls.Config{
InsecureSkipVerify: true,
})
opts = append(opts, otlptracegrpc.WithTLSCredentials(tlsCredentials))
}
exporter, err := otlptracegrpc.New(context.Background(), opts...)
if err != nil {
// panicing ensures that the error is reported
// see: https://github.com/golang/go/issues/32066
panic(err)
}
tb.Cleanup(func() { exporter.Shutdown(context.Background()) })
return exporter
}

func newEventHandler(tb testing.TB, p string, l *rate.Limiter) *eventhandler.Handler {
protocol := "apm/http"
if strings.HasPrefix(p, "otlp-") {
Expand Down
108 changes: 108 additions & 0 deletions cmd/apmbench/bench_otlp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.

package main

import (
"runtime"
"testing"
"time"

"go.uber.org/zap"
"golang.org/x/time/rate"

loadgencfg "github.com/elastic/apm-perf/internal/loadgen/config"
"github.com/elastic/apm-perf/internal/telemetrygen/common"
"github.com/elastic/apm-perf/internal/telemetrygen/logs"
"github.com/elastic/apm-perf/internal/telemetrygen/metrics"
"github.com/elastic/apm-perf/internal/telemetrygen/traces"
)

func commonConfigWithHTTPPath(httpPath string) common.Config {
insecure := !loadgencfg.Config.Secure

serverURL := loadgencfg.Config.ServerURL
endpoint := serverURL.Host
if serverURL.Port() == "" {
switch serverURL.Scheme {
case "http":
endpoint += ":80"
insecure = true
case "https":
endpoint += ":443"
}
}

secretToken := loadgencfg.Config.SecretToken
apiKey := loadgencfg.Config.APIKey
headers := make(map[string]string)
for k, v := range loadgencfg.Config.Headers {
headers[k] = v
}
if secretToken != "" || apiKey != "" {
if apiKey != "" {
// higher priority to APIKey auth
headers["Authorization"] = "ApiKey " + apiKey
} else {
headers["Authorization"] = "Bearer " + secretToken
}
}

return common.Config{
WorkerCount: runtime.GOMAXPROCS(0),
Rate: 0,
TotalDuration: 0,
ReportingInterval: 0,
SkipSettingGRPCLogger: true,
CustomEndpoint: endpoint,
Insecure: insecure,
UseHTTP: false,
HTTPPath: httpPath,
Headers: headers,
ResourceAttributes: nil,
TelemetryAttributes: nil,
CaFile: "",
ClientAuth: common.ClientAuth{},
Logger: zap.NewNop(),
}
}

func BenchmarkOTLPLogs(b *testing.B, l *rate.Limiter) {
config := logs.Config{
Config: commonConfigWithHTTPPath("/v1/logs"),
NumLogs: b.N,
Body: "test",
}
if err := logs.Start(&config); err != nil {
b.Fatal(err)
}
}

func BenchmarkOTLPTraces(b *testing.B, l *rate.Limiter) {
config := traces.Config{
Config: commonConfigWithHTTPPath("/v1/traces"),
NumTraces: b.N,
NumChildSpans: 1,
PropagateContext: false,
ServiceName: "foo",
StatusCode: "0",
Batch: true,
LoadSize: 0,
SpanDuration: 123 * time.Microsecond,
}
if err := traces.Start(&config); err != nil {
b.Fatal(err)
}
}

func BenchmarkOTLPMetrics(b *testing.B, l *rate.Limiter) {
config := metrics.Config{
Config: commonConfigWithHTTPPath("/v1/metrics"),
NumMetrics: b.N,
MetricType: "Sum",
}
if err := metrics.Start(&config); err != nil {
b.Fatal(err)
}
}
4 changes: 3 additions & 1 deletion cmd/apmbench/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ func main() {
extraMetrics,
resetStoreFunc,
Benchmark1000Transactions,
BenchmarkOTLPTraces,
BenchmarkAgentAll,
BenchmarkAgentGo,
BenchmarkAgentNodeJS,
BenchmarkAgentPython,
BenchmarkAgentRuby,
Benchmark10000AggregationGroups,
BenchmarkOTLPTraces,
BenchmarkOTLPLogs,
BenchmarkOTLPMetrics,
); err != nil {
logger.Fatal("failed to run benchmarks", zap.Error(err))
}
Expand Down
18 changes: 15 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/elastic/apm-perf
go 1.21

require (
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/klauspost/compress v1.17.7
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
Expand All @@ -12,9 +13,18 @@ require (
go.elastic.co/apm/v2 v2.5.0
go.elastic.co/ecszap v1.0.2
go.elastic.co/fastjson v1.3.0
go.opentelemetry.io/collector/pdata v1.4.0
go.opentelemetry.io/collector/semconv v0.97.0
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.24.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.24.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0
go.opentelemetry.io/otel/sdk v1.24.0
go.opentelemetry.io/otel/sdk/metric v1.24.0
go.opentelemetry.io/otel/trace v1.24.0
go.uber.org/goleak v1.3.0
go.uber.org/zap v1.27.0
golang.org/x/sync v0.6.0
golang.org/x/time v0.5.0
Expand All @@ -30,18 +40,20 @@ require (
github.com/elastic/go-windows v1.0.1 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.20.0 // indirect
Expand All @@ -50,6 +62,6 @@ require (
golang.org/x/tools v0.14.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/protobuf v1.32.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
howett.net/plist v1.0.0 // indirect
)
Loading

0 comments on commit a8d35be

Please sign in to comment.