This commit is contained in:
Mateusz Urbanek 2024-05-19 12:26:56 +02:00 committed by GitHub
commit cba9303714
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 2195 additions and 15 deletions

View file

@ -29,6 +29,7 @@ import (
backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc/proto"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc/traced"
)
// Set grpc version on compile time to compare against server version response.
@ -44,7 +45,7 @@ func NewGrpcClient(conn *grpc.ClientConn) rpc.Peer {
client := new(client)
client.client = proto.NewWoodpeckerClient(conn)
client.conn = conn
return client
return traced.NewPeerWithTracing(client, "grpc-peer")
}
func (c *client) Close() error {

View file

@ -31,6 +31,7 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
@ -117,6 +118,7 @@ func run(c *cli.Context) error {
authorizer := woodpeckerGrpcServer.NewAuthorizer(jwtManager)
grpcServer := grpc.NewServer(
grpc.StatsHandler(otelgrpc.NewServerHandler()),
grpc.StreamInterceptor(authorizer.StreamInterceptor),
grpc.UnaryInterceptor(authorizer.UnaryInterceptor),
grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{

View file

@ -29,7 +29,9 @@ import (
"go.woodpecker-ci.org/woodpecker/v2/server"
"go.woodpecker-ci.org/woodpecker/v2/server/cache"
tracedcache "go.woodpecker-ci.org/woodpecker/v2/server/cache/traced"
"go.woodpecker-ci.org/woodpecker/v2/server/queue"
tracedqueue "go.woodpecker-ci.org/woodpecker/v2/server/queue/traced"
"go.woodpecker-ci.org/woodpecker/v2/server/store"
"go.woodpecker-ci.org/woodpecker/v2/server/store/datastore"
)
@ -88,11 +90,17 @@ func checkSqliteFileExist(path string) error {
}
func setupQueue(c *cli.Context, s store.Store) queue.Queue {
return queue.WithTaskStore(queue.New(c.Context), s)
return tracedqueue.NewQueueWithTracing(
queue.WithTaskStore(queue.New(c.Context), s),
"server-queue",
)
}
func setupMembershipService(_ *cli.Context, _store store.Store) cache.MembershipService {
return cache.NewMembershipService(_store)
return tracedcache.NewMembershipServiceWithTracing(
cache.NewMembershipService(_store),
"server-membership-service",
)
}
func setupMetrics(g *errgroup.Group, _store store.Store) {

12
go.mod
View file

@ -56,6 +56,11 @@ require (
github.com/xanzy/go-gitlab v0.101.0
github.com/xeipuuv/gojsonschema v1.2.0
github.com/zalando/go-keyring v0.2.4
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.51.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0
go.opentelemetry.io/otel v1.26.0
go.opentelemetry.io/otel/trace v1.26.0
go.uber.org/multierr v1.11.0
golang.org/x/crypto v0.22.0
golang.org/x/net v0.24.0
@ -63,7 +68,7 @@ require (
golang.org/x/sync v0.6.0
golang.org/x/term v0.19.0
golang.org/x/text v0.14.0
google.golang.org/grpc v1.62.1
google.golang.org/grpc v1.63.2
google.golang.org/protobuf v1.33.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.29.3
@ -99,10 +104,12 @@ require (
github.com/docker/docker-credential-helpers v0.8.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-fed/httpsig v1.1.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/spec v0.20.13 // indirect
@ -167,6 +174,7 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.opentelemetry.io/otel/metric v1.26.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/arch v0.6.0 // indirect
golang.org/x/mod v0.14.0 // indirect
@ -174,7 +182,7 @@ require (
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.1 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gotest.tools/v3 v3.4.0 // indirect

27
go.sum
View file

@ -118,6 +118,8 @@ github.com/expr-lang/expr v1.16.3/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf h1:NrF81UtW8gG2LBGkXFQFqlfNnvMt9WdB46sfdJY4oqc=
github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -137,9 +139,12 @@ github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/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/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU=
@ -505,6 +510,20 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.51.0 h1:YtDR4UCXpMJJb5Z5h5FD47uwL4NFxoJ6brW4FZ/+/5o=
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.51.0/go.mod h1:JWEIoUElJ0VTo4VaUTCJDr9yCKxJ5jtjN7lFl06cT6g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
go.opentelemetry.io/contrib/propagators/b3 v1.26.0 h1:wgFbVA+bK2k+fGVfDOCOG4cfDAoppyr5sI2dVlh8MWM=
go.opentelemetry.io/contrib/propagators/b3 v1.26.0/go.mod h1:DDktFXxA+fyItAAM0Sbl5OBH7KOsCTjvbBdPKtoIf/k=
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4=
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@ -675,14 +694,14 @@ google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJ
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=

View file

@ -19,9 +19,19 @@ import (
"fmt"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types/traced"
)
func FindBackend(ctx context.Context, backends []types.Backend, backendName string) (types.Backend, error) {
b, err := findBackend(ctx, backends, backendName)
if err != nil {
return b, err
}
return traced.NewBackendWithTracing(b, backendName), nil
}
func findBackend(ctx context.Context, backends []types.Backend, backendName string) (types.Backend, error) {
if backendName == "auto-detect" {
for _, engine := range backends {
if engine.IsAvailable(ctx) {

View file

@ -0,0 +1,214 @@
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../../templates/opentelemetry.go.tpl
// gowrap: http://github.com/hexdigest/gowrap
package traced
//go:generate gowrap gen -p go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types -i Backend -t ../../../../templates/opentelemetry.go.tpl -o tracedbackend.gen.go -l ""
import (
"context"
"io"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
)
// BackendWithTracing implements types.Backend interface instrumented with opentracing spans
type BackendWithTracing struct {
types.Backend
_instance string
_spanDecorator func(span trace.Span, params, results map[string]interface{})
}
// NewBackendWithTracing returns BackendWithTracing
func NewBackendWithTracing(base types.Backend, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) BackendWithTracing {
d := BackendWithTracing{
Backend: base,
_instance: instance,
}
if len(spanDecorator) > 0 && spanDecorator[0] != nil {
d._spanDecorator = spanDecorator[0]
}
return d
}
// DestroyStep implements types.Backend
func (_d BackendWithTracing) DestroyStep(ctx context.Context, step *types.Step, taskUUID string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "types.Backend.DestroyStep")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"step": step,
"taskUUID": taskUUID}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Backend.DestroyStep(ctx, step, taskUUID)
}
// DestroyWorkflow implements types.Backend
func (_d BackendWithTracing) DestroyWorkflow(ctx context.Context, conf *types.Config, taskUUID string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "types.Backend.DestroyWorkflow")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"conf": conf,
"taskUUID": taskUUID}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Backend.DestroyWorkflow(ctx, conf, taskUUID)
}
// IsAvailable implements types.Backend
func (_d BackendWithTracing) IsAvailable(ctx context.Context) (b1 bool) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "types.Backend.IsAvailable")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx}, map[string]interface{}{
"b1": b1})
}
_span.End()
}()
return _d.Backend.IsAvailable(ctx)
}
// Load implements types.Backend
func (_d BackendWithTracing) Load(ctx context.Context) (bp1 *types.BackendInfo, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "types.Backend.Load")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx}, map[string]interface{}{
"bp1": bp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Backend.Load(ctx)
}
// SetupWorkflow implements types.Backend
func (_d BackendWithTracing) SetupWorkflow(ctx context.Context, conf *types.Config, taskUUID string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "types.Backend.SetupWorkflow")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"conf": conf,
"taskUUID": taskUUID}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Backend.SetupWorkflow(ctx, conf, taskUUID)
}
// StartStep implements types.Backend
func (_d BackendWithTracing) StartStep(ctx context.Context, step *types.Step, taskUUID string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "types.Backend.StartStep")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"step": step,
"taskUUID": taskUUID}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Backend.StartStep(ctx, step, taskUUID)
}
// TailStep implements types.Backend
func (_d BackendWithTracing) TailStep(ctx context.Context, step *types.Step, taskUUID string) (r1 io.ReadCloser, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "types.Backend.TailStep")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"step": step,
"taskUUID": taskUUID}, map[string]interface{}{
"r1": r1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Backend.TailStep(ctx, step, taskUUID)
}
// WaitStep implements types.Backend
func (_d BackendWithTracing) WaitStep(ctx context.Context, step *types.Step, taskUUID string) (sp1 *types.State, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "types.Backend.WaitStep")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"step": step,
"taskUUID": taskUUID}, map[string]interface{}{
"sp1": sp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Backend.WaitStep(ctx, step, taskUUID)
}

