From b011c6d4e7ff3360f0498e9d1bd10c716d5b1730 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Mon, 21 Oct 2024 08:53:56 -0400 Subject: [PATCH 1/3] otelhttp: Allow setting start time using context (#6137) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/open-telemetry/opentelemetry-go-contrib/issues/5318 This allows overriding the start time for http server metrics and traces. See the linked issue for the motivation. --------- Co-authored-by: Robert Pająk --- CHANGELOG.md | 1 + instrumentation/net/http/otelhttp/handler.go | 5 ++++ .../net/http/otelhttp/start_time_context.go | 29 +++++++++++++++++++ .../http/otelhttp/start_time_context_test.go | 23 +++++++++++++++ .../net/http/otelhttp/test/handler_test.go | 8 +++++ 5 files changed, 66 insertions(+) create mode 100644 instrumentation/net/http/otelhttp/start_time_context.go create mode 100644 instrumentation/net/http/otelhttp/start_time_context_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index ab91768f636..1b5c995c081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Transform raw (`slog.KindAny`) attribute values to matching `log.Value` types. For example, `[]string{"foo", "bar"}` attribute value is now transformed to `log.SliceValue(log.StringValue("foo"), log.StringValue("bar"))` instead of `log.String("[foo bar"])`. (#6254) - Add the `WithSource` option to the `go.opentelemetry.io/contrib/bridges/otelslog` log bridge to set the `code.*` attributes in the log record that includes the source location where the record was emitted. (#6253) +- Add `ContextWithStartTime` and `StartTimeFromContext` to `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp`, which allows setting the start time using go context. (#6137) ### Fixed diff --git a/instrumentation/net/http/otelhttp/handler.go b/instrumentation/net/http/otelhttp/handler.go index e4236ab398c..e555a475f13 100644 --- a/instrumentation/net/http/otelhttp/handler.go +++ b/instrumentation/net/http/otelhttp/handler.go @@ -117,6 +117,11 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http } } + if startTime := StartTimeFromContext(ctx); !startTime.IsZero() { + opts = append(opts, trace.WithTimestamp(startTime)) + requestStartTime = startTime + } + ctx, span := tracer.Start(ctx, h.spanNameFormatter(h.operation, r), opts...) defer span.End() diff --git a/instrumentation/net/http/otelhttp/start_time_context.go b/instrumentation/net/http/otelhttp/start_time_context.go new file mode 100644 index 00000000000..9476ef01b01 --- /dev/null +++ b/instrumentation/net/http/otelhttp/start_time_context.go @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + +import ( + "context" + "time" +) + +type startTimeContextKeyType int + +const startTimeContextKey startTimeContextKeyType = 0 + +// ContextWithStartTime returns a new context with the provided start time. The +// start time will be used for metrics and traces emitted by the +// instrumentation. Only one labeller can be injected into the context. +// Injecting it multiple times will override the previous calls. +func ContextWithStartTime(parent context.Context, start time.Time) context.Context { + return context.WithValue(parent, startTimeContextKey, start) +} + +// StartTimeFromContext retrieves a time.Time from the provided context if one +// is available. If no start time was found in the provided context, a new, +// zero start time is returned and the second return value is false. +func StartTimeFromContext(ctx context.Context) time.Time { + t, _ := ctx.Value(startTimeContextKey).(time.Time) + return t +} diff --git a/instrumentation/net/http/otelhttp/start_time_context_test.go b/instrumentation/net/http/otelhttp/start_time_context_test.go new file mode 100644 index 00000000000..fd821fbd0a0 --- /dev/null +++ b/instrumentation/net/http/otelhttp/start_time_context_test.go @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otelhttp + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestStartTimeFromContext(t *testing.T) { + ctx := context.Background() + startTime := StartTimeFromContext(ctx) + assert.True(t, startTime.IsZero()) + + now := time.Now() + ctx = ContextWithStartTime(ctx, now) + startTime = StartTimeFromContext(ctx) + assert.True(t, startTime.Equal(now)) +} diff --git a/instrumentation/net/http/otelhttp/test/handler_test.go b/instrumentation/net/http/otelhttp/test/handler_test.go index 0f56f8af959..8caec99917e 100644 --- a/instrumentation/net/http/otelhttp/test/handler_test.go +++ b/instrumentation/net/http/otelhttp/test/handler_test.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -72,6 +73,9 @@ func assertScopeMetrics(t *testing.T, sm metricdata.ScopeMetrics, attrs attribut }, } metricdatatest.AssertEqual(t, want, sm.Metrics[2], metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreValue()) + + // verify that the custom start time, which is 10 minutes in the past, is respected. + assert.GreaterOrEqual(t, sm.Metrics[2].Data.(metricdata.Histogram[float64]).DataPoints[0].Sum, float64(10*time.Minute/time.Millisecond)) } func TestHandlerBasics(t *testing.T) { @@ -102,6 +106,9 @@ func TestHandlerBasics(t *testing.T) { if err != nil { t.Fatal(err) } + // set a custom start time 10 minutes in the past. + startTime := time.Now().Add(-10 * time.Minute) + r = r.WithContext(otelhttp.ContextWithStartTime(r.Context(), startTime)) h.ServeHTTP(rr, r) rm := metricdata.ResourceMetrics{} @@ -138,6 +145,7 @@ func TestHandlerBasics(t *testing.T) { if got, expected := string(d), "hello world"; got != expected { t.Fatalf("got %q, expected %q", got, expected) } + assert.Equal(t, startTime, spans[0].StartTime()) } func TestHandlerEmittedAttributes(t *testing.T) { From 3e1fe6991d25157d488563741a454c483e78ac51 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 07:51:54 -0700 Subject: [PATCH 2/3] chore(deps): update module github.com/bytedance/sonic/loader to v0.2.1 (#6267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [github.com/bytedance/sonic/loader](https://redirect.github.com/bytedance/sonic) | `v0.2.0` -> `v0.2.1` | [![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fbytedance%2fsonic%2floader/v0.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2fbytedance%2fsonic%2floader/v0.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2fbytedance%2fsonic%2floader/v0.2.0/v0.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fbytedance%2fsonic%2floader/v0.2.0/v0.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/open-telemetry/opentelemetry-go-contrib). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../github.com/gin-gonic/gin/otelgin/example/go.mod | 2 +- .../github.com/gin-gonic/gin/otelgin/example/go.sum | 4 ++-- instrumentation/github.com/gin-gonic/gin/otelgin/go.mod | 2 +- instrumentation/github.com/gin-gonic/gin/otelgin/go.sum | 4 ++-- instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod | 2 +- instrumentation/github.com/gin-gonic/gin/otelgin/test/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/example/go.mod b/instrumentation/github.com/gin-gonic/gin/otelgin/example/go.mod index b427907b3cc..b22f45c9c3f 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/example/go.mod +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/example/go.mod @@ -18,7 +18,7 @@ require ( require ( github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic/loader v0.2.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/gabriel-vasile/mimetype v1.4.6 // indirect diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/example/go.sum b/instrumentation/github.com/gin-gonic/gin/otelgin/example/go.sum index 7201919ccb7..cc9a08d2c3b 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/example/go.sum +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/example/go.sum @@ -1,8 +1,8 @@ github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E= +github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/go.mod b/instrumentation/github.com/gin-gonic/gin/otelgin/go.mod index cef099e6fb9..7587e11f210 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/go.mod +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/go.mod @@ -14,7 +14,7 @@ require ( require ( github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic/loader v0.2.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/go.sum b/instrumentation/github.com/gin-gonic/gin/otelgin/go.sum index 693d0172bd7..e946ef776fe 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/go.sum +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/go.sum @@ -1,8 +1,8 @@ github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E= +github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod b/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod index f921a753c5a..c7d4cf44c3e 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod @@ -13,7 +13,7 @@ require ( require ( github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic/loader v0.2.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.sum b/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.sum index 3c7f60de392..dc0e4f207b7 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.sum +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.sum @@ -1,8 +1,8 @@ github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E= +github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= From 0a251077792ed66caef529cdcb6bd47651176c4d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 09:24:24 -0700 Subject: [PATCH 3/3] chore(deps): update module github.com/ebitengine/purego to v0.8.1 (#6269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [github.com/ebitengine/purego](https://redirect.github.com/ebitengine/purego) | `v0.8.0` -> `v0.8.1` | [![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2febitengine%2fpurego/v0.8.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2febitengine%2fpurego/v0.8.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2febitengine%2fpurego/v0.8.0/v0.8.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2febitengine%2fpurego/v0.8.0/v0.8.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
ebitengine/purego (github.com/ebitengine/purego) ### [`v0.8.1`](https://redirect.github.com/ebitengine/purego/compare/v0.8.0...v0.8.1) [Compare Source](https://redirect.github.com/ebitengine/purego/compare/v0.8.0...v0.8.1)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/open-telemetry/opentelemetry-go-contrib). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- instrumentation/host/example/go.mod | 2 +- instrumentation/host/example/go.sum | 4 ++-- instrumentation/host/go.mod | 2 +- instrumentation/host/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/instrumentation/host/example/go.mod b/instrumentation/host/example/go.mod index c5103d96bfa..5d83802f5d6 100644 --- a/instrumentation/host/example/go.mod +++ b/instrumentation/host/example/go.mod @@ -13,7 +13,7 @@ require ( ) require ( - github.com/ebitengine/purego v0.8.0 // indirect + github.com/ebitengine/purego v0.8.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect diff --git a/instrumentation/host/example/go.sum b/instrumentation/host/example/go.sum index 44d52ddcff4..6f6076690c4 100644 --- a/instrumentation/host/example/go.sum +++ b/instrumentation/host/example/go.sum @@ -1,7 +1,7 @@ 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/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE= -github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE= +github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= diff --git a/instrumentation/host/go.mod b/instrumentation/host/go.mod index 9d245ce776d..cf10d26227a 100644 --- a/instrumentation/host/go.mod +++ b/instrumentation/host/go.mod @@ -9,7 +9,7 @@ require ( ) require ( - github.com/ebitengine/purego v0.8.0 // indirect + github.com/ebitengine/purego v0.8.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect diff --git a/instrumentation/host/go.sum b/instrumentation/host/go.sum index 0bc554290c0..a580b0af996 100644 --- a/instrumentation/host/go.sum +++ b/instrumentation/host/go.sum @@ -1,7 +1,7 @@ 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/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE= -github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE= +github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=