diff --git a/.dockerignore b/.dockerignore index 6f359f7..d6cf9c3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -48,3 +48,5 @@ environments/ *.swp *.swo .DS_Store + +config/VERSION.txt \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0e5251b..b55af1f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ !.example.env !/bruno/environments/dev.bru !.gitkeep -/tigerbeetle_api \ No newline at end of file +/tigerbeetle_api +/config/VERSION.txt \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index c14391c..7ffdd3b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,6 +17,9 @@ COPY . . # Enable CGO and specify the Zig compiler ENV CGO_ENABLED=1 CC="zig cc" # Build the Go application +RUN --mount=type=cache,target=/go/pkg/mod \ + --mount=type=cache,target=/root/.cache/go-build \ + go generate ./... RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ go build -o tigerbeetle_api . diff --git a/grpc/config.go b/config/config.go similarity index 95% rename from grpc/config.go rename to config/config.go index 080810d..a4ef18f 100644 --- a/grpc/config.go +++ b/config/config.go @@ -1,6 +1,7 @@ -package grpc +package config import ( + "fmt" "log/slog" "os" "strconv" @@ -103,5 +104,8 @@ func NewConfig() (ok bool) { PrometheusAddr: prometheusAddr, } + + slog.Info(fmt.Sprintf("%+v", Config)) + slog.Info("Config loaded", "version", version) return true } diff --git a/grpc/config_test.go b/config/config_test.go similarity index 98% rename from grpc/config_test.go rename to config/config_test.go index fc07b79..1797ad9 100644 --- a/grpc/config_test.go +++ b/config/config_test.go @@ -1,4 +1,4 @@ -package grpc +package config import ( "os" diff --git a/config/version.go b/config/version.go new file mode 100644 index 0000000..dfcb647 --- /dev/null +++ b/config/version.go @@ -0,0 +1,7 @@ +package config + +import _ "embed" + +//go:generate sh -c "printf %s $(git rev-parse HEAD) > VERSION.txt" +//go:embed VERSION.txt +var version string diff --git a/grpc/routes.go b/grpc/routes.go index c1f8709..733c274 100644 --- a/grpc/routes.go +++ b/grpc/routes.go @@ -8,6 +8,7 @@ import ( "os" "github.com/charithe/timedbuf/v2" + "github.com/lil5/tigerbeetle_api/config" "github.com/lil5/tigerbeetle_api/metrics" "github.com/lil5/tigerbeetle_api/proto" "github.com/samber/lo" @@ -40,8 +41,8 @@ type App struct { } func (a *App) getRandomTBuf() *timedbuf.TimedBuf[TimedPayload] { - if Config.BufferCluster > 1 { - i := rand.IntN(Config.BufferCluster - 1) + if config.Config.BufferCluster > 1 { + i := rand.IntN(config.Config.BufferCluster - 1) return a.TBufs[i] } else { return a.TBuf @@ -58,7 +59,7 @@ func (a *App) Close() { const TB_MAX_BATCH_SIZE = 8190 func NewApp() *App { - tigerbeetle_go, err := tigerbeetle_go.NewClient(types.Uint128{uint8(Config.TbClusterID)}, Config.TbAddresses) + tigerbeetle_go, err := tigerbeetle_go.NewClient(types.Uint128{uint8(config.Config.TbClusterID)}, config.Config.TbAddresses) if err != nil { slog.Error("unable to connect to tigerbeetle", "err", err) os.Exit(1) @@ -66,11 +67,13 @@ func NewApp() *App { var tbuf *timedbuf.TimedBuf[TimedPayload] var tbufs []*timedbuf.TimedBuf[TimedPayload] - if Config.IsBuffered { - tbufs = make([]*timedbuf.TimedBuf[TimedPayload], Config.BufferCluster) + if config.Config.IsBuffered { + tbufs = make([]*timedbuf.TimedBuf[TimedPayload], config.Config.BufferCluster) // The maximum batch size is set in the TigerBeetle server. The default is 8190. - lenMaxBuf := float64(Config.BufferSize) + bufSizeFull := float64(config.Config.BufferSize) + bufSize80 := bufSizeFull * 0.8 + flushFunc := func(payloads []TimedPayload) { transfers := []types.Transfer{} lenPayloads := float64(len(payloads)) @@ -89,8 +92,13 @@ func NewApp() *App { payloads[isOverflowMaxTransferSizeIndex].buf.Put(payloads[isOverflowMaxTransferSizeIndex:]...) } metrics.TotalBufferCount.Inc() - metrics.TotalBufferContents.Add(lenPayloads) - metrics.TotalBufferMax.Add(lenMaxBuf) + if lenPayloads == bufSizeFull { + metrics.TotalBufferContentsFull.Inc() + } else if lenPayloads >= bufSize80 { + metrics.TotalBufferContentsGt80.Inc() + } else { + metrics.TotalBufferContentsLt80.Inc() + } metrics.TotalCreateTransferTx.Add(float64(len(transfers))) metrics.TotalTbCreateTransfersCall.Inc() results, err := tigerbeetle_go.CreateTransfers(transfers) @@ -104,8 +112,8 @@ func NewApp() *App { payload.c <- res } } - for i := range Config.BufferCluster { - tbufs[i] = timedbuf.New(Config.BufferSize, Config.BufferDelay, flushFunc) + for i := range config.Config.BufferCluster { + tbufs[i] = timedbuf.New(config.Config.BufferSize, config.Config.BufferDelay, flushFunc) } tbuf = tbufs[0] } @@ -231,7 +239,7 @@ func (s *App) CreateTransfers(ctx context.Context, in *proto.CreateTransfersRequ var err error var replies []*proto.CreateTransfersReplyItem - if Config.IsBuffered { + if config.Config.IsBuffered { buf := s.getRandomTBuf() c := make(chan TimedPayloadResponse) buf.Put(TimedPayload{ diff --git a/grpc/server.go b/grpc/server.go index d2391c7..d55bcd6 100644 --- a/grpc/server.go +++ b/grpc/server.go @@ -6,6 +6,7 @@ import ( "net" "os" + "github.com/lil5/tigerbeetle_api/config" "github.com/lil5/tigerbeetle_api/metrics" "github.com/lil5/tigerbeetle_api/proto" "github.com/prometheus/client_golang/prometheus" @@ -19,10 +20,10 @@ import ( func NewServer() { networkType := "tcp" - if Config.OnlyIpv4 { + if config.Config.OnlyIpv4 { networkType = "ipv4" } - lis, err := net.Listen(networkType, fmt.Sprintf("%s:%s", Config.Host, Config.Port)) + lis, err := net.Listen(networkType, fmt.Sprintf("%s:%s", config.Config.Host, config.Config.Port)) if err != nil { slog.Error("Failed to listen", "error", err) os.Exit(1) @@ -32,17 +33,17 @@ func NewServer() { defer app.Close() proto.RegisterTigerBeetleServer(s, app) - if Config.GrpcHealthServer { + if config.Config.GrpcHealthServer { healthServer := health.NewServer() healthpb.RegisterHealthServer(s, healthServer) healthServer.SetServingStatus("tigerbeetle.TigerBeetle", healthpb.HealthCheckResponse_SERVING) } - if Config.GrpcReflection { + if config.Config.GrpcReflection { reflection.Register(s) } - prometheusDeferClose := metrics.Register(Config.PrometheusAddr) + prometheusDeferClose := metrics.Register(config.Config.PrometheusAddr) defer prometheusDeferClose() srvMetrics := grpcprom.NewServerMetrics(grpcprom.WithServerHandlingTimeHistogram( grpcprom.WithHistogramBuckets([]float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}), diff --git a/main.go b/main.go index 9dfb07f..8da2561 100644 --- a/main.go +++ b/main.go @@ -4,16 +4,18 @@ import ( "os" "github.com/joho/godotenv" + "github.com/lil5/tigerbeetle_api/config" "github.com/lil5/tigerbeetle_api/grpc" "github.com/lil5/tigerbeetle_api/rest" ) func main() { godotenv.Load() - if ok := grpc.NewConfig(); !ok { + if ok := config.NewConfig(); !ok { os.Exit(1) } - if grpc.Config.UseGrpc { + // log add version + if config.Config.UseGrpc { grpc.NewServer() } else { rest.NewServer() diff --git a/metrics/counters.go b/metrics/counters.go index 839a525..d3de34c 100644 --- a/metrics/counters.go +++ b/metrics/counters.go @@ -6,19 +6,22 @@ import ( ) var ( - TotalBufferContents = promauto.NewCounter(prometheus.CounterOpts{ - Name: "tigerbeetleapi_buffer_contents_total", - Help: "Tigerbeetle requests buffered filled size sum", + TotalBufferContentsFull = promauto.NewCounter(prometheus.CounterOpts{ + Name: "tigerbeetleapi_buffer_contents_full_total", + Help: "Tigerbeetle buffer filled size is full", }) - - TotalBufferMax = promauto.NewCounter(prometheus.CounterOpts{ - Name: "tigerbeetleapi_buffer_max_total", - Help: "Tigerbeetle requests buffer max size sum", + TotalBufferContentsLt80 = promauto.NewCounter(prometheus.CounterOpts{ + Name: "tigerbeetleapi_buffer_contents_lt80_total", + Help: "Tigerbeetle buffer filled size is less than 80%", + }) + TotalBufferContentsGt80 = promauto.NewCounter(prometheus.CounterOpts{ + Name: "tigerbeetleapi_buffer_contents_gte80_total", + Help: "Tigerbeetle buffer filled size is greater than or equal to 80%", }) TotalBufferCount = promauto.NewCounter(prometheus.CounterOpts{ Name: "tigerbeetleapi_buffer_count_total", - Help: "Tigerbeetle requests total buffers", + Help: "Tigerbeetle requests total buffer instances created", }) TotalCreateTransferTx = promauto.NewCounter(prometheus.CounterOpts{ diff --git a/rest/server.go b/rest/server.go index 483c461..079175b 100644 --- a/rest/server.go +++ b/rest/server.go @@ -9,6 +9,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/lil5/tigerbeetle_api/config" "github.com/lil5/tigerbeetle_api/grpc" "github.com/lil5/tigerbeetle_api/metrics" @@ -18,12 +19,12 @@ import ( ) func NewServer() { - if grpc.Config.Mode != "development" { + if config.Config.Mode != "development" { gin.SetMode(gin.ReleaseMode) } r, app := Router() defer app.Close() - slog.Info("Rest server listening at", "host", grpc.Config.Host, "port", grpc.Config.Port) + slog.Info("Rest server listening at", "host", config.Config.Host, "port", config.Config.Port) defer slog.Info("Server exiting") mdlw := middleware.New(middleware.Config{ @@ -31,11 +32,11 @@ func NewServer() { }) r.Use(ginmiddleware.Handler("", mdlw)) - prometheusDeferClose := metrics.Register(grpc.Config.PrometheusAddr) + prometheusDeferClose := metrics.Register(config.Config.PrometheusAddr) defer prometheusDeferClose() - addr := fmt.Sprintf("%s:%s", grpc.Config.Host, grpc.Config.Port) - if grpc.Config.OnlyIpv4 { + addr := fmt.Sprintf("%s:%s", config.Config.Host, config.Config.Port) + if config.Config.OnlyIpv4 { server := &http.Server{Handler: r} l, err := net.Listen("tcp4", addr) if err != nil { diff --git a/suite_e2e_test.go b/suite_e2e_test.go index 8fe7b76..3c8b8f0 100644 --- a/suite_e2e_test.go +++ b/suite_e2e_test.go @@ -16,6 +16,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/lil5/tigerbeetle_api/config" "github.com/lil5/tigerbeetle_api/grpc" "github.com/lil5/tigerbeetle_api/rest" "github.com/stretchr/testify/suite" @@ -56,7 +57,7 @@ func (s *MyTestSuite) SetupSuite() { os.Setenv("TB_ADDRESSES", TB_ADDRESSES) os.Setenv("TB_CLUSTER_ID", TB_CLUSTER_ID) - if ok := grpc.NewConfig(); !ok { + if ok := config.NewConfig(); !ok { s.FailNow("SetupSuite failed to initialize creating configuration") return }