View file

@ -0,0 +1,302 @@
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../../templates/opentelemetry.go.tpl
// gowrap: http://github.com/hexdigest/gowrap
package traced
//go:generate gowrap gen -p go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc/proto -i WoodpeckerClient -t ../../../../templates/opentelemetry.go.tpl -o tracedwoodpeckerclient.gen.go -l ""
import (
context "context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc/proto"
grpc "google.golang.org/grpc"
)
// WoodpeckerClientWithTracing implements proto.WoodpeckerClient interface instrumented with opentracing spans
type WoodpeckerClientWithTracing struct {
proto.WoodpeckerClient
_instance string
_spanDecorator func(span trace.Span, params, results map[string]interface{})
}
// NewWoodpeckerClientWithTracing returns WoodpeckerClientWithTracing
func NewWoodpeckerClientWithTracing(base proto.WoodpeckerClient, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) WoodpeckerClientWithTracing {
d := WoodpeckerClientWithTracing{
WoodpeckerClient: base,
_instance: instance,
}
if len(spanDecorator) > 0 && spanDecorator[0] != nil {
d._spanDecorator = spanDecorator[0]
}
return d
}
// Done implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) Done(ctx context.Context, in *proto.DoneRequest, opts ...grpc.CallOption) (ep1 *proto.Empty, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.Done")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"ep1": ep1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.Done(ctx, in, opts...)
}
// Extend implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) Extend(ctx context.Context, in *proto.ExtendRequest, opts ...grpc.CallOption) (ep1 *proto.Empty, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.Extend")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"ep1": ep1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.Extend(ctx, in, opts...)
}
// Init implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) Init(ctx context.Context, in *proto.InitRequest, opts ...grpc.CallOption) (ep1 *proto.Empty, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.Init")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"ep1": ep1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.Init(ctx, in, opts...)
}
// Log implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) Log(ctx context.Context, in *proto.LogRequest, opts ...grpc.CallOption) (ep1 *proto.Empty, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.Log")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"ep1": ep1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.Log(ctx, in, opts...)
}
// Next implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) Next(ctx context.Context, in *proto.NextRequest, opts ...grpc.CallOption) (np1 *proto.NextResponse, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.Next")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"np1": np1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.Next(ctx, in, opts...)
}
// RegisterAgent implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) RegisterAgent(ctx context.Context, in *proto.RegisterAgentRequest, opts ...grpc.CallOption) (rp1 *proto.RegisterAgentResponse, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.RegisterAgent")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"rp1": rp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.RegisterAgent(ctx, in, opts...)
}
// ReportHealth implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) ReportHealth(ctx context.Context, in *proto.ReportHealthRequest, opts ...grpc.CallOption) (ep1 *proto.Empty, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.ReportHealth")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"ep1": ep1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.ReportHealth(ctx, in, opts...)
}
// UnregisterAgent implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) UnregisterAgent(ctx context.Context, in *proto.Empty, opts ...grpc.CallOption) (ep1 *proto.Empty, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.UnregisterAgent")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"ep1": ep1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.UnregisterAgent(ctx, in, opts...)
}
// Update implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) Update(ctx context.Context, in *proto.UpdateRequest, opts ...grpc.CallOption) (ep1 *proto.Empty, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.Update")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"ep1": ep1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.Update(ctx, in, opts...)
}
// Version implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) Version(ctx context.Context, in *proto.Empty, opts ...grpc.CallOption) (vp1 *proto.VersionResponse, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.Version")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"vp1": vp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.Version(ctx, in, opts...)
}
// Wait implements proto.WoodpeckerClient
func (_d WoodpeckerClientWithTracing) Wait(ctx context.Context, in *proto.WaitRequest, opts ...grpc.CallOption) (ep1 *proto.Empty, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "proto.WoodpeckerClient.Wait")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"in": in,
"opts": opts}, map[string]interface{}{
"ep1": ep1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.WoodpeckerClient.Wait(ctx, in, opts...)
}

