mirror of
				https://github.com/MHSanaei/3x-ui.git
				synced 2025-10-31 20:32:52 +00:00 
			
		
		
		
	improved - message logs
This commit is contained in:
		
							parent
							
								
									c9a218d060
								
							
						
					
					
						commit
						f1500a5d31
					
				
					 13 changed files with 169 additions and 121 deletions
				
			
		
							
								
								
									
										92
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								main.go
									
									
									
									
									
								
							|  | @ -21,7 +21,7 @@ import ( | |||
| ) | ||||
| 
 | ||||
| func runWebServer() { | ||||
| 	log.Printf("%v %v", config.GetName(), config.GetVersion()) | ||||
| 	log.Printf("Starting %v %v", config.GetName(), config.GetVersion()) | ||||
| 
 | ||||
| 	switch config.GetLogLevel() { | ||||
| 	case config.Debug: | ||||
|  | @ -35,31 +35,29 @@ func runWebServer() { | |||
| 	case config.Error: | ||||
| 		logger.InitLogger(logging.ERROR) | ||||
| 	default: | ||||
| 		log.Fatal("unknown log level:", config.GetLogLevel()) | ||||
| 		log.Fatalf("Unknown log level: %v", config.GetLogLevel()) | ||||
| 	} | ||||
| 
 | ||||
| 	err := database.InitDB(config.GetDBPath()) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 		log.Fatalf("Error initializing database: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	var server *web.Server | ||||
| 
 | ||||
| 	server = web.NewServer() | ||||
| 	global.SetWebServer(server) | ||||
| 	err = server.Start() | ||||
| 	if err != nil { | ||||
| 		log.Println(err) | ||||
| 		log.Fatalf("Error starting web server: %v", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	var subServer *sub.Server | ||||
| 	subServer = sub.NewServer() | ||||
| 	global.SetSubServer(subServer) | ||||
| 
 | ||||
| 	err = subServer.Start() | ||||
| 	if err != nil { | ||||
| 		log.Println(err) | ||||
| 		log.Fatalf("Error starting sub server: %v", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | @ -71,34 +69,39 @@ func runWebServer() { | |||
| 
 | ||||
| 		switch sig { | ||||
| 		case syscall.SIGHUP: | ||||
| 			logger.Info("Received SIGHUP signal. Restarting servers...") | ||||
| 
 | ||||
| 			err := server.Stop() | ||||
| 			if err != nil { | ||||
| 				logger.Warning("stop server err:", err) | ||||
| 				logger.Warning("Error stopping web server:", err) | ||||
| 			} | ||||
| 			err = subServer.Stop() | ||||
| 			if err != nil { | ||||
| 				logger.Warning("stop server err:", err) | ||||
| 				logger.Warning("Error stopping sub server:", err) | ||||
| 			} | ||||
| 
 | ||||
| 			server = web.NewServer() | ||||
| 			global.SetWebServer(server) | ||||
| 			err = server.Start() | ||||
| 			if err != nil { | ||||
| 				log.Println(err) | ||||
| 				log.Fatalf("Error restarting web server: %v", err) | ||||
| 				return | ||||
| 			} | ||||
| 			log.Println("Web server restarted successfully.") | ||||
| 
 | ||||
| 			subServer = sub.NewServer() | ||||
| 			global.SetSubServer(subServer) | ||||
| 
 | ||||
| 			err = subServer.Start() | ||||
| 			if err != nil { | ||||
| 				log.Println(err) | ||||
| 				log.Fatalf("Error restarting sub server: %v", err) | ||||
| 				return | ||||
| 			} | ||||
| 			log.Println("Sub server restarted successfully.") | ||||
| 
 | ||||
| 		default: | ||||
| 			server.Stop() | ||||
| 			subServer.Stop() | ||||
| 			log.Println("Shutting down servers.") | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
|  | @ -107,16 +110,16 @@ func runWebServer() { | |||
| func resetSetting() { | ||||
| 	err := database.InitDB(config.GetDBPath()) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 		fmt.Println("Failed to initialize database:", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	settingService := service.SettingService{} | ||||
| 	err = settingService.ResetSettings() | ||||
| 	if err != nil { | ||||
| 		fmt.Println("reset setting failed:", err) | ||||
| 		fmt.Println("Failed to reset settings:", err) | ||||
| 	} else { | ||||
| 		fmt.Println("reset setting success") | ||||
| 		fmt.Println("Settings successfully reset.") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -179,7 +182,7 @@ func updateTgbotEnableSts(status bool) { | |||
| func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime string) { | ||||
| 	err := database.InitDB(config.GetDBPath()) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 		fmt.Println("Error initializing database:", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | @ -188,68 +191,65 @@ func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime stri | |||
| 	if tgBotToken != "" { | ||||
| 		err := settingService.SetTgBotToken(tgBotToken) | ||||
| 		if err != nil { | ||||
| 			fmt.Println(err) | ||||
| 			fmt.Printf("Error setting Telegram bot token: %v\n", err) | ||||
| 			return | ||||
| 		} else { | ||||
| 			logger.Info("updateTgbotSetting tgBotToken success") | ||||
| 		} | ||||
| 		logger.Info("Successfully updated Telegram bot token.") | ||||
| 	} | ||||
| 
 | ||||
| 	if tgBotRuntime != "" { | ||||
| 		err := settingService.SetTgbotRuntime(tgBotRuntime) | ||||
| 		if err != nil { | ||||
| 			fmt.Println(err) | ||||
| 			fmt.Printf("Error setting Telegram bot runtime: %v\n", err) | ||||
| 			return | ||||
| 		} else { | ||||
| 			logger.Infof("updateTgbotSetting tgBotRuntime[%s] success", tgBotRuntime) | ||||
| 		} | ||||
| 		logger.Infof("Successfully updated Telegram bot runtime to [%s].", tgBotRuntime) | ||||
| 	} | ||||
| 
 | ||||
| 	if tgBotChatid != "" { | ||||
| 		err := settingService.SetTgBotChatId(tgBotChatid) | ||||
| 		if err != nil { | ||||
| 			fmt.Println(err) | ||||
| 			fmt.Printf("Error setting Telegram bot chat ID: %v\n", err) | ||||
| 			return | ||||
| 		} else { | ||||
| 			logger.Info("updateTgbotSetting tgBotChatid success") | ||||
| 		} | ||||
| 		logger.Info("Successfully updated Telegram bot chat ID.") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func updateSetting(port int, username string, password string, webBasePath string) { | ||||
| 	err := database.InitDB(config.GetDBPath()) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 		fmt.Println("Database initialization failed:", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	settingService := service.SettingService{} | ||||
| 	userService := service.UserService{} | ||||
| 
 | ||||
| 	if port > 0 { | ||||
| 		err := settingService.SetPort(port) | ||||
| 		if err != nil { | ||||
| 			fmt.Println("set port failed:", err) | ||||
| 			fmt.Println("Failed to set port:", err) | ||||
| 		} else { | ||||
| 			fmt.Printf("set port %v success", port) | ||||
| 			fmt.Printf("Port set successfully: %v\n", port) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if username != "" || password != "" { | ||||
| 		userService := service.UserService{} | ||||
| 		err := userService.UpdateFirstUser(username, password) | ||||
| 		if err != nil { | ||||
| 			fmt.Println("set username and password failed:", err) | ||||
| 			fmt.Println("Failed to update username and password:", err) | ||||
| 		} else { | ||||
| 			fmt.Println("set username and password success") | ||||
| 			fmt.Println("Username and password updated successfully") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if webBasePath != "" { | ||||
| 		err := settingService.SetBasePath(webBasePath) | ||||
| 		if err != nil { | ||||
| 			fmt.Println("set base URI path failed:", err) | ||||
| 			fmt.Println("Failed to set base URI path:", err) | ||||
| 		} else { | ||||
| 			fmt.Println("set base URI path success") | ||||
| 			fmt.Println("Base URI path set successfully") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -348,19 +348,19 @@ func main() { | |||
| 	var reset bool | ||||
| 	var show bool | ||||
| 	var remove_secret bool | ||||
| 	settingCmd.BoolVar(&reset, "reset", false, "reset all settings") | ||||
| 	settingCmd.BoolVar(&show, "show", false, "show current settings") | ||||
| 	settingCmd.BoolVar(&remove_secret, "remove_secret", false, "remove secret") | ||||
| 	settingCmd.IntVar(&port, "port", 0, "set panel port") | ||||
| 	settingCmd.StringVar(&username, "username", "", "set login username") | ||||
| 	settingCmd.StringVar(&password, "password", "", "set login password") | ||||
| 	settingCmd.StringVar(&webBasePath, "webBasePath", "", "set web base path") | ||||
| 	settingCmd.StringVar(&webCertFile, "webCert", "", "set web public key path") | ||||
| 	settingCmd.StringVar(&webKeyFile, "webCertKey", "", "set web private key path") | ||||
| 	settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "set telegram bot token") | ||||
| 	settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "set telegram bot cron time") | ||||
| 	settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "set telegram bot chat id") | ||||
| 	settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "enable telegram bot notify") | ||||
| 	settingCmd.BoolVar(&reset, "reset", false, "Reset all settings") | ||||
| 	settingCmd.BoolVar(&show, "show", false, "Display current settings") | ||||
| 	settingCmd.BoolVar(&remove_secret, "remove_secret", false, "Remove secret key") | ||||
| 	settingCmd.IntVar(&port, "port", 0, "Set panel port number") | ||||
| 	settingCmd.StringVar(&username, "username", "", "Set login username") | ||||
| 	settingCmd.StringVar(&password, "password", "", "Set login password") | ||||
| 	settingCmd.StringVar(&webBasePath, "webBasePath", "", "Set base path for Panel") | ||||
| 	settingCmd.StringVar(&webCertFile, "webCert", "", "Set path to public key file for panel") | ||||
| 	settingCmd.StringVar(&webKeyFile, "webCertKey", "", "Set path to private key file for panel") | ||||
| 	settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "Set token for Telegram bot") | ||||
| 	settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "Set cron time for Telegram bot notifications") | ||||
| 	settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "Set chat ID for Telegram bot notifications") | ||||
| 	settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "Enable notifications via Telegram bot") | ||||
| 
 | ||||
| 	oldUsage := flag.Usage | ||||
| 	flag.Usage = func() { | ||||
|  |  | |||
|  | @ -163,13 +163,13 @@ func (s *Server) Start() (err error) { | |||
| 			} | ||||
| 			listener = network.NewAutoHttpsListener(listener) | ||||
| 			listener = tls.NewListener(listener, c) | ||||
| 			logger.Info("sub server run https on", listener.Addr()) | ||||
| 			logger.Info("Sub server running HTTPS on", listener.Addr()) | ||||
| 		} else { | ||||
| 			logger.Error("error in loading certificates: ", err) | ||||
| 			logger.Info("sub server run http on", listener.Addr()) | ||||
| 			logger.Error("Error loading certificates:", err) | ||||
| 			logger.Info("Sub server running HTTP on", listener.Addr()) | ||||
| 		} | ||||
| 	} else { | ||||
| 		logger.Info("sub server run http on", listener.Addr()) | ||||
| 		logger.Info("Sub server running HTTP on", listener.Addr()) | ||||
| 	} | ||||
| 	s.listener = listener | ||||
| 
 | ||||
|  |  | |||
|  | @ -76,25 +76,25 @@ func (a *IndexController) login(c *gin.Context) { | |||
| 
 | ||||
| 	sessionMaxAge, err := a.settingService.GetSessionMaxAge() | ||||
| 	if err != nil { | ||||
| 		logger.Warningf("Unable to get session's max age from DB") | ||||
| 		logger.Warning("Unable to get session's max age from DB") | ||||
| 	} | ||||
| 
 | ||||
| 	if sessionMaxAge > 0 { | ||||
| 		err = session.SetMaxAge(c, sessionMaxAge*60) | ||||
| 		if err != nil { | ||||
| 			logger.Warningf("Unable to set session's max age") | ||||
| 			logger.Warning("Unable to set session's max age") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	err = session.SetLoginUser(c, user) | ||||
| 	logger.Info(user.Username, " logged in successfully") | ||||
| 	logger.Infof("%s logged in successfully", user.Username) | ||||
| 	jsonMsg(c, I18nWeb(c, "pages.login.toasts.successLogin"), err) | ||||
| } | ||||
| 
 | ||||
| func (a *IndexController) logout(c *gin.Context) { | ||||
| 	user := session.GetLoginUser(c) | ||||
| 	if user != nil { | ||||
| 		logger.Info(user.Username, " logged out successfully") | ||||
| 		logger.Infof("%s logged out successfully", user.Username) | ||||
| 	} | ||||
| 	session.ClearSession(c) | ||||
| 	c.Redirect(http.StatusTemporaryRedirect, c.GetString("base_path")) | ||||
|  |  | |||
|  | @ -252,46 +252,55 @@ func (j *CheckClientIpJob) addInboundClientIps(clientEmail string, ips []string) | |||
| 
 | ||||
| func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.InboundClientIps, clientEmail string, ips []string) bool { | ||||
| 	jsonIps, err := json.Marshal(ips) | ||||
| 	j.checkError(err) | ||||
| 	if err != nil { | ||||
| 		logger.Error("failed to marshal IPs to JSON:", err) | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	inboundClientIps.ClientEmail = clientEmail | ||||
| 	inboundClientIps.Ips = string(jsonIps) | ||||
| 
 | ||||
| 	// check inbound limitation
 | ||||
| 	// Fetch inbound settings by client email
 | ||||
| 	inbound, err := j.getInboundByEmail(clientEmail) | ||||
| 	j.checkError(err) | ||||
| 
 | ||||
| 	if inbound.Settings == "" { | ||||
| 		logger.Debug("wrong data ", inbound) | ||||
| 	if err != nil { | ||||
| 		logger.Errorf("failed to fetch inbound settings for email %s: %s", clientEmail, err) | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	if inbound.Settings == "" { | ||||
| 		logger.Debug("wrong data:", inbound) | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// Unmarshal settings to get client limits
 | ||||
| 	settings := map[string][]model.Client{} | ||||
| 	json.Unmarshal([]byte(inbound.Settings), &settings) | ||||
| 	clients := settings["clients"] | ||||
| 	shouldCleanLog := false | ||||
| 	j.disAllowedIps = []string{} | ||||
| 
 | ||||
| 	// create iplimit log file channel
 | ||||
| 	logIpFile, err := os.OpenFile(xray.GetIPLimitLogPath(), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644) | ||||
| 	// Open log file for IP limits
 | ||||
| 	logIpFile, err := os.OpenFile(xray.GetIPLimitLogPath(), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) | ||||
| 	if err != nil { | ||||
| 		logger.Errorf("failed to create or open ip limit log file: %s", err) | ||||
| 		logger.Errorf("failed to open IP limit log file: %s", err) | ||||
| 		return false | ||||
| 	} | ||||
| 	defer logIpFile.Close() | ||||
| 	log.SetOutput(logIpFile) | ||||
| 	log.SetFlags(log.LstdFlags) | ||||
| 
 | ||||
| 	// Check client IP limits
 | ||||
| 	for _, client := range clients { | ||||
| 		if client.Email == clientEmail { | ||||
| 			limitIp := client.LimitIP | ||||
| 
 | ||||
| 			if limitIp != 0 { | ||||
| 			if limitIp > 0 && inbound.Enable { | ||||
| 				shouldCleanLog = true | ||||
| 
 | ||||
| 				if limitIp < len(ips) && inbound.Enable { | ||||
| 				if limitIp < len(ips) { | ||||
| 					j.disAllowedIps = append(j.disAllowedIps, ips[limitIp:]...) | ||||
| 					for i := limitIp; i < len(ips); i++ { | ||||
| 						log.Printf("[LIMIT_IP] Email = %s || SRC = %s", clientEmail, ips[i]) | ||||
| 						logger.Debugf("[LIMIT_IP] Email = %s || SRC = %s", clientEmail, ips[i]) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | @ -301,12 +310,15 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun | |||
| 	sort.Strings(j.disAllowedIps) | ||||
| 
 | ||||
| 	if len(j.disAllowedIps) > 0 { | ||||
| 		logger.Debug("disAllowedIps ", j.disAllowedIps) | ||||
| 		logger.Debug("disAllowedIps:", j.disAllowedIps) | ||||
| 	} | ||||
| 
 | ||||
| 	db := database.GetDB() | ||||
| 	err = db.Save(inboundClientIps).Error | ||||
| 	j.checkError(err) | ||||
| 	if err != nil { | ||||
| 		logger.Error("failed to save inboundClientIps:", err) | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	return shouldCleanLog | ||||
| } | ||||
|  |  | |||
|  | @ -19,10 +19,8 @@ func (j *XrayTrafficJob) Run() { | |||
| 	if !j.xrayService.IsXrayRunning() { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	traffics, clientTraffics, err := j.xrayService.GetXrayTraffic() | ||||
| 	if err != nil { | ||||
| 		logger.Warning("get xray traffic failed:", err) | ||||
| 		return | ||||
| 	} | ||||
| 	err, needRestart0 := j.inboundService.AddTraffic(traffics, clientTraffics) | ||||
|  |  | |||
|  | @ -1142,7 +1142,7 @@ func (s *InboundService) GetClientInboundByTrafficID(trafficId int) (traffic *xr | |||
| 	var traffics []*xray.ClientTraffic | ||||
| 	err = db.Model(xray.ClientTraffic{}).Where("id = ?", trafficId).Find(&traffics).Error | ||||
| 	if err != nil { | ||||
| 		logger.Warning(err) | ||||
| 		logger.Warningf("Error retrieving ClientTraffic with trafficId %d: %v", trafficId, err) | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	if len(traffics) > 0 { | ||||
|  | @ -1157,7 +1157,7 @@ func (s *InboundService) GetClientInboundByEmail(email string) (traffic *xray.Cl | |||
| 	var traffics []*xray.ClientTraffic | ||||
| 	err = db.Model(xray.ClientTraffic{}).Where("email = ?", email).Find(&traffics).Error | ||||
| 	if err != nil { | ||||
| 		logger.Warning(err) | ||||
| 		logger.Warningf("Error retrieving ClientTraffic with email %s: %v", email, err) | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	if len(traffics) > 0 { | ||||
|  | @ -1698,15 +1698,20 @@ func (s *InboundService) DelDepletedClients(id int) (err error) { | |||
| func (s *InboundService) GetClientTrafficTgBot(tgId int64) ([]*xray.ClientTraffic, error) { | ||||
| 	db := database.GetDB() | ||||
| 	var inbounds []*model.Inbound | ||||
| 	err := db.Model(model.Inbound{}).Where("settings like ?", fmt.Sprintf(`%%"tgId": %d%%`, tgId)).Find(&inbounds).Error | ||||
| 
 | ||||
| 	// Retrieve inbounds where settings contain the given tgId
 | ||||
| 	err := db.Model(model.Inbound{}).Where("settings LIKE ?", fmt.Sprintf(`%%"tgId": %d%%`, tgId)).Find(&inbounds).Error | ||||
| 	if err != nil && err != gorm.ErrRecordNotFound { | ||||
| 		logger.Errorf("Error retrieving inbounds with tgId %d: %v", tgId, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	var emails []string | ||||
| 	for _, inbound := range inbounds { | ||||
| 		clients, err := s.GetClients(inbound) | ||||
| 		if err != nil { | ||||
| 			logger.Error("Unable to get clients from inbound") | ||||
| 			logger.Errorf("Error retrieving clients for inbound %d: %v", inbound.Id, err) | ||||
| 			continue | ||||
| 		} | ||||
| 		for _, client := range clients { | ||||
| 			if client.TgID == tgId { | ||||
|  | @ -1714,15 +1719,19 @@ func (s *InboundService) GetClientTrafficTgBot(tgId int64) ([]*xray.ClientTraffi | |||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	var traffics []*xray.ClientTraffic | ||||
| 	err = db.Model(xray.ClientTraffic{}).Where("email IN ?", emails).Find(&traffics).Error | ||||
| 	if err != nil { | ||||
| 		if err == gorm.ErrRecordNotFound { | ||||
| 			logger.Warning(err) | ||||
| 			return nil, err | ||||
| 			logger.Warning("No ClientTraffic records found for emails:", emails) | ||||
| 			return nil, nil | ||||
| 		} | ||||
| 		logger.Errorf("Error retrieving ClientTraffic for emails %v: %v", emails, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return traffics, err | ||||
| 
 | ||||
| 	return traffics, nil | ||||
| } | ||||
| 
 | ||||
| func (s *InboundService) GetClientTrafficByEmail(email string) (traffic *xray.ClientTraffic, err error) { | ||||
|  | @ -1731,7 +1740,7 @@ func (s *InboundService) GetClientTrafficByEmail(email string) (traffic *xray.Cl | |||
| 
 | ||||
| 	err = db.Model(xray.ClientTraffic{}).Where("email = ?", email).Find(&traffics).Error | ||||
| 	if err != nil { | ||||
| 		logger.Warning(err) | ||||
| 		logger.Warningf("Error retrieving ClientTraffic with email %s: %v", email, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if len(traffics) > 0 { | ||||
|  | @ -1746,38 +1755,51 @@ func (s *InboundService) SearchClientTraffic(query string) (traffic *xray.Client | |||
| 	inbound := &model.Inbound{} | ||||
| 	traffic = &xray.ClientTraffic{} | ||||
| 
 | ||||
| 	err = db.Model(model.Inbound{}).Where("settings like ?", "%\""+query+"\"%").First(inbound).Error | ||||
| 	// Search for inbound settings that contain the query
 | ||||
| 	err = db.Model(model.Inbound{}).Where("settings LIKE ?", "%\""+query+"\"%").First(inbound).Error | ||||
| 	if err != nil { | ||||
| 		if err == gorm.ErrRecordNotFound { | ||||
| 			logger.Warning(err) | ||||
| 			logger.Warningf("Inbound settings containing query %s not found: %v", query, err) | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		logger.Errorf("Error searching for inbound settings with query %s: %v", query, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	traffic.InboundId = inbound.Id | ||||
| 
 | ||||
| 	// get settings clients
 | ||||
| 	// Unmarshal settings to get clients
 | ||||
| 	settings := map[string][]model.Client{} | ||||
| 	json.Unmarshal([]byte(inbound.Settings), &settings) | ||||
| 	if err := json.Unmarshal([]byte(inbound.Settings), &settings); err != nil { | ||||
| 		logger.Errorf("Error unmarshalling inbound settings for inbound ID %d: %v", inbound.Id, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	clients := settings["clients"] | ||||
| 	for _, client := range clients { | ||||
| 		if client.ID == query && client.Email != "" { | ||||
| 			traffic.Email = client.Email | ||||
| 			break | ||||
| 		} | ||||
| 		if client.Password == query && client.Email != "" { | ||||
| 		if (client.ID == query || client.Password == query) && client.Email != "" { | ||||
| 			traffic.Email = client.Email | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if traffic.Email == "" { | ||||
| 		return nil, err | ||||
| 		logger.Warningf("No client found with query %s in inbound ID %d", query, inbound.Id) | ||||
| 		return nil, gorm.ErrRecordNotFound | ||||
| 	} | ||||
| 
 | ||||
| 	// Retrieve ClientTraffic based on the found email
 | ||||
| 	err = db.Model(xray.ClientTraffic{}).Where("email = ?", traffic.Email).First(traffic).Error | ||||
| 	if err != nil { | ||||
| 		logger.Warning(err) | ||||
| 		if err == gorm.ErrRecordNotFound { | ||||
| 			logger.Warningf("ClientTraffic for email %s not found: %v", traffic.Email, err) | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		logger.Errorf("Error retrieving ClientTraffic for email %s: %v", traffic.Email, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return traffic, err | ||||
| 
 | ||||
| 	return traffic, nil | ||||
| } | ||||
| 
 | ||||
| func (s *InboundService) GetInboundClientIps(clientEmail string) (string, error) { | ||||
|  |  | |||
|  | @ -70,7 +70,7 @@ func (s *OutboundService) GetOutboundsTraffic() ([]*model.OutboundTraffics, erro | |||
| 
 | ||||
| 	err := db.Model(model.OutboundTraffics{}).Find(&traffics).Error | ||||
| 	if err != nil { | ||||
| 		logger.Warning(err) | ||||
| 		logger.Warning("Error retrieving OutboundTraffics: ", err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ func (s *PanelService) RestartPanel(delay time.Duration) error { | |||
| 		time.Sleep(delay) | ||||
| 		err := p.Signal(syscall.SIGHUP) | ||||
| 		if err != nil { | ||||
| 			logger.Error("send signal SIGHUP failed:", err) | ||||
| 			logger.Error("failed to send SIGHUP signal:", err) | ||||
| 		} | ||||
| 	}() | ||||
| 	return nil | ||||
|  |  | |||
|  | @ -64,52 +64,59 @@ func (t *Tgbot) GetHashStorage() *global.HashStorage { | |||
| } | ||||
| 
 | ||||
| func (t *Tgbot) Start(i18nFS embed.FS) error { | ||||
| 	// Initialize localizer
 | ||||
| 	err := locale.InitLocalizer(i18nFS, &t.settingService) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// init hash storage => store callback queries
 | ||||
| 	// Initialize hash storage to store callback queries
 | ||||
| 	hashStorage = global.NewHashStorage(20 * time.Minute) | ||||
| 
 | ||||
| 	t.SetHostname() | ||||
| 	tgBottoken, err := t.settingService.GetTgBotToken() | ||||
| 	if err != nil || tgBottoken == "" { | ||||
| 		logger.Warning("Get TgBotToken failed:", err) | ||||
| 
 | ||||
| 	// Get Telegram bot token
 | ||||
| 	tgBotToken, err := t.settingService.GetTgBotToken() | ||||
| 	if err != nil || tgBotToken == "" { | ||||
| 		logger.Warning("Failed to get Telegram bot token:", err) | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	tgBotid, err := t.settingService.GetTgBotChatId() | ||||
| 	// Get Telegram bot chat ID(s)
 | ||||
| 	tgBotID, err := t.settingService.GetTgBotChatId() | ||||
| 	if err != nil { | ||||
| 		logger.Warning("Get GetTgBotChatId failed:", err) | ||||
| 		logger.Warning("Failed to get Telegram bot chat ID:", err) | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if tgBotid != "" { | ||||
| 		for _, adminId := range strings.Split(tgBotid, ",") { | ||||
| 			id, err := strconv.Atoi(adminId) | ||||
| 	// Parse admin IDs from comma-separated string
 | ||||
| 	if tgBotID != "" { | ||||
| 		for _, adminID := range strings.Split(tgBotID, ",") { | ||||
| 			id, err := strconv.Atoi(adminID) | ||||
| 			if err != nil { | ||||
| 				logger.Warning("Failed to get IDs from GetTgBotChatId:", err) | ||||
| 				logger.Warning("Failed to parse admin ID from Telegram bot chat ID:", err) | ||||
| 				return err | ||||
| 			} | ||||
| 			adminIds = append(adminIds, int64(id)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Get Telegram bot proxy URL
 | ||||
| 	tgBotProxy, err := t.settingService.GetTgBotProxy() | ||||
| 	if err != nil { | ||||
| 		logger.Warning("Failed to get ProxyUrl:", err) | ||||
| 		logger.Warning("Failed to get Telegram bot proxy URL:", err) | ||||
| 	} | ||||
| 
 | ||||
| 	bot, err = t.NewBot(tgBottoken, tgBotProxy) | ||||
| 	// Create new Telegram bot instance
 | ||||
| 	bot, err = t.NewBot(tgBotToken, tgBotProxy) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Get tgbot's api error:", err) | ||||
| 		logger.Error("Failed to initialize Telegram bot API:", err) | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// listen for TG bot income messages
 | ||||
| 	// Start receiving Telegram bot messages
 | ||||
| 	if !isRunning { | ||||
| 		logger.Info("Starting Telegram receiver ...") | ||||
| 		logger.Info("Telegram bot receiver started") | ||||
| 		go t.OnReceive() | ||||
| 		isRunning = true | ||||
| 	} | ||||
|  |  | |||
|  | @ -97,7 +97,7 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) { | |||
| 						if !clientTraffic.Enable { | ||||
| 							clients = RemoveIndex(clients, index-indexDecrease) | ||||
| 							indexDecrease++ | ||||
| 							logger.Info("Remove Inbound User ", c["email"], " due the expire or traffic limit") | ||||
| 							logger.Infof("Remove Inbound User %s due to expiration or traffic limit", c["email"]) | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | @ -165,11 +165,20 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) { | |||
| 
 | ||||
| func (s *XrayService) GetXrayTraffic() ([]*xray.Traffic, []*xray.ClientTraffic, error) { | ||||
| 	if !s.IsXrayRunning() { | ||||
| 		return nil, nil, errors.New("xray is not running") | ||||
| 		err := errors.New("xray is not running") | ||||
| 		logger.Debug("Attempted to fetch Xray traffic, but Xray is not running:", err) | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	s.xrayAPI.Init(p.GetAPIPort()) | ||||
| 	apiPort := p.GetAPIPort() | ||||
| 	s.xrayAPI.Init(apiPort) | ||||
| 	defer s.xrayAPI.Close() | ||||
| 	return s.xrayAPI.GetTraffic(true) | ||||
| 
 | ||||
| 	traffic, clientTraffic, err := s.xrayAPI.GetTraffic(true) | ||||
| 	if err != nil { | ||||
| 		logger.Debug("Failed to fetch Xray traffic:", err) | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	return traffic, clientTraffic, nil | ||||
| } | ||||
| 
 | ||||
| func (s *XrayService) RestartXray(isForce bool) error { | ||||
|  | @ -202,7 +211,7 @@ func (s *XrayService) RestartXray(isForce bool) error { | |||
| func (s *XrayService) StopXray() error { | ||||
| 	lock.Lock() | ||||
| 	defer lock.Unlock() | ||||
| 	logger.Debug("stop xray") | ||||
| 	logger.Debug("Attempting to stop Xray...") | ||||
| 	if s.IsXrayRunning() { | ||||
| 		return p.Stop() | ||||
| 	} | ||||
|  |  | |||
|  | @ -344,13 +344,13 @@ func (s *Server) Start() (err error) { | |||
| 			} | ||||
| 			listener = network.NewAutoHttpsListener(listener) | ||||
| 			listener = tls.NewListener(listener, c) | ||||
| 			logger.Info("web server run https on", listener.Addr()) | ||||
| 			logger.Info("Web server running HTTPS on", listener.Addr()) | ||||
| 		} else { | ||||
| 			logger.Error("error in loading certificates: ", err) | ||||
| 			logger.Info("web server run http on", listener.Addr()) | ||||
| 			logger.Error("Error loading certificates:", err) | ||||
| 			logger.Info("Web server running HTTP on", listener.Addr()) | ||||
| 		} | ||||
| 	} else { | ||||
| 		logger.Info("web server run http on", listener.Addr()) | ||||
| 		logger.Info("Web server running HTTP on", listener.Addr()) | ||||
| 	} | ||||
| 	s.listener = listener | ||||
| 
 | ||||
|  |  | |||
|  | @ -183,6 +183,7 @@ func (x *XrayAPI) GetTraffic(reset bool) ([]*Traffic, []*ClientTraffic, error) { | |||
| 
 | ||||
| 	resp, err := (*x.StatsServiceClient).QueryStats(ctx, &statsService.QueryStatsRequest{Reset_: reset}) | ||||
| 	if err != nil { | ||||
| 		logger.Debug("Failed to query Xray stats:", err) | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 
 | ||||
|  | @ -196,7 +197,6 @@ func (x *XrayAPI) GetTraffic(reset bool) ([]*Traffic, []*ClientTraffic, error) { | |||
| 			processClientTraffic(matches, stat.Value, emailTrafficMap) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return mapToSlice(tagTrafficMap), mapToSlice(emailTrafficMap), nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -60,14 +60,14 @@ func GetAccessPersistentPrevLogPath() string { | |||
| func GetAccessLogPath() (string, error) { | ||||
| 	config, err := os.ReadFile(GetConfigPath()) | ||||
| 	if err != nil { | ||||
| 		logger.Warningf("Something went wrong: %s", err) | ||||
| 		logger.Warningf("Failed to read configuration file: %s", err) | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	jsonConfig := map[string]interface{}{} | ||||
| 	err = json.Unmarshal([]byte(config), &jsonConfig) | ||||
| 	if err != nil { | ||||
| 		logger.Warningf("Something went wrong: %s", err) | ||||
| 		logger.Warningf("Failed to parse JSON configuration: %s", err) | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
|  | @ -206,7 +206,7 @@ func (p *process) Start() (err error) { | |||
| 
 | ||||
| 	err = os.MkdirAll(config.GetLogFolder(), 0o770) | ||||
| 	if err != nil { | ||||
| 		logger.Warningf("Something went wrong: %s", err) | ||||
| 		logger.Warningf("Failed to create log folder: %s", err) | ||||
| 	} | ||||
| 
 | ||||
| 	configPath := GetConfigPath() | ||||
|  | @ -224,7 +224,7 @@ func (p *process) Start() (err error) { | |||
| 	go func() { | ||||
| 		err := cmd.Run() | ||||
| 		if err != nil { | ||||
| 			logger.Error("Failure in running xray-core: ", err) | ||||
| 			logger.Error("Failure in running xray-core:", err) | ||||
| 			p.exitErr = err | ||||
| 		} | ||||
| 	}() | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 mhsanaei
						mhsanaei