From b506d8ec5f98a4602a1afaa841d6b3af6e799810 Mon Sep 17 00:00:00 2001 From: Jin Hai Date: Tue, 14 Jul 2026 22:20:26 +0800 Subject: [PATCH] Go: add more frameworks (#16915) ### Summary 1. Add hooks for server init 2. Add hooks for router init 3. Add jaeger and otel related config Signed-off-by: Jin Hai --- cmd/ragflow_server.go | 6 ++++ conf/service_conf.yaml | 6 ++++ docker/.env | 9 ++++++ docker/docker-compose-base.yml | 15 ++++++++++ docker/service_conf.yaml.template | 6 ++++ internal/admin/router.go | 3 ++ internal/admin/router_ee.go | 23 ++++++++++++++++ internal/common/number.go | 10 ++++++- internal/router/router.go | 3 ++ internal/router/router_ee.go | 23 ++++++++++++++++ internal/server/config.go | 9 ++++++ internal/server/server_ee.go | 46 +++++++++++++++++++++++++++++++ 12 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 internal/admin/router_ee.go create mode 100644 internal/router/router_ee.go create mode 100644 internal/server/server_ee.go diff --git a/cmd/ragflow_server.go b/cmd/ragflow_server.go index 83575597f8..ddd326b5b7 100644 --- a/cmd/ragflow_server.go +++ b/cmd/ragflow_server.go @@ -368,6 +368,12 @@ func main() { common.Warn("Failed to initialize server variables from Redis, using defaults", zap.String("error", err.Error())) } + if err = server.StartServer(); err != nil { + common.Error("Failed to start EE server", err) + os.Exit(1) + } + defer server.ShutdownServer() + if arguments.name == nil { arguments.name = &serverName } diff --git a/conf/service_conf.yaml b/conf/service_conf.yaml index 6e6e480145..8b20da26db 100644 --- a/conf/service_conf.yaml +++ b/conf/service_conf.yaml @@ -51,6 +51,12 @@ redis: nats: host: "localhost" port: 4222 +otel: + host: "localhost" + port: 4318 + secure: false + sample_ratio: 1.0 + stdout: true task_executor: message_queue_type: 'nats' file_syncer: diff --git a/docker/.env b/docker/.env index c90859b0f9..cfb19b635c 100644 --- a/docker/.env +++ b/docker/.env @@ -148,6 +148,15 @@ REDIS_PASSWORD=infini_rag_flow NATS_HOST=nats NATS_PORT=4222 +# Jaeger (distributed tracing) +# Enable by adding `jaeger` to COMPOSE_PROFILES, e.g.: +# COMPOSE_PROFILES=${COMPOSE_PROFILES},jaeger +# Then update otel.host in service_conf.yaml to "jaeger". +JAEGER_VERSION=2.19.0 +JAEGER_OTLP_GRPC_PORT=4317 +JAEGER_OTLP_HTTP_PORT=4318 +JAEGER_UI_PORT=16686 + # The port used to expose RAGFlow's HTTP API service to the host machine, # allowing EXTERNAL access to the service running inside the Docker container. SVR_WEB_HTTP_PORT=80 diff --git a/docker/docker-compose-base.yml b/docker/docker-compose-base.yml index a2654cf733..5ec2c571e5 100644 --- a/docker/docker-compose-base.yml +++ b/docker/docker-compose-base.yml @@ -270,6 +270,21 @@ services: timeout: 10s retries: 30 + jaeger: + profiles: + - jaeger + image: jaegertracing/jaeger:${JAEGER_VERSION:-2.19.0} + ports: + - ${JAEGER_OTLP_GRPC_PORT:-4317}:4317 + - ${JAEGER_OTLP_HTTP_PORT:-4318}:4318 + - ${JAEGER_UI_PORT:-16686}:16686 + env_file: .env + environment: + - COLLECTOR_OTLP_ENABLED=true + networks: + - ragflow + restart: unless-stopped + tei-cpu: profiles: - tei-cpu diff --git a/docker/service_conf.yaml.template b/docker/service_conf.yaml.template index b2668f74de..2805a7fa64 100644 --- a/docker/service_conf.yaml.template +++ b/docker/service_conf.yaml.template @@ -63,6 +63,12 @@ redis: nats: host: ${NATS_HOST:-0.0.0.0} port: ${NATS_PORT:-4222} +otel: + host: ${OTEL_HOST:-0.0.0.0} + port: ${OTEL_PORT:-4318} + secure: false + sample_ratio: 1.0 + stdout: false task_executor: message_queue_type: 'nats' file_syncer: diff --git a/internal/admin/router.go b/internal/admin/router.go index 48293553a8..7f380cabe9 100644 --- a/internal/admin/router.go +++ b/internal/admin/router.go @@ -34,6 +34,9 @@ func NewRouter(handler *Handler) *Router { // Setup setup routes func (r *Router) Setup(engine *gin.Engine) { + + SetupEERouter(engine) + // Healthz to get system health engine.GET("/healthz", r.handler.Healthz) engine.GET("/", r.handler.Live) diff --git a/internal/admin/router_ee.go b/internal/admin/router_ee.go new file mode 100644 index 0000000000..c0b321f3b2 --- /dev/null +++ b/internal/admin/router_ee.go @@ -0,0 +1,23 @@ +// +// Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +// +// 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 admin + +import "github.com/gin-gonic/gin" + +func SetupEERouter(engine *gin.Engine) { + +} diff --git a/internal/common/number.go b/internal/common/number.go index e1043efc8b..b735b47af4 100644 --- a/internal/common/number.go +++ b/internal/common/number.go @@ -16,7 +16,10 @@ package common -import "strconv" +import ( + "math" + "strconv" +) // PyFloat64 is a float64 that serializes to JSON using the same format as Python's json.dumps. // Python uses the "shortest unique representation" algorithm (dtoa) for float64, @@ -171,3 +174,8 @@ func IsZeroVector(v []float64) bool { } return true } + +func AlmostEqual64(a, b float64) bool { + const epsilon = 1e-9 + return math.Abs(a-b) <= epsilon +} diff --git a/internal/router/router.go b/internal/router/router.go index ae3ae6a29e..a2896006e6 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -122,6 +122,9 @@ func NewRouter( // Setup setup routes func (r *Router) Setup(engine *gin.Engine) { + + SetupEERouter(engine) + // Mark all responses from Go with a header for debugging. engine.Use(func(c *gin.Context) { c.Header("X-API-Source", "go") diff --git a/internal/router/router_ee.go b/internal/router/router_ee.go new file mode 100644 index 0000000000..35e07292f6 --- /dev/null +++ b/internal/router/router_ee.go @@ -0,0 +1,23 @@ +// +// Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +// +// 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 router + +import "github.com/gin-gonic/gin" + +func SetupEERouter(engine *gin.Engine) { + +} diff --git a/internal/server/config.go b/internal/server/config.go index bf5385257b..36a31823ba 100644 --- a/internal/server/config.go +++ b/internal/server/config.go @@ -53,6 +53,7 @@ type Config struct { Language string `mapstructure:"language"` TaskExecutor TaskExecutorConfig `mapstructure:"task_executor"` FileSyncer FileSyncerConfig `mapstructure:"file_syncer"` + OTel OtelConfig `mapstructure:"otel"` } // AdminConfig admin server configuration @@ -81,6 +82,14 @@ type FileSyncerConfig struct { SyncInterval int `mapstructure:"sync_interval"` } +type OtelConfig struct { + Host string `mapstructure:"host"` + Port int `mapstructure:"port"` + SampleRatio float64 `mapstructure:"sample_ratio"` + Secure bool `mapstructure:"secure"` + Stdout bool `mapstructure:"stdout"` +} + // UserDefaultLLMConfig user default LLM configuration type UserDefaultLLMConfig struct { DefaultModels DefaultModelsConfig `mapstructure:"default_models"` diff --git a/internal/server/server_ee.go b/internal/server/server_ee.go new file mode 100644 index 0000000000..32c896cdaa --- /dev/null +++ b/internal/server/server_ee.go @@ -0,0 +1,46 @@ +// +// Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +// +// 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 server + +import "errors" + +var serverEE *EEServer + +func init() { + serverEE = newEEServer() +} + +type EEServer struct { +} + +func newEEServer() *EEServer { + return &EEServer{} +} + +func StartServer() error { + if serverEE == nil { + return errors.New("server EE is nil") + } + return nil +} + +func ShutdownServer() error { + if serverEE == nil { + return errors.New("server EE is nil") + } + return nil +}