View file

@ -0,0 +1,285 @@
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../templates/opentelemetry.go.tpl
// gowrap: http://github.com/hexdigest/gowrap
package traced
//go:generate gowrap gen -p go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc -i Peer -t ../../../templates/opentelemetry.go.tpl -o tracedpeer.gen.go -l ""
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc"
)
// PeerWithTracing implements rpc.Peer interface instrumented with opentracing spans
type PeerWithTracing struct {
rpc.Peer
_instance string
_spanDecorator func(span trace.Span, params, results map[string]interface{})
}
// NewPeerWithTracing returns PeerWithTracing
func NewPeerWithTracing(base rpc.Peer, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) PeerWithTracing {
d := PeerWithTracing{
Peer: base,
_instance: instance,
}
if len(spanDecorator) > 0 && spanDecorator[0] != nil {
d._spanDecorator = spanDecorator[0]
}
return d
}
// Done implements rpc.Peer
func (_d PeerWithTracing) Done(ctx context.Context, id string, state rpc.State) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.Done")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id,
"state": state}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.Done(ctx, id, state)
}
// Extend implements rpc.Peer
func (_d PeerWithTracing) Extend(ctx context.Context, id string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.Extend")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.Extend(ctx, id)
}
// Init implements rpc.Peer
func (_d PeerWithTracing) Init(ctx context.Context, id string, state rpc.State) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.Init")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id,
"state": state}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.Init(ctx, id, state)
}
// Log implements rpc.Peer
func (_d PeerWithTracing) Log(ctx context.Context, logEntry *rpc.LogEntry) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.Log")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"logEntry": logEntry}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.Log(ctx, logEntry)
}
// Next implements rpc.Peer
func (_d PeerWithTracing) Next(ctx context.Context, f rpc.Filter) (wp1 *rpc.Workflow, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.Next")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"f": f}, map[string]interface{}{
"wp1": wp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.Next(ctx, f)
}
// RegisterAgent implements rpc.Peer
func (_d PeerWithTracing) RegisterAgent(ctx context.Context, platform string, backend string, version string, capacity int) (i1 int64, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.RegisterAgent")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"platform": platform,
"backend": backend,
"version": version,
"capacity": capacity}, map[string]interface{}{
"i1": i1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.RegisterAgent(ctx, platform, backend, version, capacity)
}
// ReportHealth implements rpc.Peer
func (_d PeerWithTracing) ReportHealth(ctx context.Context) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.ReportHealth")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.ReportHealth(ctx)
}
// UnregisterAgent implements rpc.Peer
func (_d PeerWithTracing) UnregisterAgent(ctx context.Context) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.UnregisterAgent")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.UnregisterAgent(ctx)
}
// Update implements rpc.Peer
func (_d PeerWithTracing) Update(ctx context.Context, id string, state rpc.State) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.Update")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id,
"state": state}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.Update(ctx, id, state)
}
// Version implements rpc.Peer
func (_d PeerWithTracing) Version(ctx context.Context) (vp1 *rpc.Version, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.Version")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx}, map[string]interface{}{
"vp1": vp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.Version(ctx)
}
// Wait implements rpc.Peer
func (_d PeerWithTracing) Wait(ctx context.Context, id string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "rpc.Peer.Wait")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Peer.Wait(ctx, id)
}

