@@ -3,12 +3,14 @@ package main
33import (
44 "context"
55 "log"
6- "net/http"
7- "os"
6+ "time"
87
98 _ "apprun/docs" // Swagger docs (自动生成)
10- internalConfig "apprun/internal/config"
119 "apprun/modules/config"
10+ "apprun/pkg/database"
11+ "apprun/pkg/env"
12+ "apprun/pkg/logger"
13+ "apprun/pkg/server"
1214 "apprun/routes"
1315
1416 _ "github.com/lib/pq"
@@ -25,31 +27,57 @@ import (
2527// @license.name Apache 2.0
2628// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
2729
30+ // @host localhost:8080
2831// @BasePath /api
2932
3033// @schemes http https
3134func main () {
32- ctx := context .Background ()
33-
34- // 创建配置引导器
35- bootstrap := config .NewBootstrap (getEnv ("CONFIG_DIR" , "./config" ))
35+ // Recover from panics during startup (e.g., missing required environment variables)
36+ defer func () {
37+ if r := recover (); r != nil {
38+ log .Fatalf ("❌ Startup failed: %v" , r )
39+ }
40+ }()
41+
42+ // Phase 0: Load infrastructure config from file to environment variables
43+ // This allows default.yaml to provide defaults while respecting existing env vars
44+ // Priority: runtime env > config file > code defaults
45+ configDir := env .Get ("CONFIG_DIR" , "./config" )
46+ if err := env .LoadConfigToEnv (configDir ); err != nil {
47+ log .Printf ("⚠️ Warning: Failed to load config file: %v" , err )
48+ log .Println ("⚠️ Using environment variables and code defaults only" )
49+ }
3650
37- // 1. 加载初始配置
38- cfg , err := bootstrap .LoadInitialConfig (ctx )
39- if err != nil {
40- log .Fatalf ("❌ Failed to load initial config: %v" , err )
51+ // Create context with timeout for startup phase
52+ ctx , cancel := context .WithTimeout (context .Background (), 30 * time .Second )
53+ defer cancel ()
54+
55+ // Phase 1: Initialize Configuration Module Registry
56+ // Register business module configurations for centralized management
57+ // Note: Infrastructure configs (server, database) are NOT registered here
58+ // They are managed via environment variables loaded in Phase 0
59+ registry := config .NewRegistry ()
60+ if err := registry .Register ("logger" , & logger.Config {}); err != nil {
61+ log .Fatalf ("❌ Failed to register logger config: %v" , err )
4162 }
42- log .Printf ("✅ Config loaded: %s v%s" , cfg . App . Name , cfg . App . Version )
63+ log .Println ("✅ Logger module registered with config center" )
4364
44- // 2. 初始化数据库
45- dbClient , err := bootstrap .InitDatabase (ctx , cfg )
65+ // Create configuration bootstrapper with registry
66+ bootstrap := config .NewBootstrapWithRegistry (env .Get ("CONFIG_DIR" , "./config" ), registry )
67+
68+ // Phase 2: Connect to Database (Layer 1 infrastructure)
69+ // Database connection is required for config service and business logic
70+ // Note: DB_PASSWORD environment variable is required (set via Phase 0 or export)
71+ dbCfg := database .DefaultConfig ()
72+ dbClient , err := database .Connect (ctx , dbCfg )
4673 if err != nil {
47- log .Fatalf ("❌ Failed to initialize database: %v" , err )
74+ log .Fatalf ("❌ Failed to connect to database: %v" , err )
4875 }
4976 defer dbClient .Close ()
5077 log .Println ("✅ Database connected" )
5178
52- // 3. 创建配置服务
79+ // Phase 3: Initialize Config Service (Layer 2 - Configuration Center)
80+ // Config service manages runtime configurations stored in database
5381 configService , err := bootstrap .CreateService (ctx , dbClient )
5482 if err != nil {
5583 log .Printf ("⚠️ Warning: Failed to create config service: %v" , err )
@@ -58,56 +86,55 @@ func main() {
5886 log .Println ("✅ Config service initialized with DB support" )
5987 }
6088
61- // 4. 设置路由
62- router := routes .SetupRoutes (configService )
63-
64- // 5. 启动服务器
65- startServer (router , cfg )
66- }
67-
68- // startServer 启动 HTTP/HTTPS 服务器
69- func startServer (router http.Handler , cfg * internalConfig.Config ) {
70- // 获取 TLS 配置
71- sslCertFile := os .Getenv ("SSL_CERT_FILE" )
72- sslKeyFile := os .Getenv ("SSL_KEY_FILE" )
73- httpPort := getEnv ("SERVER_PORT" , "8080" )
74- httpsPort := getEnv ("HTTPS_PORT" , "8443" )
75-
76- // 检查是否启用 TLS
77- if sslCertFile != "" && sslKeyFile != "" {
78- // 启动 HTTPS 服务器
79- log .Printf ("🔒 Starting HTTPS server on :%s" , httpsPort )
80- log .Printf ("📄 Using certificate: %s" , sslCertFile )
81-
82- // 同时启动 HTTP 服务器(用于健康检查和可能的重定向)
83- go func () {
84- httpAddr := ":" + httpPort
85- log .Printf ("🌐 Starting HTTP server on %s (for health checks)" , httpAddr )
86- if err := http .ListenAndServe (httpAddr , router ); err != nil {
87- log .Fatalf ("HTTP server failed: %v" , err )
88- }
89- }()
90-
91- // 启动 HTTPS 服务器
92- httpsAddr := ":" + httpsPort
93- if err := http .ListenAndServeTLS (httpsAddr , sslCertFile , sslKeyFile , router ); err != nil {
94- log .Fatalf ("HTTPS server failed: %v" , err )
95- }
89+ // Phase 4: Initialize Business Logger (Layer 2 - Runtime Logger)
90+ // Business logger is used for application runtime logging (request handling, business logic)
91+ // Startup logs continue using standard log package (this is still bootstrap phase)
92+ loggerCfg := logger.Config {
93+ Level : logger .LevelInfo , // Default level, can be overridden by config service
94+ Output : logger.OutputConfig {
95+ Targets : []string {"stdout" },
96+ },
97+ }
98+ // TODO: Load logger config from config service in future iterations
99+ // For now, use default config for business logger initialization
100+ businessLogger , err := logger .NewZapLogger (loggerCfg )
101+ if err != nil {
102+ log .Printf ("⚠️ Warning: Failed to initialize business logger: %v" , err )
103+ log .Println ("⚠️ Using NopLogger (no-op) for runtime logging" )
104+ // Fallback to NopLogger if initialization fails
96105 } else {
97- // 仅启动 HTTP 服务器
98- addr := ":" + httpPort
99- log .Printf ("🌐 Starting HTTP server on %s" , addr )
100- log .Printf ("💡 Tip: Set SSL_CERT_FILE and SSL_KEY_FILE to enable HTTPS" )
101- if err := http .ListenAndServe (addr , router ); err != nil {
102- log .Fatalf ("HTTP server failed: %v" , err )
103- }
106+ logger .SetLogger (businessLogger )
107+ defer businessLogger .Close ()
108+ log .Println ("✅ Business logger initialized (runtime logging ready)" )
104109 }
105- }
106110
107- // getEnv 获取环境变量,如果不存在则返回默认值
108- func getEnv (key , defaultValue string ) string {
109- if value := os .Getenv (key ); value != "" {
110- return value
111+ // Phase 5: Setup HTTP Routes
112+ // Register all HTTP handlers and middleware
113+ router := routes .SetupRoutes (configService )
114+ log .Println ("✅ HTTP routes configured" )
115+
116+ // Phase 6: Configure HTTP/HTTPS Server
117+ // Server configuration is automatically loaded from environment variables by DefaultConfig()
118+ // Environment variables are set in Phase 0 by LoadConfigToEnv() from default.yaml
119+ // Naming convention: SERVER_HTTP_PORT, SERVER_HTTPS_PORT, SERVER_SSL_CERT_FILE, etc.
120+ serverCfg := server .DefaultConfig ()
121+
122+ // Print startup summary (still using standard log - bootstrap phase)
123+ log .Println ("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" )
124+ log .Println ("🚀 AppRun Server Starting..." )
125+ log .Printf (" Database: %s@%s:%d/%s" , dbCfg .User , dbCfg .Host , dbCfg .Port , dbCfg .DBName )
126+ log .Printf (" HTTP Port: %s" , serverCfg .HTTPPort )
127+ if serverCfg .SSLCertFile != "" {
128+ log .Printf (" HTTPS Port: %s (TLS Enabled)" , serverCfg .HTTPSPort )
129+ }
130+ log .Printf (" Config Dir: %s" , env .Get ("CONFIG_DIR" , "./config" ))
131+ log .Printf (" Logger Level: %s" , loggerCfg .Level )
132+ log .Println ("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" )
133+ log .Println ("📝 Note: Using standard log for startup, business logger for runtime" )
134+
135+ // Phase 7: Start HTTP/HTTPS Server (enters runtime phase)
136+ // From this point, handlers will use logger.L() for business logging
137+ if err := server .Start (router , serverCfg ); err != nil {
138+ log .Fatalf ("❌ Server failed: %v" , err )
111139 }
112- return defaultValue
113140}
0 commit comments