Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion server/.air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ tmp_dir = "tmp"

[build]
# execute command
cmd = "go build -o ./tmp/api ./cmd/reearth"
cmd = "go build -ldflags=\"-X main.version=0.0.1\" -o ./tmp/api ./cmd/reearth"
bin = "tmp/api"
full_bin = "tmp/api"
delay = 1000 # ms
Expand Down
4 changes: 2 additions & 2 deletions server/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ e2e:
# =======================

build:
go build ./cmd/reearth
go build -ldflags="-X main.version=0.0.1" ./cmd/reearth

dev: dev-install
air

run-app:
go run ./cmd/reearth
go run -ldflags="-X main.version=0.0.1" ./cmd/reearth

clean:
go clean -modcache
Expand Down
2 changes: 1 addition & 1 deletion server/cmd/reearth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package main

import "github.com/reearth/reearth/server/internal/app"

var version = ""
var version = "" // set via -ldflags at build time

func main() {
app.Start(debug, version)
Expand Down
4 changes: 2 additions & 2 deletions server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/oklog/ulid/v2 v2.1.1
github.com/pkg/errors v0.9.1
github.com/ravilushqa/otelgqlgen v0.17.0
github.com/reearth/orb v0.0.0-20250123044717-f6f70ce16355
github.com/reearth/reearthx v0.0.0-20250923165051-5bd6f1c10f7a
github.com/samber/lo v1.50.0
Expand All @@ -50,6 +49,7 @@ require (
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0
go.opentelemetry.io/otel v1.35.0
go.opentelemetry.io/otel/sdk v1.35.0
go.opentelemetry.io/otel/trace v1.35.0
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b
golang.org/x/net v0.40.0
golang.org/x/oauth2 v0.28.0
Expand Down Expand Up @@ -144,6 +144,7 @@ require (
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ravilushqa/otelgqlgen v0.17.0 // indirect
github.com/rs/cors v1.11.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sanity-io/litter v1.5.5 // indirect
Expand Down Expand Up @@ -176,7 +177,6 @@ require (
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
Expand Down
95 changes: 95 additions & 0 deletions server/internal/adapter/middleware/rest_tracer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package middleware

import (
"net/http"

echo "github.com/labstack/echo/v4"
"github.com/reearth/reearthx/log"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)

func RestAPITracingMiddleware() echo.MiddlewareFunc {
tracer := otel.Tracer("reearth-visualizer")

return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
req := c.Request()
ctx := req.Context()

routePath := c.Path()
actualPath := req.URL.Path
path := routePath
if path == "" {
path = actualPath
}
if req.Method == "OPTIONS" || actualPath == "/favicon.ico" {
return next(c)
}

spanName := req.Method + " " + path
ctx, span := tracer.Start(ctx, spanName,
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(
attribute.String("component", "rest"),
attribute.String("http.route", path),
attribute.String("http.path", actualPath),
attribute.String("http.method", req.Method),
attribute.String("http.url", req.URL.Path),
attribute.String("http.host", req.Host),
attribute.String("http.scheme", req.URL.Scheme),
),
)
defer span.End()

if query := req.URL.Query(); len(query) > 0 {
queryCount := 0
for key := range query {
span.SetAttributes(attribute.String("http.query."+key, "present"))
queryCount++
}
span.SetAttributes(attribute.Int("http.query.count", queryCount))
}

paramNames := c.ParamNames()
if len(paramNames) > 0 {
for _, paramName := range paramNames {
paramValue := c.Param(paramName)
if paramValue != "" {
span.SetAttributes(attribute.String("http.param."+paramName, paramValue))
}
}
}

c.SetRequest(req.WithContext(ctx))

err := next(c)

status := c.Response().Status
if status == 0 {
status = 200
}

span.SetAttributes(
attribute.Int("http.status_code", status),
attribute.Int64("http.response.size", c.Response().Size),
)

if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
log.Warnfc(ctx, "rest: %s %s failed with error: %v", req.Method, path, err)
} else if status >= 400 {
span.SetStatus(codes.Error, http.StatusText(status))
log.Warnfc(ctx, "rest: %s %s returned status %d", req.Method, path, status)
} else {
span.SetStatus(codes.Ok, "Request completed successfully")
log.Infofc(ctx, "rest: %s %s completed successfully (status=%d)", req.Method, path, status)
}

return err
}
}
}
3 changes: 2 additions & 1 deletion server/internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func initEcho(ctx context.Context, cfg *ServerConfig) *echo.Echo {
e.Logger = logger
e.Use(
middleware.Recover(),
otelecho.Middleware("reearth"),
otelecho.Middleware("reearth-visualizer"),
appmiddleware.RestAPITracingMiddleware(), // Add detailed REST API tracing
echo.WrapMiddleware(appx.RequestIDMiddleware()),
logger.AccessLogger(),
middleware.Gzip(),
Expand Down
4 changes: 2 additions & 2 deletions server/internal/app/auth_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (

var ErrInvalidEmailORPassword = errors.New("wrong email or password")

func authServer(ctx context.Context, e *echo.Echo, cfg *config.AuthSrvConfig, repos *repo.Container) {
func authServer(ctx context.Context, ec *echo.Echo, cfg *config.AuthSrvConfig, repos *repo.Container) {
if cfg.Disabled {
return
}
Expand All @@ -33,7 +33,7 @@ func authServer(ctx context.Context, e *echo.Echo, cfg *config.AuthSrvConfig, re
UserRepo: &authServerUser{User: repos.User},
ConfigRepo: &authServerConfig{Config: repos.Config},
RequestRepo: repos.AuthRequest,
}, e.Group(""))
}, ec.Group(""))
}

type authServerUser struct {
Expand Down
2 changes: 1 addition & 1 deletion server/internal/app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Config struct {
GCPProject string `envconfig:"GOOGLE_CLOUD_PROJECT" pp:",omitempty"`
Profiler string `pp:",omitempty"`
Tracer string `pp:",omitempty"`
TracerSample float64 `default:"0.01" pp:",omitempty"`
TracerSample float64 `default:"0.01" envconfig:"REEARTH_TRACER_SAMPLE" pp:",omitempty"`
Marketplace MarketplaceConfig `pp:",omitempty"`
AssetBaseURL string `default:"http://localhost:8080/assets"`
Origins []string `pp:",omitempty"`
Expand Down
21 changes: 18 additions & 3 deletions server/internal/app/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/99designs/gqlgen/graphql/handler/lru"
"github.com/99designs/gqlgen/graphql/handler/transport"
"github.com/labstack/echo/v4"
"github.com/ravilushqa/otelgqlgen"
"github.com/reearth/reearth/server/internal/adapter"
"github.com/reearth/reearth/server/internal/adapter/gql"
"github.com/reearth/reearth/server/internal/app/config"
Expand All @@ -20,6 +19,9 @@ import (
"github.com/reearth/reearthx/log"
"github.com/vektah/gqlparser/v2/ast"
"github.com/vektah/gqlparser/v2/gqlerror"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"golang.org/x/text/language"
)

Expand Down Expand Up @@ -59,8 +61,10 @@ func GraphqlAPI(conf config.GraphQLConfig, dev bool) echo.HandlerFunc {
srv.Use(extension.FixedComplexityLimit(conf.ComplexityLimit))
}

// tracing
srv.Use(otelgqlgen.Middleware())
// tracing with detailed operation tracking
srv.AroundOperations(detailedOperationTracer())
srv.AroundResponses(responseTracer())
// srv.AroundFields(fieldTracer())

srv.SetErrorPresenter(func(ctx context.Context, e error) *gqlerror.Error {
defer func() {
Expand All @@ -80,6 +84,17 @@ func GraphqlAPI(conf config.GraphQLConfig, dev bool) echo.HandlerFunc {
return func(c echo.Context) error {
req := c.Request()
ctx := req.Context()
tracer := otel.Tracer("reearth-visualizer")
ctx, span := tracer.Start(ctx, "GraphQL Handler",
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(
attribute.String("component", "graphql"),
attribute.String("http.method", req.Method),
attribute.String("http.url", req.URL.Path),
attribute.String("handler", "graphql"),
),
)
defer span.End()

usecases := adapter.Usecases(ctx)
ctx = gql.AttachUsecases(ctx, usecases, enableDataLoaders)
Expand Down
4 changes: 2 additions & 2 deletions server/internal/app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

func Start(debug bool, version string) {
log.Infof("reearth %s", version)
log.Infof("Re:Earth Visualizer API version %s", version)

ctx := context.Background()

Expand All @@ -32,7 +32,7 @@ func Start(debug bool, version string) {
initProfiler(conf.Profiler, version)

// Init tracer
closer := initTracer(ctx, conf)
closer := initTracer(ctx, conf, version)
defer func() {
if closer != nil {
if err := closer.Close(); err != nil {
Expand Down
Loading