From 69d9a9343a7fb72d43287eaba212494fef09876a Mon Sep 17 00:00:00 2001 From: yakumioto Date: Thu, 5 Dec 2024 19:04:58 +0800 Subject: [PATCH] feat: add benchmarks and use stdout tracer in examples Signed-off-by: yakumioto --- README.md | 15 ++++++ README_zhCN.md | 15 ++++++ benchmark_test.go | 129 ++++++++++++++++++++++++++++++++++++++++++++++ example_test.go | 31 ++++++++--- go.mod | 15 ++---- go.sum | 32 +++--------- 6 files changed, 194 insertions(+), 43 deletions(-) create mode 100644 benchmark_test.go diff --git a/README.md b/README.md index 5b0b8bd..ac641e8 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,21 @@ func initTracer(ctx context.Context) (func(), error) { } ``` +## Benchmark + +``` +goos: darwin +goarch: amd64 +pkg: github.com/yakumioto/otelslog +cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz +BenchmarkTextSlog-12 255117 4781 ns/op 4260 B/op 7 allocs/op +BenchmarkJSONSlog-12 346534 3367 ns/op 4157 B/op 7 allocs/op +BenchmarkJSONOtelSlogWithAttr-12 238906 5670 ns/op 5489 B/op 20 allocs/op +BenchmarkTextOtelSlogWithAttr-12 245080 4871 ns/op 5342 B/op 20 allocs/op +BenchmarkJSONOtelSlogWithContext-12 275746 4189 ns/op 5021 B/op 18 allocs/op +BenchmarkTextOtelSlogWithContext-12 271627 4346 ns/op 5001 B/op 19 allocs/op +``` + ## Best Practices To maximize the benefits of otelslog in your application: diff --git a/README_zhCN.md b/README_zhCN.md index a77237e..6c5433e 100644 --- a/README_zhCN.md +++ b/README_zhCN.md @@ -194,6 +194,21 @@ func initTracer(ctx context.Context) (func(), error) { } ``` +## 基准测试 + +``` +goos: darwin +goarch: amd64 +pkg: github.com/yakumioto/otelslog +cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz +BenchmarkTextSlog-12 255117 4781 ns/op 4260 B/op 7 allocs/op +BenchmarkJSONSlog-12 346534 3367 ns/op 4157 B/op 7 allocs/op +BenchmarkJSONOtelSlogWithAttr-12 238906 5670 ns/op 5489 B/op 20 allocs/op +BenchmarkTextOtelSlogWithAttr-12 245080 4871 ns/op 5342 B/op 20 allocs/op +BenchmarkJSONOtelSlogWithContext-12 275746 4189 ns/op 5021 B/op 18 allocs/op +BenchmarkTextOtelSlogWithContext-12 271627 4346 ns/op 5001 B/op 19 allocs/op +``` + ## 最佳实践 为了在您的应用中最大化 otelslog 的效益: diff --git a/benchmark_test.go b/benchmark_test.go new file mode 100644 index 0000000..d042189 --- /dev/null +++ b/benchmark_test.go @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024 yakumioto + * All rights reserved. + */ + +package otelslog + +import ( + "bytes" + "context" + "log/slog" + "testing" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" +) + +func setUpBenchmarkTracer() { + exporter := tracetest.NewInMemoryExporter() + traceProvider := trace.NewTracerProvider(trace.WithSyncer(exporter)) + otel.SetTracerProvider(traceProvider) +} + +func BenchmarkTextSlog(b *testing.B) { + buf := bytes.NewBuffer(nil) + slog.SetDefault(slog.New( + slog.NewTextHandler(buf, nil), + ), + ) + setUpBenchmarkTracer() + ctx := context.Background() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + tracer := otel.Tracer("benchmark") + _, span := tracer.Start(ctx, "benchmark") + defer span.End() + slog.InfoContext(ctx, "hello, world") + } +} + +func BenchmarkJSONSlog(b *testing.B) { + buf := bytes.NewBuffer(nil) + slog.SetDefault(slog.New( + slog.NewJSONHandler(buf, nil), + ), + ) + + setUpBenchmarkTracer() + ctx := context.Background() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + tracer := otel.Tracer("benchmark") + _, span := tracer.Start(ctx, "benchmark") + defer span.End() + slog.InfoContext(ctx, "hello, world") + } +} + +func BenchmarkJSONOtelSlogWithAttr(b *testing.B) { + buf := bytes.NewBuffer(nil) + slog.SetDefault(slog.New( + NewHandler( + slog.NewJSONHandler(buf, nil), + ), + )) + setUpBenchmarkTracer() + ctx := context.Background() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + span := NewSpanContext("span") + defer span.End() + slog.InfoContext(ctx, "hello, world", "trace", span) + } +} +func BenchmarkTextOtelSlogWithAttr(b *testing.B) { + buf := bytes.NewBuffer(nil) + slog.SetDefault(slog.New( + NewHandler( + slog.NewTextHandler(buf, nil), + ), + )) + setUpBenchmarkTracer() + ctx := context.Background() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + span := NewSpanContext("span") + defer span.End() + slog.InfoContext(ctx, "hello, world", "trace", span) + } +} +func BenchmarkJSONOtelSlogWithContext(b *testing.B) { + buf := bytes.NewBuffer(nil) + slog.SetDefault(slog.New( + NewHandler( + slog.NewJSONHandler(buf, nil), + ), + )) + setUpBenchmarkTracer() + ctx := context.Background() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + spanCtx := NewMustSpanContextWithContext(ctx, "span") + defer spanCtx.Done() + slog.InfoContext(spanCtx, "hello, world") + } +} +func BenchmarkTextOtelSlogWithContext(b *testing.B) { + buf := bytes.NewBuffer(nil) + slog.SetDefault(slog.New( + NewHandler( + slog.NewTextHandler(buf, nil), + ), + )) + setUpBenchmarkTracer() + ctx := context.Background() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + spanCtx := NewMustSpanContextWithContext(ctx, "span") + defer spanCtx.Done() + slog.InfoContext(spanCtx, "hello, world") + } +} diff --git a/example_test.go b/example_test.go index 48b073b..2a13e52 100644 --- a/example_test.go +++ b/example_test.go @@ -6,13 +6,14 @@ package otelslog_test import ( + "bytes" "context" + "fmt" "log/slog" "os" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.24.0" @@ -23,17 +24,27 @@ import ( // initTracer initializes an OTLP exporter, and configures the corresponding trace provider. func initTracer(ctx context.Context) (func(), error) { // Create OTLP exporter - exporter, err := otlptrace.New( - ctx, - otlptracegrpc.NewClient( - otlptracegrpc.WithEndpoint("127.0.0.1:4317"), // Your collector endpoint - otlptracegrpc.WithInsecure(), // For testing only - ), + + // example with stdouttrace on buffer + buf := bytes.NewBuffer(nil) + exporter, err := stdouttrace.New( + stdouttrace.WithWriter(buf), ) if err != nil { return nil, err } + // exporter, err := otlptrace.New( + // ctx, + // otlptracegrpc.NewClient( + // otlptracegrpc.WithEndpoint("127.0.0.1:4317"), // Your collector endpoint + // otlptracegrpc.WithInsecure(), // For testing only + // ), + // ) + // if err != nil { + // return nil, err + // } + // Create resource with service information res, err := resource.New(ctx, resource.WithAttributes( @@ -60,6 +71,10 @@ func initTracer(ctx context.Context) (func(), error) { if err := tp.Shutdown(ctx); err != nil { slog.Error("Error shutting down tracer provider", "error", err) } + + // example with stdouttrace on buffer + fmt.Println("------- Trace span log -------") + fmt.Println(buf.String()) }, nil } diff --git a/go.mod b/go.mod index 91db67b..9b05d8b 100644 --- a/go.mod +++ b/go.mod @@ -5,28 +5,21 @@ go 1.23 require ( github.com/stretchr/testify v1.10.0 go.opentelemetry.io/otel v1.32.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 go.opentelemetry.io/otel/sdk v1.32.0 go.opentelemetry.io/otel/trace v1.32.0 ) require ( - github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect go.opentelemetry.io/otel/metric v1.32.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect - golang.org/x/net v0.30.0 // indirect golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect - google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.35.1 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8e15ca5..7a7a625 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -11,48 +10,33 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s= go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= -google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=