View file

@ -0,0 +1,64 @@
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../templates/opentelemetry.go.tpl
// gowrap: http://github.com/hexdigest/gowrap
package traced
//go:generate gowrap gen -p go.woodpecker-ci.org/woodpecker/v2/server/cache -i MembershipService -t ../../../templates/opentelemetry.go.tpl -o tracedmembership.gen.go -l ""
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"go.woodpecker-ci.org/woodpecker/v2/server/cache"
"go.woodpecker-ci.org/woodpecker/v2/server/forge"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
// MembershipServiceWithTracing implements cache.MembershipService interface instrumented with opentracing spans
type MembershipServiceWithTracing struct {
cache.MembershipService
_instance string
_spanDecorator func(span trace.Span, params, results map[string]interface{})
}
// NewMembershipServiceWithTracing returns MembershipServiceWithTracing
func NewMembershipServiceWithTracing(base cache.MembershipService, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) MembershipServiceWithTracing {
d := MembershipServiceWithTracing{
MembershipService: base,
_instance: instance,
}
if len(spanDecorator) > 0 && spanDecorator[0] != nil {
d._spanDecorator = spanDecorator[0]
}
return d
}
// Get implements cache.MembershipService
func (_d MembershipServiceWithTracing) Get(ctx context.Context, _forge forge.Forge, u *model.User, org string) (op1 *model.OrgPerm, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "cache.MembershipService.Get")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"_forge": _forge,
"u": u,
"org": org}, map[string]interface{}{
"op1": op1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.MembershipService.Get(ctx, _forge, u, org)
}

View file

