Files
lijiaoqiao/platform-token-runtime/internal/app/bootstrap.go
Your Name e249a9160b P3-C: 三服务可观测面统一 - metrics端点统一/健康检查别名/traceID透传
Gateway:
- remote_runtime.go: P3-C-08 从请求上下文透传 X-Request-Id 到 platform-token-runtime

Supply-api:
- 新建 internal/metrics/metrics.go: HTTP请求计数/latency/token发布/worker queue指标 (Prometheus-text)
- 新建 internal/metrics/metrics_test.go: 6个测试覆盖
- bootstrap.go: 注册 /metrics (P3-C-01/04)、/health、/healthz 别名 (P3-C-05)

Platform-token-runtime:
- bootstrap.go: 添加 /health 和 /livez 别名 (P3-C-05)

三服务 /metrics 统一为 text/plain; version=0.0.4
三服务 /health 端点统一别名
Gateway → platform-token-runtime 透传 trace ID
2026-04-21 18:40:43 +08:00

129 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package app
import (
"context"
"fmt"
"net/http"
"strings"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"lijiaoqiao/platform-token-runtime/internal/auth/service"
"lijiaoqiao/platform-token-runtime/internal/httpapi"
met "lijiaoqiao/platform-token-runtime/internal/metrics"
)
type Config struct {
Addr string
Env string
RuntimeStore service.RuntimeStore
AuditStore service.AuditStore
Now func() time.Time
}
var newPostgresStoreBundle = func(ctx context.Context, databaseURL string) (service.RuntimeStore, service.AuditStore, func(), error) {
if ctx == nil {
ctx = context.Background()
}
pool, err := pgxpool.New(ctx, strings.TrimSpace(databaseURL))
if err != nil {
return nil, nil, nil, err
}
if err := pool.Ping(ctx); err != nil {
pool.Close()
return nil, nil, nil, err
}
return service.NewPostgresRuntimeStore(pool), service.NewPostgresAuditStore(pool), pool.Close, nil
}
func BuildPostgresStores(ctx context.Context, databaseURL string) (service.RuntimeStore, service.AuditStore, func(), error) {
if strings.TrimSpace(databaseURL) == "" {
return nil, nil, nil, fmt.Errorf("token runtime database url is required")
}
return newPostgresStoreBundle(ctx, databaseURL)
}
func BuildRuntime(cfg Config) (*service.InMemoryTokenRuntime, service.AuditStore, error) {
now := cfg.Now
if now == nil {
now = time.Now
}
env := strings.ToLower(strings.TrimSpace(cfg.Env))
runtimeStore := cfg.RuntimeStore
auditStore := cfg.AuditStore
switch env {
case "", "dev":
if runtimeStore == nil {
runtimeStore = service.NewInMemoryRuntimeStore()
}
if auditStore == nil {
auditStore = service.NewMemoryAuditStore()
}
case "prod", "staging":
if runtimeStore == nil {
return nil, nil, fmt.Errorf("runtime store is required in %s", env)
}
if auditStore == nil {
return nil, nil, fmt.Errorf("audit store is required in %s", env)
}
default:
return nil, nil, fmt.Errorf("unsupported TOKEN_RUNTIME_ENV %q", cfg.Env)
}
return service.NewInMemoryTokenRuntimeWithStore(now, runtimeStore), auditStore, nil
}
func BuildServer(cfg Config) (*http.Server, error) {
now := cfg.Now
if now == nil {
now = time.Now
}
addr := strings.TrimSpace(cfg.Addr)
if addr == "" {
addr = ":18081"
}
runtime, auditor, err := BuildRuntime(cfg)
if err != nil {
return nil, err
}
api := httpapi.NewTokenAPI(runtime, auditor, now)
mux := http.NewServeMux()
mux.HandleFunc("/actuator/health", func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"status":"UP"}`))
})
// P3-C-05: /health 和 /livez 别名(统一路径,对齐 gateway/supply-api
mux.HandleFunc("/health", func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"status":"UP"}`))
})
mux.HandleFunc("/livez", func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"status":"UP"}`))
})
// P3-B: /metrics 端点Prometheus-text 格式)
mux.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; version=0.0.4")
_, _ = w.Write([]byte(met.Export()))
})
api.Register(mux)
return &http.Server{
Addr: addr,
Handler: mux,
ReadHeaderTimeout: 5 * time.Second,
ReadTimeout: 10 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 30 * time.Second,
}, nil
}