From e8fcaadf5c85143c4cc04b321ff02325c0e05fc2 Mon Sep 17 00:00:00 2001 From: Rodney Osodo Date: Thu, 17 Oct 2024 02:19:50 +0300 Subject: [PATCH] feat: add LGTM docker stack Signed-off-by: Rodney Osodo --- .golangci.yaml | 3 + docker/Dockerfile => Dockerfile | 0 Makefile | 7 +- calculator/middleware/tracing.go | 11 ++- cmd/main.go | 133 ++++++++++++++++++++++++--- compose.yaml | 135 ++++++++++++++++++++++++++++ go.mod | 19 +++- go.sum | 42 +++++++-- grafana/datasources/datasource.yaml | 45 ++++++++++ loki/loki-config.yaml | 37 ++++++++ prometheus/prometheus.yaml | 15 ++++ pyroscope/pyroscope.yml | 6 ++ 12 files changed, 431 insertions(+), 22 deletions(-) rename docker/Dockerfile => Dockerfile (100%) create mode 100644 compose.yaml create mode 100644 grafana/datasources/datasource.yaml create mode 100644 loki/loki-config.yaml create mode 100644 prometheus/prometheus.yaml create mode 100644 pyroscope/pyroscope.yml diff --git a/.golangci.yaml b/.golangci.yaml index 5ecf10e..023534a 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -13,6 +13,9 @@ linters-settings: - style - experimental - opinionated + disabled-checks: + - hugeParam + - exitAfterDefer linters: enable-all: true diff --git a/docker/Dockerfile b/Dockerfile similarity index 100% rename from docker/Dockerfile rename to Dockerfile diff --git a/Makefile b/Makefile index c65115e..83305b5 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ define make_docker --no-cache \ --tag=$(DOCKER_IMAGE_NAME):$(VERSION) \ --tag=$(DOCKER_IMAGE_NAME):latest \ - -f docker/Dockerfile . + -f Dockerfile . endef define docker_push @@ -48,6 +48,10 @@ docker-push: docker run-binary: @go run cmd/main.go +.PHONY: run-docker +run-docker: + docker compose --env-file .env up + .PHONY: proto proto: @protoc -I. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative calculator/calculator.proto @@ -67,6 +71,7 @@ help: @echo " make docker - Build the docker image" @echo " make docker-push - Push the docker image" @echo " make run-binary - Run the binary" + @echo " make run-docker - Run the docker image" @echo " make proto - Generate protobuf files" @echo " make lint - Lint the code" @echo " make all - Build the binary and docker image" diff --git a/calculator/middleware/tracing.go b/calculator/middleware/tracing.go index 6deefb3..2a5f6a3 100644 --- a/calculator/middleware/tracing.go +++ b/calculator/middleware/tracing.go @@ -15,7 +15,7 @@ type tracing struct { svc calculator.Service } -func Tracing(svc calculator.Service, tracer trace.Tracer) calculator.Service { +func Tracing(tracer trace.Tracer, svc calculator.Service) calculator.Service { return &tracing{tracer, svc} } @@ -44,12 +44,15 @@ func (t *tracing) Divide(ctx context.Context, a, b int64) (result int64, err err } func (t *tracing) trace(ctx context.Context, name string, a, b, result int64, err error) { - _, span := t.tracer.Start(ctx, name, trace.WithAttributes( + attributes := []attribute.KeyValue{ attribute.Int64("a", a), attribute.Int64("b", b), attribute.Int64("result", result), - attribute.String("error", err.Error()), - )) + } + if err != nil { + attributes = append(attributes, attribute.String("error", err.Error())) + } + _, span := t.tracer.Start(ctx, name, trace.WithAttributes(attributes...)) span.End() } diff --git a/cmd/main.go b/cmd/main.go index edd7065..7ba9efa 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -6,37 +6,53 @@ import ( "log/slog" "net" "net/http" + "net/url" "os" "time" "github.com/caarlos0/env/v11" + "github.com/grafana/pyroscope-go" "github.com/hashicorp/go-retryablehttp" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/rodneyosodo/gophercon/calculator" "github.com/rodneyosodo/gophercon/calculator/api" "github.com/rodneyosodo/gophercon/calculator/middleware" + slogloki "github.com/samber/slog-loki" + slogmulti "github.com/samber/slog-multi" + "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/exporters/prometheus" + "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.17.0" + "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/reflection" "google.golang.org/grpc/stats/opentelemetry" ) -const defHTTPTimeout = 10 * time.Second - type config struct { LogLevel string `env:"GOPHERCON_LOG_LEVEL" envDefault:"info"` Addr string `env:"GOPHERCON_ADDR" envDefault:":11211"` - PrometheusEndpoint string `env:"GOPHERCON_PROMETHEUS_ENDPOINT" envDefault:":9464"` + PrometheusEndpoint string `env:"GOPHERCON_PROMETHEUS_ENDPOINT" envDefault:":11212"` ReadTimeout time.Duration `env:"GOPHERCON_READ_TIMEOUT" envDefault:"10s"` WriteTimeout time.Duration `env:"GOPHERCON_WRITE_TIMEOUT" envDefault:"10s"` + OTELURL url.URL `env:"GOPHERCON_OTEL_URL" envDefault:""` + TraceRatio float64 `env:"GOPHERCON_TRACE_RATIO" envDefault:"0.1"` + LokiURL string `env:"GOPHERCON_LOKI_URL" envDefault:""` + PyroScopeURL string `env:"GOPHERCON_PYROSCOPE_URL" envDefault:""` } func main() { ctx, cancel := context.WithCancel(context.Background()) - var g *errgroup.Group - g, _ = errgroup.WithContext(ctx) + g, ctx := errgroup.WithContext(ctx) cfg := config{} if err := env.Parse(&cfg); err != nil { @@ -47,12 +63,65 @@ func main() { if err := level.UnmarshalText([]byte(cfg.LogLevel)); err != nil { log.Fatalf("failed to parse log level: %s", err.Error()) } - logHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ - Level: level, - }) - logger := slog.New(logHandler) + fanout := slogmulti.Fanout( + slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + Level: level, + }), + ) + if cfg.LokiURL != "" { + hander := slogloki.Option{Level: level, Endpoint: cfg.LokiURL}.NewLokiHandler() + fanout = slogmulti.Fanout( + slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + Level: level, + }), + hander, + ) + } + + logger := slog.New(fanout) slog.SetDefault(logger) + if cfg.PyroScopeURL != "" { + if _, err := pyroscope.Start(pyroscope.Config{ + ApplicationName: "gophercon", + ServerAddress: cfg.PyroScopeURL, + Logger: nil, + ProfileTypes: []pyroscope.ProfileType{ + pyroscope.ProfileCPU, + pyroscope.ProfileAllocObjects, + pyroscope.ProfileAllocSpace, + pyroscope.ProfileInuseObjects, + pyroscope.ProfileInuseSpace, + pyroscope.ProfileGoroutines, + pyroscope.ProfileMutexCount, + }, + }); err != nil { + logger.Error("failed to start pyroscope", slog.Any("error", err)) + os.Exit(1) + } + } + + var tp trace.TracerProvider + switch { + case cfg.OTELURL == (url.URL{}): + tp = noop.NewTracerProvider() + default: + sdktp, err := initTracer(ctx, cfg.OTELURL, cfg.TraceRatio) + if err != nil { + logger.Error("failed to initialize opentelemetry", slog.Any("error", err)) + os.Exit(1) + + return + } + defer func() { + if err := sdktp.Shutdown(ctx); err != nil { + logger.Error("error shutting down tracer provider", slog.Any("error", err)) + } + }() + tp = sdktp + } + tracer := tp.Tracer("gophercon") + exporter, err := prometheus.New() if err != nil { logger.Error("Failed to start prometheus exporter", slog.String("error", err.Error())) @@ -84,7 +153,7 @@ func main() { os.Exit(1) } - server := grpc.NewServer(so) + server := grpc.NewServer(so, grpc.StatsHandler(otelgrpc.NewServerHandler())) reflection.Register(server) retryClient := retryablehttp.NewClient() @@ -94,6 +163,7 @@ func main() { service := calculator.NewService(httpClient) service = middleware.Logging(logger, service) + service = middleware.Tracing(tracer, service) calculator.RegisterCalculatorServer(server, api.NewGrpcServer(service)) g.Go(func() error { @@ -108,3 +178,46 @@ func main() { os.Exit(1) } } + +func initTracer(ctx context.Context, otelURL url.URL, fraction float64) (*sdktrace.TracerProvider, error) { + options := []otlptracehttp.Option{ + otlptracehttp.WithEndpoint(otelURL.Host), otlptracehttp.WithURLPath(otelURL.Path), + } + + var client otlptrace.Client + switch otelURL.Scheme { + case "http": + options = append(options, otlptracehttp.WithInsecure()) + client = otlptracehttp.NewClient(options...) + case "https": + client = otlptracehttp.NewClient(options...) + } + + exporter, err := otlptrace.New(ctx, client) + if err != nil { + return nil, err + } + + attributes := []attribute.KeyValue{ + semconv.ServiceNameKey.String("gophercon"), + } + + hostAttr, err := resource.New(ctx, resource.WithHost(), resource.WithOSDescription(), resource.WithContainer()) + if err != nil { + return nil, err + } + attributes = append(attributes, hostAttr.Attributes()...) + + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.TraceIDRatioBased(fraction)), + sdktrace.WithBatcher(exporter), + sdktrace.WithResource(resource.NewWithAttributes( + semconv.SchemaURL, + attributes..., + )), + ) + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + + return tp, nil +} diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..00efea1 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,135 @@ +name: gophercon + +networks: + gophercon-net: + driver: bridge + +volumes: + prometheus-volume: + +services: + gophercon: + image: ghcr.io/rodneyosodo/gophercon:latest + container_name: gophercon + restart: unless-stopped + ports: + - ${GOPHERCON_PORT}:${GOPHERCON_PORT} + - ${GOPHERCON_PROMETHEUS_PORT}:${GOPHERCON_PROMETHEUS_PORT} + expose: + - ${GOPHERCON_PORT} + - ${GOPHERCON_PROMETHEUS_PORT} + networks: + - gophercon-net + environment: + GOPHERCON_LOG_LEVEL: ${GOPHERCON_LOG_LEVEL} + GOPHERCON_ADDR: ${GOPHERCON_ADDR} + GOPHERCON_PROMETHEUS_ENDPOINT: ${GOPHERCON_PROMETHEUS_ENDPOINT} + GOPHERCON_READ_TIMEOUT: ${GOPHERCON_READ_TIMEOUT} + GOPHERCON_WRITE_TIMEOUT: ${GOPHERCON_WRITE_TIMEOUT} + GOPHERCON_OTEL_URL: ${GOPHERCON_OTEL_URL} + GOPHERCON_TRACE_RATIO: ${GOPHERCON_TRACE_RATIO} + GOPHERCON_LOKI_URL: ${GOPHERCON_LOKI_URL} + GOPHERCON_PYROSCOPE_URL: ${GOPHERCON_PYROSCOPE_URL} + + loki: + image: grafana/loki:2.9.8 + container_name: loki + restart: on-failure + ports: + - ${LOKI_PORT}:${LOKI_PORT} + command: "-config.file=/etc/loki/config.yaml -target=all" + volumes: + - ./loki/loki-config.yaml:/etc/loki/config.yaml + networks: + - gophercon-net + + prometheus: + image: prom/prometheus:v2.54.1 + container_name: prometheus + restart: on-failure + command: + - --web.enable-remote-write-receiver + - --enable-feature=native-histograms + - --config.file=/etc/prometheus/prometheus.yml + ports: + - ${PROMETHEUS_PORT}:${PROMETHEUS_PORT} + networks: + - gophercon-net + volumes: + - type: bind + source: ./prometheus/prometheus.yaml + target: /etc/prometheus/prometheus.yml + - prometheus-volume:/prometheus + + tempo: + image: grafana/tempo:2.6.0 + container_name: tempo + restart: on-failure + command: + - "-storage.trace.backend=local" + - "-storage.trace.local.path=/tmp/tempo/traces" + - "-storage.trace.wal.path=/tmp/tempo/wal" + - "-auth.enabled=false" + - "-server.http-listen-port=3200" + ports: + - "3200:3200" + - "4317:4317" + - "4318:4318" + networks: + - gophercon-net + + grafana: + image: grafana/grafana:11.2.0 + container_name: grafana + restart: on-failure + depends_on: + - prometheus + ports: + - ${GRAFANA_PORT}:${GRAFANA_PORT} + environment: + - GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER} + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD} + volumes: + - ./grafana:/etc/grafana/provisioning/ + networks: + - gophercon-net + + agent: + image: grafana/agent:latest + container_name: agent + restart: on-failure + volumes: + - "./contrib/agent-local.river:/grafana-agent.river:Z" + - "${DOCKER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock" + command: + ["run", "/grafana-agent.river", "--server.http.listen-addr=0.0.0.0:12345"] + ports: + - "12345:12345" + environment: + AGENT_MODE: flow + QUICKPIZZA_HOST: quickpizza:3333 + METRICS_ENDPOINT: http://prometheus:9090/api/v1/write + TRACES_ENDPOINT: http://tempo:4317 + LOGS_ENDPOINT: http://loki:3100/loki/api/v1/push + depends_on: + - prometheus + - gophercon + - tempo + networks: + - gophercon-net + + pyroscope: + image: grafana/pyroscope:latest + container_name: pyroscope + restart: on-failure + environment: + JAEGER_AGENT_HOST: tempo + JAEGER_SAMPLER_TYPE: const + JAEGER_SAMPLER_PARAM: 1 + command: ["-config.file=/etc/pyroscope.yml"] + ports: + - "4040:4040" + volumes: + - ./pyroscope/pyroscope.yml:/etc/pyroscope.yml + networks: + - gophercon-net diff --git a/go.mod b/go.mod index 3eb1c3a..4db8af0 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,17 @@ go 1.23.2 require ( github.com/caarlos0/env/v11 v11.2.2 + github.com/grafana/pyroscope-go v1.2.0 github.com/hashicorp/go-retryablehttp v0.7.7 github.com/prometheus/client_golang v1.20.5 + github.com/samber/slog-loki v1.0.0 + github.com/samber/slog-multi v1.2.3 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 go.opentelemetry.io/otel v1.31.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 go.opentelemetry.io/otel/exporters/prometheus v0.53.0 + go.opentelemetry.io/otel/sdk v1.31.0 go.opentelemetry.io/otel/sdk/metric v1.31.0 go.opentelemetry.io/otel/trace v1.31.0 golang.org/x/sync v0.8.0 @@ -17,21 +24,31 @@ require ( ) require ( + github.com/afiskon/promtail-client v0.0.0-20190305142237-506f3f921e9c // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect + github.com/samber/lo v1.47.0 // indirect go.opentelemetry.io/otel/metric v1.31.0 // indirect - go.opentelemetry.io/otel/sdk v1.31.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect ) diff --git a/go.sum b/go.sum index 9fbafed..0c23517 100644 --- a/go.sum +++ b/go.sum @@ -2,18 +2,22 @@ cel.dev/expr v0.16.1 h1:NR0+oFYzR1CqLFhTAqg3ql59G9VfN8fKq1TCHJ6gq1g= cel.dev/expr v0.16.1/go.mod h1:AsGA5zb3WruAEQeQng1RZdGEXmBj0jvMWh6l5SnNuC8= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +github.com/afiskon/promtail-client v0.0.0-20190305142237-506f3f921e9c h1:AMDVOKGaiqse4qiRXSzRgpC9DCNTHCx6zpzdtXXrKM4= +github.com/afiskon/promtail-client v0.0.0-20190305142237-506f3f921e9c/go.mod h1:p/7Wos+jcfrnwLqqzJMZ0s323kfVtJPW+HUvAANklVQ= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/caarlos0/env/v11 v11.2.2 h1:95fApNrUyueipoZN/EhA8mMxiNxrBwDa+oAZrMWl3Kg= github.com/caarlos0/env/v11 v11.2.2/go.mod h1:JBfcdeQiBoI3Zh1QRAWfe+tpiNTmDtcCj/hHHHMx0vc= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= -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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.13.0 h1:HzkeUz1Knt+3bK+8LG1bxOO/jzWZmdxpwC51i202les= github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8= github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= @@ -25,10 +29,20 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/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/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grafana/pyroscope-go v1.2.0 h1:aILLKjTj8CS8f/24OPMGPewQSYlhmdQMBmol1d3KGj8= +github.com/grafana/pyroscope-go v1.2.0/go.mod h1:2GHr28Nr05bg2pElS+dDsc98f3JTUh2f6Fz1hWXrqwk= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= @@ -47,8 +61,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= -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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= @@ -57,10 +71,24 @@ github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJN github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/samber/slog-loki v1.0.0 h1:T/Dv0LlCfFEEi2PDzpxJgQeoFxAvjCnriItaBGgNT6s= +github.com/samber/slog-loki v1.0.0/go.mod h1:7FpVL6ECdmstVLDogUDE7tLdyEIjW/B/u0+ctPmYzd0= +github.com/samber/slog-multi v1.2.3 h1:np8YoAZbGP699xA92SYZxs7zzKpL1/yBYk6q8/caXpc= +github.com/samber/slog-multi v1.2.3/go.mod h1:ACuZ5B6heK57TfMVkVknN2UZHoFfjCwRxR0Q2OXKHlo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 h1:yMkBS9yViCc7U7yeLzJPM2XizlfdVvBRSmsQDWu6qc0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0/go.mod h1:n8MR6/liuGB5EmTETUBeU5ZgqMOlqKRxUaqPQBOANZ8= go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= go.opentelemetry.io/otel/exporters/prometheus v0.53.0 h1:QXobPHrwiGLM4ufrY3EOmDPJpo2P90UuFau4CDPJA/I= go.opentelemetry.io/otel/exporters/prometheus v0.53.0/go.mod h1:WOAXGr3D00CfzmFxtTV1eR0GpoHuPEu+HJT8UWW2SIU= go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= @@ -71,6 +99,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= @@ -81,8 +111,8 @@ golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= diff --git a/grafana/datasources/datasource.yaml b/grafana/datasources/datasource.yaml new file mode 100644 index 0000000..fb40408 --- /dev/null +++ b/grafana/datasources/datasource.yaml @@ -0,0 +1,45 @@ +apiVersion: 1 + +datasources: + - name: prometheus + type: prometheus + access: proxy + orgId: 1 + url: http://prometheus:9090 + basicAuth: false + isDefault: true + jsonData: + tlsAuth: false + tlsAuthWithCACert: false + editable: false + + - name: Tempo + type: tempo + access: proxy + orgId: 1 + url: http://tempo:3200 + basicAuth: false + isDefault: false + version: 1 + editable: false + apiVersion: 1 + uid: tempo + + - name: Pyroscope + type: "phlare" + access: "proxy" + orgId: 1 + uid: pyroscope + url: http://pyroscope:4040 + isDefault: false + editable: false + + - name: Loki + type: loki + access: proxy + orgId: 1 + url: http://loki:3100 + basicAuth: false + isDefault: false + version: 1 + editable: false diff --git a/loki/loki-config.yaml b/loki/loki-config.yaml new file mode 100644 index 0000000..7fff6f0 --- /dev/null +++ b/loki/loki-config.yaml @@ -0,0 +1,37 @@ +auth_enabled: false + +server: + http_listen_port: 3100 + grpc_listen_port: 9096 + +common: + instance_addr: 127.0.0.1 + path_prefix: /tmp/loki + storage: + filesystem: + chunks_directory: /tmp/loki/chunks + rules_directory: /tmp/loki/rules + replication_factor: 1 + ring: + kvstore: + store: inmemory + +query_range: + results_cache: + cache: + embedded_cache: + enabled: true + max_size_mb: 100 + +schema_config: + configs: + - from: 2024-01-01 + store: tsdb + object_store: filesystem + schema: v13 + index: + prefix: index_ + period: 24h + +analytics: + reporting_enabled: false diff --git a/prometheus/prometheus.yaml b/prometheus/prometheus.yaml new file mode 100644 index 0000000..7061ddf --- /dev/null +++ b/prometheus/prometheus.yaml @@ -0,0 +1,15 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: "twiga" + honor_timestamps: true + scrape_interval: 15s + scrape_timeout: 10s + metrics_path: / + follow_redirects: true + enable_http2: true + static_configs: + - targets: + - gophercon:11212 diff --git a/pyroscope/pyroscope.yml b/pyroscope/pyroscope.yml new file mode 100644 index 0000000..4741c7b --- /dev/null +++ b/pyroscope/pyroscope.yml @@ -0,0 +1,6 @@ +tracing: + enabled: true + profiling_enabled: true + +pyroscopedb: + max_block_duration: 5m