@ -23,6 +23,7 @@ import (
"net/http"
"net/url"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"golang.org/x/oauth2"
"golang.org/x/oauth2/bitbucket"
@ -63,6 +64,8 @@ type Client struct {
}
func NewClient(ctx context.Context, url string, client *http.Client) *Client {
client.Transport = otelhttp.NewTransport(client.Transport)
return &Client{
Client: client,
base: url,

View file

@ -21,6 +21,7 @@ import (
"net/http"
"strings"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"golang.org/x/oauth2"
)
@ -34,8 +35,11 @@ type Client struct {
}
func NewClientWithToken(ctx context.Context, ts oauth2.TokenSource, url string) *Client {
client := oauth2.NewClient(ctx, ts)
client.Transport = otelhttp.NewTransport(client.Transport)
return &Client{
client: oauth2.NewClient(ctx, ts),
client: client,
base: url,
}
}

View file

@ -30,6 +30,7 @@ import (
"code.gitea.io/sdk/gitea"
"github.com/rs/zerolog/log"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"golang.org/x/oauth2"
"go.woodpecker-ci.org/woodpecker/v2/server"
@ -591,6 +592,7 @@ func (c *Gitea) newClientToken(ctx context.Context, token string) (*gitea.Client
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
}
httpClient.Transport = otelhttp.NewTransport(httpClient.Transport)
client, err := gitea.NewClient(c.url, gitea.SetToken(token), gitea.SetHTTPClient(httpClient), gitea.SetContext(ctx))
if err != nil &&
(errors.Is(err, &gitea.ErrUnknownVersion{}) || strings.Contains(err.Error(), "Malformed version")) {

View file

@ -28,6 +28,7 @@ import (
"github.com/google/go-github/v61/github"
"github.com/rs/zerolog/log"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"golang.org/x/oauth2"
"go.woodpecker-ci.org/woodpecker/v2/server"
@ -400,12 +401,12 @@ func (c *client) newContext(ctx context.Context) context.Context {
return ctx
}
return context.WithValue(ctx, oauth2.HTTPClient, &http.Client{
Transport: &http.Transport{
Transport: otelhttp.NewTransport(&http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}),
})
}

View file

@ -20,6 +20,7 @@ import (
"net/http"
"github.com/xanzy/go-gitlab"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
const (
@ -30,10 +31,10 @@ const (
// client using the provided OAuth token.
func newClient(url, accessToken string, skipVerify bool) (*gitlab.Client, error) {
return gitlab.NewOAuthClient(accessToken, gitlab.WithBaseURL(url), gitlab.WithHTTPClient(&http.Client{
Transport: &http.Transport{
Transport: otelhttp.NewTransport(&http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: skipVerify},
Proxy: http.ProxyFromEnvironment,
},
}),
}))
}

View file

@ -14,10 +14,24 @@ import (
"go.woodpecker-ci.org/woodpecker/v2/server/forge/gitea"
"go.woodpecker-ci.org/woodpecker/v2/server/forge/github"
"go.woodpecker-ci.org/woodpecker/v2/server/forge/gitlab"
"go.woodpecker-ci.org/woodpecker/v2/server/forge/traced"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
func Forge(forge *model.Forge) (forge.Forge, error) {
func Forge(_forge *model.Forge) (forge.Forge, error) {
f, err := new(_forge)
if err != nil {
return f, err
}
if fr, ok := f.(traced.ForgeRefresher); ok {
return traced.NewForgeRefresherWithTracing(fr, string(_forge.Type)), nil
}
return traced.NewForgeWithTracing(f, string(_forge.Type)), nil
}
func new(forge *model.Forge) (forge.Forge, error) {
switch forge.Type {
case model.ForgeTypeAddon:
return setupAddon(forge)

View file

@ -0,0 +1,22 @@
// Copyright 2024 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package traced
import "go.woodpecker-ci.org/woodpecker/v2/server/forge"
type ForgeRefresher interface {
forge.Forge
forge.Refresher
}

View file

@ -0,0 +1,432 @@
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../templates/opentelemetry.go.tpl
// gowrap: http://github.com/hexdigest/gowrap
package traced
//go:generate gowrap gen -p go.woodpecker-ci.org/woodpecker/v2/server/forge -i Forge -t ../../../templates/opentelemetry.go.tpl -o tracedforge.gen.go -l ""
import (
"context"
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"go.woodpecker-ci.org/woodpecker/v2/server/forge"
"go.woodpecker-ci.org/woodpecker/v2/server/forge/types"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
// ForgeWithTracing implements forge.Forge interface instrumented with opentracing spans
type ForgeWithTracing struct {
forge.Forge
_instance string
_spanDecorator func(span trace.Span, params, results map[string]interface{})
}
// NewForgeWithTracing returns ForgeWithTracing
func NewForgeWithTracing(base forge.Forge, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) ForgeWithTracing {
d := ForgeWithTracing{
Forge: base,
_instance: instance,
}
if len(spanDecorator) > 0 && spanDecorator[0] != nil {
d._spanDecorator = spanDecorator[0]
}
return d
}
// Activate implements forge.Forge
func (_d ForgeWithTracing) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Activate")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"link": link}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Activate(ctx, u, r, link)
}
// Auth implements forge.Forge
func (_d ForgeWithTracing) Auth(ctx context.Context, token string, secret string) (s1 string, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Auth")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"token": token,
"secret": secret}, map[string]interface{}{
"s1": s1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Auth(ctx, token, secret)
}
// BranchHead implements forge.Forge
func (_d ForgeWithTracing) BranchHead(ctx context.Context, u *model.User, r *model.Repo, branch string) (cp1 *model.Commit, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.BranchHead")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"branch": branch}, map[string]interface{}{
"cp1": cp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.BranchHead(ctx, u, r, branch)
}
// Branches implements forge.Forge
func (_d ForgeWithTracing) Branches(ctx context.Context, u *model.User, r *model.Repo, p *model.ListOptions) (sa1 []string, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Branches")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"p": p}, map[string]interface{}{
"sa1": sa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Branches(ctx, u, r, p)
}
// Deactivate implements forge.Forge
func (_d ForgeWithTracing) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Deactivate")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"link": link}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Deactivate(ctx, u, r, link)
}
// Dir implements forge.Forge
func (_d ForgeWithTracing) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) (fpa1 []*types.FileMeta, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Dir")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"b": b,
"f": f}, map[string]interface{}{
"fpa1": fpa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Dir(ctx, u, r, b, f)
}
// File implements forge.Forge
func (_d ForgeWithTracing) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) (ba1 []byte, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.File")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"b": b,
"f": f}, map[string]interface{}{
"ba1": ba1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.File(ctx, u, r, b, f)
}
// Hook implements forge.Forge
func (_d ForgeWithTracing) Hook(ctx context.Context, r *http.Request) (repo *model.Repo, pipeline *model.Pipeline, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Hook")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"r": r}, map[string]interface{}{
"repo": repo,
"pipeline": pipeline,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Hook(ctx, r)
}
// Login implements forge.Forge
func (_d ForgeWithTracing) Login(ctx context.Context, r *types.OAuthRequest) (up1 *model.User, s1 string, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Login")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"r": r}, map[string]interface{}{
"up1": up1,
"s1": s1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Login(ctx, r)
}
// Org implements forge.Forge
func (_d ForgeWithTracing) Org(ctx context.Context, u *model.User, org string) (op1 *model.Org, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Org")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"org": org}, map[string]interface{}{
"op1": op1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Org(ctx, u, org)
}
// OrgMembership implements forge.Forge
func (_d ForgeWithTracing) OrgMembership(ctx context.Context, u *model.User, org string) (op1 *model.OrgPerm, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.OrgMembership")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"org": org}, map[string]interface{}{
"op1": op1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.OrgMembership(ctx, u, org)
}
// PullRequests implements forge.Forge
func (_d ForgeWithTracing) PullRequests(ctx context.Context, u *model.User, r *model.Repo, p *model.ListOptions) (ppa1 []*model.PullRequest, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.PullRequests")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"p": p}, map[string]interface{}{
"ppa1": ppa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.PullRequests(ctx, u, r, p)
}
// Repo implements forge.Forge
func (_d ForgeWithTracing) Repo(ctx context.Context, u *model.User, remoteID model.ForgeRemoteID, owner string, name string) (rp1 *model.Repo, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Repo")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"remoteID": remoteID,
"owner": owner,
"name": name}, map[string]interface{}{
"rp1": rp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Repo(ctx, u, remoteID, owner, name)
}
// Repos implements forge.Forge
func (_d ForgeWithTracing) Repos(ctx context.Context, u *model.User) (rpa1 []*model.Repo, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Repos")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u}, map[string]interface{}{
"rpa1": rpa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Repos(ctx, u)
}
// Status implements forge.Forge
func (_d ForgeWithTracing) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, p *model.Workflow) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Status")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"b": b,
"p": p}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Status(ctx, u, r, b, p)
}
// Teams implements forge.Forge
func (_d ForgeWithTracing) Teams(ctx context.Context, u *model.User) (tpa1 []*model.Team, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "forge.Forge.Teams")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u}, map[string]interface{}{
"tpa1": tpa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Forge.Teams(ctx, u)
}

View file

@ -0,0 +1,454 @@
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../templates/opentelemetry.go.tpl
// gowrap: http://github.com/hexdigest/gowrap
package traced
//go:generate gowrap gen -p go.woodpecker-ci.org/woodpecker/v2/server/forge/traced -i ForgeRefresher -t ../../../templates/opentelemetry.go.tpl -o tracedforgerefresher.gen.go -l ""
import (
"context"
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"go.woodpecker-ci.org/woodpecker/v2/server/forge/types"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
// ForgeRefresherWithTracing implements ForgeRefresher interface instrumented with opentracing spans
type ForgeRefresherWithTracing struct {
ForgeRefresher
_instance string
_spanDecorator func(span trace.Span, params, results map[string]interface{})
}
// NewForgeRefresherWithTracing returns ForgeRefresherWithTracing
func NewForgeRefresherWithTracing(base ForgeRefresher, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) ForgeRefresherWithTracing {
d := ForgeRefresherWithTracing{
ForgeRefresher: base,
_instance: instance,
}
if len(spanDecorator) > 0 && spanDecorator[0] != nil {
d._spanDecorator = spanDecorator[0]
}
return d
}
// Activate implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Activate")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"link": link}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Activate(ctx, u, r, link)
}
// Auth implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Auth(ctx context.Context, token string, secret string) (s1 string, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Auth")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"token": token,
"secret": secret}, map[string]interface{}{
"s1": s1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Auth(ctx, token, secret)
}
// BranchHead implements ForgeRefresher
func (_d ForgeRefresherWithTracing) BranchHead(ctx context.Context, u *model.User, r *model.Repo, branch string) (cp1 *model.Commit, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.BranchHead")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"branch": branch}, map[string]interface{}{
"cp1": cp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.BranchHead(ctx, u, r, branch)
}
// Branches implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Branches(ctx context.Context, u *model.User, r *model.Repo, p *model.ListOptions) (sa1 []string, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Branches")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"p": p}, map[string]interface{}{
"sa1": sa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Branches(ctx, u, r, p)
}
// Deactivate implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Deactivate")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"link": link}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Deactivate(ctx, u, r, link)
}
// Dir implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) (fpa1 []*types.FileMeta, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Dir")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"b": b,
"f": f}, map[string]interface{}{
"fpa1": fpa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Dir(ctx, u, r, b, f)
}
// File implements ForgeRefresher
func (_d ForgeRefresherWithTracing) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) (ba1 []byte, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.File")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"b": b,
"f": f}, map[string]interface{}{
"ba1": ba1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.File(ctx, u, r, b, f)
}
// Hook implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Hook(ctx context.Context, r *http.Request) (repo *model.Repo, pipeline *model.Pipeline, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Hook")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"r": r}, map[string]interface{}{
"repo": repo,
"pipeline": pipeline,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Hook(ctx, r)
}
// Login implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Login(ctx context.Context, r *types.OAuthRequest) (up1 *model.User, s1 string, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Login")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"r": r}, map[string]interface{}{
"up1": up1,
"s1": s1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Login(ctx, r)
}
// Org implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Org(ctx context.Context, u *model.User, org string) (op1 *model.Org, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Org")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"org": org}, map[string]interface{}{
"op1": op1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Org(ctx, u, org)
}
// OrgMembership implements ForgeRefresher
func (_d ForgeRefresherWithTracing) OrgMembership(ctx context.Context, u *model.User, org string) (op1 *model.OrgPerm, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.OrgMembership")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"org": org}, map[string]interface{}{
"op1": op1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.OrgMembership(ctx, u, org)
}
// PullRequests implements ForgeRefresher
func (_d ForgeRefresherWithTracing) PullRequests(ctx context.Context, u *model.User, r *model.Repo, p *model.ListOptions) (ppa1 []*model.PullRequest, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.PullRequests")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"p": p}, map[string]interface{}{
"ppa1": ppa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.PullRequests(ctx, u, r, p)
}
// Refresh implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Refresh(ctx context.Context, up1 *model.User) (b1 bool, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Refresh")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"up1": up1}, map[string]interface{}{
"b1": b1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Refresh(ctx, up1)
}
// Repo implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Repo(ctx context.Context, u *model.User, remoteID model.ForgeRemoteID, owner string, name string) (rp1 *model.Repo, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Repo")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"remoteID": remoteID,
"owner": owner,
"name": name}, map[string]interface{}{
"rp1": rp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Repo(ctx, u, remoteID, owner, name)
}
// Repos implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Repos(ctx context.Context, u *model.User) (rpa1 []*model.Repo, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Repos")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u}, map[string]interface{}{
"rpa1": rpa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Repos(ctx, u)
}
// Status implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, p *model.Workflow) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Status")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u,
"r": r,
"b": b,
"p": p}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Status(ctx, u, r, b, p)
}
// Teams implements ForgeRefresher
func (_d ForgeRefresherWithTracing) Teams(ctx context.Context, u *model.User) (tpa1 []*model.Team, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "ForgeRefresher.Teams")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"u": u}, map[string]interface{}{
"tpa1": tpa1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.ForgeRefresher.Teams(ctx, u)
}

