refactor: simplify log format

This commit is contained in:
tinkle-community
2025-12-08 02:13:58 +08:00
parent a12c0ae8c9
commit d780c2a988
2 changed files with 75 additions and 72 deletions
+39 -57
View File
@@ -348,22 +348,22 @@ func (s *Server) getTraderFromQuery(c *gin.Context) (*manager.TraderManager, str
// AI trader management related structures // AI trader management related structures
type CreateTraderRequest struct { type CreateTraderRequest struct {
Name string `json:"name" binding:"required"` Name string `json:"name" binding:"required"`
AIModelID string `json:"ai_model_id" binding:"required"` AIModelID string `json:"ai_model_id" binding:"required"`
ExchangeID string `json:"exchange_id" binding:"required"` ExchangeID string `json:"exchange_id" binding:"required"`
StrategyID string `json:"strategy_id"` // Strategy ID (new version) StrategyID string `json:"strategy_id"` // Strategy ID (new version)
InitialBalance float64 `json:"initial_balance"` InitialBalance float64 `json:"initial_balance"`
ScanIntervalMinutes int `json:"scan_interval_minutes"` ScanIntervalMinutes int `json:"scan_interval_minutes"`
IsCrossMargin *bool `json:"is_cross_margin"` // Pointer type, nil means use default value true IsCrossMargin *bool `json:"is_cross_margin"` // Pointer type, nil means use default value true
// The following fields are kept for backward compatibility, new version uses strategy config // The following fields are kept for backward compatibility, new version uses strategy config
BTCETHLeverage int `json:"btc_eth_leverage"` BTCETHLeverage int `json:"btc_eth_leverage"`
AltcoinLeverage int `json:"altcoin_leverage"` AltcoinLeverage int `json:"altcoin_leverage"`
TradingSymbols string `json:"trading_symbols"` TradingSymbols string `json:"trading_symbols"`
CustomPrompt string `json:"custom_prompt"` CustomPrompt string `json:"custom_prompt"`
OverrideBasePrompt bool `json:"override_base_prompt"` OverrideBasePrompt bool `json:"override_base_prompt"`
SystemPromptTemplate string `json:"system_prompt_template"` // System prompt template name SystemPromptTemplate string `json:"system_prompt_template"` // System prompt template name
UseCoinPool bool `json:"use_coin_pool"` UseCoinPool bool `json:"use_coin_pool"`
UseOITop bool `json:"use_oi_top"` UseOITop bool `json:"use_oi_top"`
} }
type ModelConfig struct { type ModelConfig struct {
@@ -381,8 +381,8 @@ type SafeModelConfig struct {
Name string `json:"name"` Name string `json:"name"`
Provider string `json:"provider"` Provider string `json:"provider"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
CustomAPIURL string `json:"customApiUrl"` // Custom API URL (usually not sensitive) CustomAPIURL string `json:"customApiUrl"` // Custom API URL (usually not sensitive)
CustomModelName string `json:"customModelName"` // Custom model name (not sensitive) CustomModelName string `json:"customModelName"` // Custom model name (not sensitive)
} }
type ExchangeConfig struct { type ExchangeConfig struct {
@@ -403,8 +403,8 @@ type SafeExchangeConfig struct {
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
Testnet bool `json:"testnet,omitempty"` Testnet bool `json:"testnet,omitempty"`
HyperliquidWalletAddr string `json:"hyperliquidWalletAddr"` // Hyperliquid wallet address (not sensitive) HyperliquidWalletAddr string `json:"hyperliquidWalletAddr"` // Hyperliquid wallet address (not sensitive)
AsterUser string `json:"asterUser"` // Aster username (not sensitive) AsterUser string `json:"asterUser"` // Aster username (not sensitive)
AsterSigner string `json:"asterSigner"` // Aster signer (not sensitive) AsterSigner string `json:"asterSigner"` // Aster signer (not sensitive)
} }
type UpdateModelConfigRequest struct { type UpdateModelConfigRequest struct {
@@ -584,8 +584,8 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
Name: req.Name, Name: req.Name,
AIModelID: req.AIModelID, AIModelID: req.AIModelID,
ExchangeID: req.ExchangeID, ExchangeID: req.ExchangeID,
StrategyID: req.StrategyID, // Associated strategy ID (new version) StrategyID: req.StrategyID, // Associated strategy ID (new version)
InitialBalance: actualBalance, // Use actual queried balance InitialBalance: actualBalance, // Use actual queried balance
BTCETHLeverage: btcEthLeverage, BTCETHLeverage: btcEthLeverage,
AltcoinLeverage: altcoinLeverage, AltcoinLeverage: altcoinLeverage,
TradingSymbols: req.TradingSymbols, TradingSymbols: req.TradingSymbols,
@@ -630,20 +630,20 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
// UpdateTraderRequest Update trader request // UpdateTraderRequest Update trader request
type UpdateTraderRequest struct { type UpdateTraderRequest struct {
Name string `json:"name" binding:"required"` Name string `json:"name" binding:"required"`
AIModelID string `json:"ai_model_id" binding:"required"` AIModelID string `json:"ai_model_id" binding:"required"`
ExchangeID string `json:"exchange_id" binding:"required"` ExchangeID string `json:"exchange_id" binding:"required"`
StrategyID string `json:"strategy_id"` // Strategy ID (new version) StrategyID string `json:"strategy_id"` // Strategy ID (new version)
InitialBalance float64 `json:"initial_balance"` InitialBalance float64 `json:"initial_balance"`
ScanIntervalMinutes int `json:"scan_interval_minutes"` ScanIntervalMinutes int `json:"scan_interval_minutes"`
IsCrossMargin *bool `json:"is_cross_margin"` IsCrossMargin *bool `json:"is_cross_margin"`
// The following fields are kept for backward compatibility, new version uses strategy config // The following fields are kept for backward compatibility, new version uses strategy config
BTCETHLeverage int `json:"btc_eth_leverage"` BTCETHLeverage int `json:"btc_eth_leverage"`
AltcoinLeverage int `json:"altcoin_leverage"` AltcoinLeverage int `json:"altcoin_leverage"`
TradingSymbols string `json:"trading_symbols"` TradingSymbols string `json:"trading_symbols"`
CustomPrompt string `json:"custom_prompt"` CustomPrompt string `json:"custom_prompt"`
OverrideBasePrompt bool `json:"override_base_prompt"` OverrideBasePrompt bool `json:"override_base_prompt"`
SystemPromptTemplate string `json:"system_prompt_template"` SystemPromptTemplate string `json:"system_prompt_template"`
} }
// handleUpdateTrader Update trader configuration // handleUpdateTrader Update trader configuration
@@ -974,11 +974,11 @@ func (s *Server) handleSyncBalance(c *gin.Context) {
exchangeCfg.AsterSigner, exchangeCfg.AsterSigner,
exchangeCfg.AsterPrivateKey, exchangeCfg.AsterPrivateKey,
) )
case "bybit": case "bybit":
tempTrader = trader.NewBybitTrader( tempTrader = trader.NewBybitTrader(
exchangeCfg.APIKey, exchangeCfg.APIKey,
exchangeCfg.SecretKey, exchangeCfg.SecretKey,
) )
default: default:
c.JSON(http.StatusBadRequest, gin.H{"error": "Unsupported exchange type"}) c.JSON(http.StatusBadRequest, gin.H{"error": "Unsupported exchange type"})
return return
@@ -1271,23 +1271,6 @@ func (s *Server) handleGetExchangeConfigs(c *gin.Context) {
} }
logger.Infof("✅ Found %d exchange configs", len(exchanges)) logger.Infof("✅ Found %d exchange configs", len(exchanges))
// Debug: Output config details (masked)
for _, ex := range exchanges {
apiKeyMasked := ""
if len(ex.APIKey) > 8 {
apiKeyMasked = ex.APIKey[:8] + "..."
}
secretKeyMasked := ""
if len(ex.SecretKey) > 8 {
secretKeyMasked = ex.SecretKey[:8] + "..."
}
logger.Infof(" └─ Exchange: %s, APIKey: %s, SecretKey: %s", ex.ID, apiKeyMasked, secretKeyMasked)
}
// Print complete JSON response for debugging
jsonData, _ := json.Marshal(exchanges)
logger.Infof("📤 Complete JSON response: %s", string(jsonData))
// Convert to safe response structure, remove sensitive information // Convert to safe response structure, remove sensitive information
safeExchanges := make([]SafeExchangeConfig, len(exchanges)) safeExchanges := make([]SafeExchangeConfig, len(exchanges))
for i, exchange := range exchanges { for i, exchange := range exchanges {
@@ -1742,7 +1725,6 @@ func (s *Server) authMiddleware() gin.HandlerFunc {
} }
} }
// handleLogout Add current token to blacklist // handleLogout Add current token to blacklist
func (s *Server) handleLogout(c *gin.Context) { func (s *Server) handleLogout(c *gin.Context) {
authHeader := c.GetHeader("Authorization") authHeader := c.GetHeader("Authorization")
+36 -15
View File
@@ -1,7 +1,11 @@
package logger package logger
import ( import (
"fmt"
"os" "os"
"path/filepath"
"runtime"
"strings"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@@ -11,15 +15,40 @@ var (
Log *logrus.Logger Log *logrus.Logger
) )
// compactFormatter is a custom formatter for cleaner log output
type compactFormatter struct {
logrus.TextFormatter
}
func (f *compactFormatter) Format(entry *logrus.Entry) ([]byte, error) {
level := strings.ToUpper(entry.Level.String())[0:4]
// Skip frames to find actual caller (skip logrus + our wrapper functions)
caller := ""
for i := 3; i < 10; i++ {
_, file, line, ok := runtime.Caller(i)
if !ok {
break
}
// Skip logrus internal and our logger.go
if !strings.Contains(file, "logrus") && !strings.HasSuffix(file, "logger/logger.go") {
// Get package name from path (e.g., "nofx/manager/trader_manager.go" -> "manager")
dir := filepath.Dir(file)
pkg := filepath.Base(dir)
caller = fmt.Sprintf("%s/%s:%d", pkg, filepath.Base(file), line)
break
}
}
msg := fmt.Sprintf("[%s] %s %s\n", level, caller, entry.Message)
return []byte(msg), nil
}
func init() { func init() {
// Auto-initialize default logger to ensure it works before Init is called // Auto-initialize default logger to ensure it works before Init is called
Log = logrus.New() Log = logrus.New()
Log.SetLevel(logrus.InfoLevel) Log.SetLevel(logrus.InfoLevel)
Log.SetFormatter(&logrus.TextFormatter{ Log.SetFormatter(&compactFormatter{})
FullTimestamp: true,
TimestampFormat: "2006-01-02 15:04:05",
ForceColors: true,
})
Log.SetOutput(os.Stdout) Log.SetOutput(os.Stdout)
} }
@@ -47,17 +76,9 @@ func Init(cfg *Config) error {
} }
Log.SetLevel(level) Log.SetLevel(level)
// Set formatter (always use colored text format) // Set compact formatter
Log.SetFormatter(&logrus.TextFormatter{ Log.SetFormatter(&compactFormatter{})
FullTimestamp: true,
TimestampFormat: "2006-01-02 15:04:05",
ForceColors: true,
})
// Set output target (default stdout)
Log.SetOutput(os.Stdout) Log.SetOutput(os.Stdout)
// Enable caller location info
Log.SetReportCaller(true) Log.SetReportCaller(true)
return nil return nil