fix bug when no child tracer created

This commit is contained in:
Sergey Chubaryan 2024-09-02 21:24:57 +03:00
parent 2c1abf5a7f
commit ea967a5608
7 changed files with 86 additions and 24 deletions

30
deploy/grafana-ds.yaml Normal file
View File

@ -0,0 +1,30 @@
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
uid: prometheus
access: proxy
orgId: 1
url: http://prometheus:9090
basicAuth: false
isDefault: false
version: 1
editable: false
jsonData:
httpMethod: GET
- name: Tempo
type: tempo
access: proxy
orgId: 1
url: http://tempo:3200
basicAuth: false
isDefault: true
version: 1
editable: false
apiVersion: 1
uid: tempo
jsonData:
httpMethod: GET
serviceMap:
datasourceUid: prometheus

View File

@ -18,6 +18,7 @@ services:
- "host.docker.internal:host-gateway"
volumes:
- grafana-volume:/var/lib/grafana
- ./deploy/grafana-ds.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
prometheus:
image: prom/prometheus:v2.54.0

View File

@ -24,7 +24,8 @@ import (
"time"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/sdk/trace"
traceSdk "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/trace"
)
type App struct{}
@ -105,6 +106,24 @@ func (a *App) Run(p RunParams) {
}
}
var tracer trace.Tracer
{
tracerExporter, err := otlptracehttp.New(context.Background(), otlptracehttp.WithEndpointURL("http://localhost:4318"))
if err != nil {
logger.Fatal().Err(err).Msg("failed initializing tracer")
}
tracerProvider := traceSdk.NewTracerProvider(
traceSdk.WithSampler(traceSdk.AlwaysSample()),
traceSdk.WithBatcher(
tracerExporter,
traceSdk.WithMaxQueueSize(4096),
traceSdk.WithMaxExportBatchSize(1024),
),
)
tracer = tracerProvider.Tracer("backend")
}
// Build business-logic objects
var (
userService services.UserService
@ -115,7 +134,7 @@ func (a *App) Run(p RunParams) {
jwtUtil = utils.NewJwtUtil(key)
passwordUtil = utils.NewPasswordUtil()
userRepo = repos.NewUserRepo(sqlDb)
userRepo = repos.NewUserRepo(sqlDb, tracer)
emailRepo = repos.NewEmailRepo()
actionTokenRepo = repos.NewActionTokenRepo(sqlDb)
@ -163,17 +182,6 @@ func (a *App) Run(p RunParams) {
clientNotifier := client_notifier.NewBasicNotifier()
tracerExporter, err := otlptracehttp.New(context.Background(), otlptracehttp.WithEndpointURL("http://localhost:4318"))
if err != nil {
logger.Fatal().Err(err).Msg("failed initializing tracer")
}
tracerProvider := trace.NewTracerProvider(
trace.WithSampler(trace.AlwaysSample()),
trace.WithBatcher(tracerExporter),
)
tracer := tracerProvider.Tracer("backend")
// Start profiling
if args.GetProfilePath() != "" {
pprofFile, err := os.Create(args.GetProfilePath())

View File

@ -6,6 +6,8 @@ import (
"context"
"database/sql"
"errors"
"go.opentelemetry.io/otel/trace"
)
// type userDAO struct {
@ -22,15 +24,19 @@ type UserRepo interface {
GetUserByEmail(ctx context.Context, login string) (*models.UserDTO, error)
}
func NewUserRepo(db integrations.SqlDB) UserRepo {
return &userRepo{db}
func NewUserRepo(db integrations.SqlDB, tracer trace.Tracer) UserRepo {
return &userRepo{db, tracer}
}
type userRepo struct {
db integrations.SqlDB
db integrations.SqlDB
tracer trace.Tracer
}
func (u *userRepo) CreateUser(ctx context.Context, dto models.UserDTO) (*models.UserDTO, error) {
_, span := u.tracer.Start(ctx, "postgres")
defer span.End()
query := `insert into users (email, secret, name) values ($1, $2, $3) returning id;`
row := u.db.QueryRowContext(ctx, query, dto.Email, dto.Secret, dto.Name)
@ -48,6 +54,9 @@ func (u *userRepo) CreateUser(ctx context.Context, dto models.UserDTO) (*models.
}
func (u *userRepo) UpdateUser(ctx context.Context, userId string, dto models.UserUpdateDTO) error {
_, span := u.tracer.Start(ctx, "postgres")
defer span.End()
query := `update users set secret=$1, name=$2 where id = $3;`
_, err := u.db.ExecContext(ctx, query, dto.Secret, dto.Name, userId)
if err != nil {
@ -58,6 +67,9 @@ func (u *userRepo) UpdateUser(ctx context.Context, userId string, dto models.Use
}
func (u *userRepo) GetUserById(ctx context.Context, id string) (*models.UserDTO, error) {
_, span := u.tracer.Start(ctx, "postgres")
defer span.End()
query := `select id, email, secret, name from users where id = $1;`
row := u.db.QueryRowContext(ctx, query, id)
@ -74,6 +86,9 @@ func (u *userRepo) GetUserById(ctx context.Context, id string) (*models.UserDTO,
}
func (u *userRepo) GetUserByEmail(ctx context.Context, login string) (*models.UserDTO, error) {
_, span := u.tracer.Start(ctx, "postgres")
defer span.End()
query := `select id, email, secret, name from users where email = $1;`
row := u.db.QueryRowContext(ctx, query, login)

View File

@ -7,7 +7,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
@ -16,15 +15,11 @@ func NewRequestLogMiddleware(logger log.Logger, tracer trace.Tracer, prometheus
prometheus.RequestInc()
defer prometheus.RequestDec()
_, span := tracer.Start(c.Request.Context(), c.Request.URL.Path)
defer span.End()
requestId := c.GetHeader("X-Request-Id")
if requestId == "" {
requestId = uuid.New().String()
}
span.SetAttributes(attribute.String("requestId", c.ClientIP()))
log.SetCtxRequestId(c, requestId)
path := c.Request.URL.Path

View File

@ -2,16 +2,26 @@ package middleware
import (
"github.com/gin-gonic/gin"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
)
func NewTracingMiddleware(tracer trace.Tracer) gin.HandlerFunc {
prop := otel.GetTextMapPropagator()
return func(c *gin.Context) {
_, span := tracer.Start(c.Request.Context(), c.Request.URL.Path)
savedCtx := c.Request.Context()
defer func() {
c.Request = c.Request.WithContext(savedCtx)
}()
ctx := prop.Extract(savedCtx, propagation.HeaderCarrier(c.Request.Header))
ctx, span := tracer.Start(ctx, c.Request.URL.Path)
defer span.End()
span.SetAttributes(attribute.String("requestId", c.ClientIP()))
c.Request = c.Request.WithContext(ctx)
c.Next()
}

View File

@ -35,6 +35,8 @@ func New(opts NewServerOpts) *Server {
}
r := gin.New()
r.ContextWithFallback = true // Use it to allow getting values from c.Request.Context()
r.Static("/webapp", "./webapp")
r.GET("/health", handlers.NewDummyHandler())
@ -43,6 +45,7 @@ func New(opts NewServerOpts) *Server {
r.Use(middleware.NewRecoveryMiddleware(opts.Logger, prometheus, opts.DebugMode))
r.Use(middleware.NewRequestLogMiddleware(opts.Logger, opts.Tracer, prometheus))
r.Use(middleware.NewTracingMiddleware(opts.Tracer))
r.GET("/pooling", handlers.NewLongPoolingHandler(opts.Logger, opts.Notifier))