View file

@ -0,0 +1,277 @@
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../templates/opentelemetry.go.tpl
// gowrap: http://github.com/hexdigest/gowrap
package traced
//go:generate gowrap gen -p go.woodpecker-ci.org/woodpecker/v2/server/queue -i Queue -t ../../../templates/opentelemetry.go.tpl -o tracedqueue.gen.go -l ""
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
"go.woodpecker-ci.org/woodpecker/v2/server/queue"
)
// QueueWithTracing implements queue.Queue interface instrumented with opentracing spans
type QueueWithTracing struct {
queue.Queue
_instance string
_spanDecorator func(span trace.Span, params, results map[string]interface{})
}
// NewQueueWithTracing returns QueueWithTracing
func NewQueueWithTracing(base queue.Queue, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) QueueWithTracing {
d := QueueWithTracing{
Queue: base,
_instance: instance,
}
if len(spanDecorator) > 0 && spanDecorator[0] != nil {
d._spanDecorator = spanDecorator[0]
}
return d
}
// Done implements queue.Queue
func (_d QueueWithTracing) Done(ctx context.Context, id string, exitStatus model.StatusValue) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.Done")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id,
"exitStatus": exitStatus}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.Done(ctx, id, exitStatus)
}
// Error implements queue.Queue
func (_d QueueWithTracing) Error(ctx context.Context, id string, e1 error) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.Error")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id,
"e1": e1}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.Error(ctx, id, e1)
}
// ErrorAtOnce implements queue.Queue
func (_d QueueWithTracing) ErrorAtOnce(ctx context.Context, ids []string, e1 error) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.ErrorAtOnce")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"ids": ids,
"e1": e1}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.ErrorAtOnce(ctx, ids, e1)
}
// Evict implements queue.Queue
func (_d QueueWithTracing) Evict(ctx context.Context, id string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.Evict")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.Evict(ctx, id)
}
// EvictAtOnce implements queue.Queue
func (_d QueueWithTracing) EvictAtOnce(ctx context.Context, ids []string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.EvictAtOnce")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"ids": ids}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.EvictAtOnce(ctx, ids)
}
// Extend implements queue.Queue
func (_d QueueWithTracing) Extend(ctx context.Context, id string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.Extend")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.Extend(ctx, id)
}
// Info implements queue.Queue
func (_d QueueWithTracing) Info(ctx context.Context) (i1 queue.InfoT) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.Info")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx}, map[string]interface{}{
"i1": i1})
}
_span.End()
}()
return _d.Queue.Info(ctx)
}
// Poll implements queue.Queue
func (_d QueueWithTracing) Poll(ctx context.Context, agentID int64, f queue.FilterFn) (tp1 *model.Task, err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.Poll")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"agentID": agentID,
"f": f}, map[string]interface{}{
"tp1": tp1,
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.Poll(ctx, agentID, f)
}
// Push implements queue.Queue
func (_d QueueWithTracing) Push(ctx context.Context, task *model.Task) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.Push")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"task": task}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.Push(ctx, task)
}
// PushAtOnce implements queue.Queue
func (_d QueueWithTracing) PushAtOnce(ctx context.Context, tasks []*model.Task) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.PushAtOnce")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"tasks": tasks}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.PushAtOnce(ctx, tasks)
}
// Wait implements queue.Queue
func (_d QueueWithTracing) Wait(ctx context.Context, id string) (err error) {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "queue.Queue.Wait")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, map[string]interface{}{
"ctx": ctx,
"id": id}, map[string]interface{}{
"err": err})
} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
_span.End()
}()
return _d.Queue.Wait(ctx, id)
}

