Skip to content

Commit

Permalink
Merge pull request #9 from grafana/chore/cleanup
Browse files Browse the repository at this point in the history
Deprecate unused options
  • Loading branch information
kolesnikovae authored Dec 5, 2023
2 parents 614c343 + 207e85a commit 98e430f
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 315 deletions.
67 changes: 49 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,64 @@
# Profiling Instrumentation
# Profiling Instrumentation for OpenTelemetry Go SDK

**NOTE**: This is an experimental package -- and will be officially supported in future versions of Pyroscope

The package provides means to integrate tracing with profiling. More specifically, a `TracerProvider` implementation,
that annotates profiling data with span IDs: when a new trace span emerges, the tracer adds a `profile_id` [pprof tag](https://github.com/google/pprof/blob/master/doc/README.md#tag-filtering)
that annotates profiling data with span IDs: when a new trace span emerges, the tracer adds a `span_id` [pprof tag](https://github.com/google/pprof/blob/master/doc/README.md#tag-filtering)
that points to the span. This makes it possible to filter out a profile of a particular trace span in [Pyroscope](https://pyroscope.io).

### Jaeger Example
You can find a full Jaeger example (with custom Jaeger UI) in the [tracing/jaeger](https://github.com/pyroscope-io/pyroscope/tree/main/examples/tracing/jaeger) folder in the Pyroscope repository.
![image](https://user-images.githubusercontent.com/23323466/164025573-1f6e713b-ec94-4d82-842c-faf2be652b7f.png)
Note that the module does not control `pprof` profiler itself – it still needs to be started for profiles to be
collected. This can be done either via `runtime/pprof` package, or using the [Pyroscope client](https://github.com/grafana/pyroscope-go).

#### Baseline Diffs
We also added functionality where each individual span is compared to a baseline of spans with similar properties and the diff can be shown in the UI:
By default, only the root span gets labeled (the first span created locally): such spans are marked with the
`pyroscope.profile.id` attribute set to the span ID. Please note that presence of the attribute does not necessarily
indicate that the span has a profile: stack trace samples might not be collected, if the utilized CPU time is
less than the sample interval (10ms).

[![Watch the video](https://user-images.githubusercontent.com/23323466/165633049-9591b0fd-b8be-4fbd-a0af-d90a1dd89b7b.mov)](https://user-images.githubusercontent.com/23323466/165633049-9591b0fd-b8be-4fbd-a0af-d90a1dd89b7b.mov)
Limitations:
- Only CPU profiling is fully supported at the moment.

### Trace spans profiles

### Grafana Example
For another example of what this package allows you to do you can see with Grafana the ability to link between logs, traces and profiles in the following video ([source](https://github.com/pyroscope-io/pyroscope/tree/main/examples/tracing/jaeger)):
To start profiling trace spans, you need to include our go module in your app:

[![Watch the video](https://user-images.githubusercontent.com/23323466/172881613-842f67f0-6bfa-4671-a44a-e966d5ca67a4.mov)](https://user-images.githubusercontent.com/23323466/172881613-842f67f0-6bfa-4671-a44a-e966d5ca67a4.mov)
```
go get github.com/grafana/otel-profiling-go
```

Then add the pyroscope tracer provider:

### Other Notes
Note that the module does not control `pprof` profiler itself – it still needs to be started for profiles to be
collected. This can be done either via `runtime/pprof` package, or using the [Pyroscope client](https://github.com/pyroscope-io/client).
```go
package main

import (
otelpyroscope "github.com/grafana/otel-profiling-go"
"github.com/grafana/pyroscope-go"
)

func main() {
// Initialize your tracer provider as usual.
tp := initTracer()

// Wrap it with otelpyroscope tracer provider.
otel.SetTracerProvider(otelpyroscope.NewTracerProvider(tp))

// If you're using Pyroscope Go SDK, initialize pyroscope profiler.
_, _ = pyroscope.Start(pyroscope.Config{
ApplicationName: "my-service",
ServerAddress: "http://localhost:4040",
})

// Your code goes here.
}
```

Tracing integration is supported in pull mode as well: if you scrape profiles using Grafana Agent, you should
make sure that the pyroscope `service_name` label matches `service.name` attribute specified in the OTel SDK configuration.
Please refer to the [Grafana Agent](https://grafana.com/docs/pyroscope/latest/configure-client/grafana-agent/go_pull/)
documentation to learn more.

## Example

By default, only the root span gets annotated (the first span created locally), this is done to circumvent the fact that the profiler records only the time spent on CPU. Otherwise, all the children profiles should be merged to get the full representation of the root span profile.
You can find a complete example setup with Grafana Tempo in the [Pyroscope repository](https://github.com/grafana/pyroscope/tree/main/examples/tracing/tempo).

There are few limitations:
- Only Go CPU profiling is fully supported at the moment.
- Due to the very idea of the sampling profilers, spans shorter than the sample interval may not be captured. For example, Go CPU profiler probes stack traces 100 times per second, meaning that spans shorter than 10ms may not be captured.
![image](https://github.com/grafana/otel-profiling-go/assets/12090599/31e33cd1-818b-4116-b952-c9ec7b1fb593)
66 changes: 66 additions & 0 deletions deprecated.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package otelpyroscope

// Config describes tracer configuration.
// DEPRECATED: Do not use.
type Config struct {
AppName string
PyroscopeURL string
IncludeProfileURL bool
IncludeProfileBaselineURL bool
ProfileBaselineLabels map[string]string

RootOnly bool
AddSpanName bool
}

// WithRootSpanOnly indicates that only the root span is to be profiled.
// The profile includes samples captured during child span execution
// but the spans won't have their own profiles and won't be annotated
// with pyroscope.profile attributes.
// The option is enabled by default.
// DEPRECATED: Ignored by tracer.
func WithRootSpanOnly(bool) Option { return func(tp *tracerProvider) {} }

// WithAddSpanName specifies whether the current span name should be added
// to the profile labels. N.B if the name is dynamic, or too many values
// are supposed, this may significantly deteriorate performance.
// By default, span name is not added to profile labels.
// DEPRECATED: Ignored by tracer.
func WithAddSpanName(bool) Option { return func(tp *tracerProvider) {} }

// WithAppName specifies the profiled application name.
// It should match the name specified in pyroscope configuration.
// Required, if profile URL or profile baseline URL is enabled.
// DEPRECATED: Ignored by tracer.
func WithAppName(string) Option { return func(tp *tracerProvider) {} }

// WithPyroscopeURL provides a base URL for the profile and baseline URLs.
// Required, if profile URL or profile baseline URL is enabled.
// DEPRECATED: Ignored by tracer.
func WithPyroscopeURL(string) Option { return func(tp *tracerProvider) {} }

// WithProfileURL specifies whether to add the pyroscope.profile.url
// attribute with the URL to the span profile.
// DEPRECATED: Ignored by tracer.
func WithProfileURL(bool) Option { return func(tp *tracerProvider) {} }

// WithProfileBaselineURL specifies whether to add the
// pyroscope.profile.baseline.url attribute with the URL
// to the baseline profile. See WithProfileBaselineLabels.
// DEPRECATED: Ignored by tracer.
func WithProfileBaselineURL(bool) Option { return func(tp *tracerProvider) {} }

// WithProfileBaselineLabels provides a map of extra labels to be added to the
// baseline query alongside with pprof labels set in runtime. Typically,
// it should match the labels specified in the Pyroscope profiler config.
// Note that the map must not be modified.
// DEPRECATED: Ignored by tracer.
func WithProfileBaselineLabels(map[string]string) Option { return func(tp *tracerProvider) {} }

// WithProfileURLBuilder specifies how profile URL is to be built.
// DEPRECATED: Ignored by tracer.
func WithProfileURLBuilder(func(_ string) string) Option { return func(tp *tracerProvider) {} }

// WithDefaultProfileURLBuilder specifies the default profile URL builder.
// DEPRECATED: Ignored by tracer.
func WithDefaultProfileURLBuilder(_, _ string) Option { return func(tp *tracerProvider) {} }
13 changes: 0 additions & 13 deletions example/Dockerfile

This file was deleted.

18 changes: 0 additions & 18 deletions example/README.md

This file was deleted.

16 changes: 0 additions & 16 deletions example/docker-compose.yaml

This file was deleted.

10 changes: 5 additions & 5 deletions example/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ module github.com/pyroscope-io/otel-profiling-go/example
go 1.16

require (
github.com/grafana/pyroscope-go v1.0.4 // indirect
github.com/pyroscope-io/otel-profiling-go v0.4.0
go.opentelemetry.io/otel v1.20.0
github.com/grafana/otel-profiling-go v0.5.0
github.com/grafana/pyroscope-go v1.0.4
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1
go.opentelemetry.io/otel/sdk v1.20.0
go.opentelemetry.io/otel/sdk v1.21.0
)

replace github.com/pyroscope-io/otel-profiling-go => ../
replace github.com/grafana/otel-profiling-go => ../
19 changes: 8 additions & 11 deletions example/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
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/grafana/pyroscope-go v0.2.1/go.mod h1:zRdQXIGxy0H2QbKEkCmZBR6KOLLIFYLWsdzVI0MRm2E=
github.com/grafana/pyroscope-go v1.0.4 h1:oyQX0BOkL+iARXzHuCdIF5TQ7/sRSel1YFViMHC7Bm0=
github.com/grafana/pyroscope-go v1.0.4/go.mod h1:0d7ftwSMBV/Awm7CCiYmHQEG8Y44Ma3YSjt+nWcWztY=
github.com/grafana/pyroscope-go/godeltaprof v0.1.4 h1:mDsJ3ngul7UfrHibGQpV66PbZ3q1T8glz/tK3bQKKEk=
github.com/grafana/pyroscope-go/godeltaprof v0.1.4/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko=
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/pyroscope-io/client v0.2.1 h1:GUyrncANOCuFhnmgURnpJ90o9z/uwZMx+1l9RMJUuKk=
github.com/pyroscope-io/client v0.2.1/go.mod h1:zRdQXIGxy0H2QbKEkCmZBR6KOLLIFYLWsdzVI0MRm2E=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand All @@ -27,18 +24,18 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4=
go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc=
go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1 h1:yaXaoJjXaJqRnsfW9HrN7pGb7bzcEn31Rk6yo2LFaWo=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1/go.mod h1:BFiGsTMZdqtxufux8ANXuMeRz9dMPVFdJZadUWDFD7o=
go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA=
go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE=
go.opentelemetry.io/otel/sdk v1.20.0 h1:5Jf6imeFZlZtKv9Qbo6qt2ZkmWtdWx/wzcCbNUlAWGM=
go.opentelemetry.io/otel/sdk v1.20.0/go.mod h1:rmkSx1cZCm/tn16iWDn1GQbLtsW/LvsdEEFzCSRM6V0=
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc=
go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ=
go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
Expand Down
37 changes: 11 additions & 26 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"context"
"errors"
"log"
"net/http"
Expand All @@ -13,26 +12,20 @@ import (
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/trace"

"github.com/pyroscope-io/otel-profiling-go"
)

const (
appName = "example-app"
pyroscopeEndpoint = "http://localhost:4040"
otelpyroscope "github.com/grafana/otel-profiling-go"
)

func main() {
tp := initTracer(appName, pyroscopeEndpoint)
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
log.Printf("Error shutting down tracer provider: %v", err)
}
}()
// Initialize your tracer provider as usual.
tp := initTracer()

// Wrap it with otelpyroscope tracer provider.
otel.SetTracerProvider(otelpyroscope.NewTracerProvider(tp))

// Initialize pyroscope profiler.
_, _ = pyroscope.Start(pyroscope.Config{
ApplicationName: appName,
ServerAddress: pyroscopeEndpoint,
Logger: pyroscope.StandardLogger,
ApplicationName: "my-service",
ServerAddress: "http://localhost:4040",
})

log.Println("starting listening")
Expand All @@ -42,7 +35,7 @@ func main() {
}
}

func cpuBoundHandler(w http.ResponseWriter, r *http.Request) {
func cpuBoundHandler(_ http.ResponseWriter, r *http.Request) {
tracer := otel.GetTracerProvider().Tracer("")
_, span := tracer.Start(r.Context(), "cpuBoundHandler")
defer span.End()
Expand All @@ -54,7 +47,7 @@ func cpuBoundHandler(w http.ResponseWriter, r *http.Request) {
}
}

func initTracer(appName, pyroscopeEndpoint string) *trace.TracerProvider {
func initTracer() *trace.TracerProvider {
exporter, err := stdouttrace.New(stdouttrace.WithPrettyPrint())
if err != nil {
log.Fatal(err)
Expand All @@ -63,14 +56,6 @@ func initTracer(appName, pyroscopeEndpoint string) *trace.TracerProvider {
trace.WithSampler(trace.AlwaysSample()),
trace.WithBatcher(exporter),
)
otel.SetTracerProvider(otelpyroscope.NewTracerProvider(tp,
otelpyroscope.WithAppName(appName),
otelpyroscope.WithPyroscopeURL(pyroscopeEndpoint),
otelpyroscope.WithRootSpanOnly(true),
otelpyroscope.WithAddSpanName(true),
otelpyroscope.WithProfileURL(true),
otelpyroscope.WithProfileBaselineURL(true),
))
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{},
propagation.Baggage{},
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module github.com/pyroscope-io/otel-profiling-go
module github.com/grafana/otel-profiling-go

go 1.16

require (
go.opentelemetry.io/otel v1.20.0
go.opentelemetry.io/otel/trace v1.20.0
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/sdk v1.21.0
go.opentelemetry.io/otel/trace v1.21.0
)
17 changes: 12 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
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=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
Expand All @@ -15,11 +17,16 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc=
go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs=
go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM=
go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ=
go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
Loading

0 comments on commit 98e430f

Please sign in to comment.