View file

@ -26,6 +26,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
"go.woodpecker-ci.org/woodpecker/v2/server"
"go.woodpecker-ci.org/woodpecker/v2/web"
@ -45,6 +46,9 @@ func (f *prefixFS) Open(name string) (http.File, error) {
// New returns a gin engine to serve the web frontend.
func New() (*gin.Engine, error) {
e := gin.New()
e.Use(otelgin.Middleware("woodpecker"))
var err error
indexHTML, err = parseIndex()
if err != nil {

View file

@ -0,0 +1,53 @@
{{.Import}}
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
{{ $decorator := (or .Vars.DecoratorName (printf "%sWithTracing" .Interface.Name)) }}
// {{$decorator}} implements {{.Interface.Type}} interface instrumented with opentracing spans
type {{$decorator}} struct {
{{.Interface.Type}}
_instance string
_spanDecorator func(span trace.Span, params, results map[string]interface{})
}
// New{{$decorator}} returns {{$decorator}}
func New{{$decorator}} (base {{.Interface.Type}}, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) {{$decorator}} {
d := {{$decorator}} {
{{.Interface.Name}}: base,
_instance: instance,
}
if len(spanDecorator) > 0 && spanDecorator[0] != nil {
d._spanDecorator = spanDecorator[0]
}
return d
}
{{range $method := .Interface.Methods}}
{{if $method.AcceptsContext}}
// {{$method.Name}} implements {{$.Interface.Type}}
func (_d {{$decorator}}) {{$method.Declaration}} {
ctx, _span := otel.Tracer(_d._instance).Start(ctx, "{{$.Interface.Type}}.{{$method.Name}}")
defer func() {
if _d._spanDecorator != nil {
_d._spanDecorator(_span, {{$method.ParamsMap}}, {{$method.ResultsMap}})
}{{- if $method.ReturnsError}} else if err != nil {
_span.RecordError(err)
_span.SetAttributes(
attribute.String("event", "error"),
attribute.String("message", err.Error()),
)
}
{{end}}
_span.End()
}()
{{$method.Pass (printf "_d.%s." $.Interface.Name) }}
}
{{end}}
{{end}}