feat(logging): add detailed logging throughout application components
- Implement logging in router setup, auth handlers, and frpc operations - Add SoftwareInfo struct for version tracking and logging - Enhance error messages with more context and logging - Replace direct error returns with formatted error logging - Add debug logs for token operations and request validations
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"super-frpc/postLog"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -58,13 +59,15 @@ func CloseFrpcDatabase() error {
|
||||
|
||||
func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "invalid request method")
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
|
||||
postLog.Debug(fmt.Sprintf("[CreateInstanceHandler] Invalid request method: %s", r.Method))
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "failed to read request body")
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to read request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
@@ -72,7 +75,8 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// 先解析为map,处理类型不匹配的情况
|
||||
var reqMap map[string]interface{}
|
||||
if err := json.Unmarshal(body, &reqMap); err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "invalid request format")
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to unmarshal request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -107,7 +111,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// 处理instanceInfo字段
|
||||
instanceInfoMap, ok := reqMap["instanceInfo"].(map[string]interface{})
|
||||
if !ok {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "invalid instanceInfo format")
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceInfo format")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -137,24 +141,27 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// 重新序列化为JSON,用于ValidateRequestWithBody
|
||||
reqBody, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "invalid request format")
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to marshal request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
||||
return
|
||||
}
|
||||
|
||||
userID, _, err := ValidateRequestWithBody(w, r, reqBody)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to validate request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := CheckPermission(userID, "superuser", "admin"); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to check permission: %v", err))
|
||||
SendErrorResponse(w, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if req.InstanceInfo.Name == "" || req.InstanceInfo.ServerAddr == "" ||
|
||||
req.InstanceInfo.ServerPort == "" || req.InstanceInfo.AuthMethod == "" {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "missing required fields in instanceInfo")
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in instanceInfo")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -165,13 +172,15 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
user, err := GetUserByID(userID)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to get user info")
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
configDir, err := GetConfigDir()
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to get config directory")
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to get config directory: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get config directory")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -180,7 +189,8 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
configContent := generateFrpcConfig(req.InstanceInfo)
|
||||
if err := os.WriteFile(configPath, []byte(configContent), 0644); err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to create config file")
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to create config file %s: %v", configPath, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to create config file")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -192,7 +202,8 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if err != nil {
|
||||
os.Remove(configPath)
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to save instance to database")
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to save instance %s to database: %v", req.InstanceInfo.Name, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to save instance to database")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -200,12 +211,13 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err := createBootService(user.Username, req.InstanceInfo.Name, configPath, runUser); err != nil {
|
||||
frpcDB.Exec("DELETE FROM frpcInstances WHERE userID = ? AND name = ?", userID, req.InstanceInfo.Name)
|
||||
os.Remove(configPath)
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to create boot service")
|
||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to create boot service for instance %s: %v", req.InstanceInfo.Name, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to create boot service")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
SendSuccessResponse(w, "instance created successfully", map[string]interface{}{
|
||||
SendSuccessResponse(w, "Instance created successfully", map[string]interface{}{
|
||||
"name": req.InstanceInfo.Name,
|
||||
"configPath": configPath,
|
||||
"bootAtStart": req.BootAtStart,
|
||||
@@ -214,31 +226,35 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName string) {
|
||||
if r.Method != http.MethodPost {
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "invalid request method")
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "failed to read request body")
|
||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to read request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
userID, _, err := ValidateRequestWithBody(w, r, body)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to validate request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := CheckPermission(userID, "superuser", "admin"); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to check permission: %v", err))
|
||||
SendErrorResponse(w, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
user, err := GetUserByID(userID)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to get user info")
|
||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -255,68 +271,78 @@ func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to query instance")
|
||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to query instance: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
||||
return
|
||||
}
|
||||
|
||||
if instance.BootAtStart {
|
||||
if err := removeBootService(user.Username, instanceName); err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to remove boot service")
|
||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to remove boot service for instance %s: %v", instanceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove boot service")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(instance.ConfigPath); err == nil {
|
||||
if err := os.Remove(instance.ConfigPath); err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to remove config file")
|
||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to remove config file %s: %v", instance.ConfigPath, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove config file")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_, err = frpcDB.Exec("DELETE FROM frpcInstances WHERE id = ?", instance.ID)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to delete instance from database")
|
||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to delete instance %s from database: %v", instanceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to delete instance from database")
|
||||
return
|
||||
}
|
||||
|
||||
SendSuccessResponse(w, "instance deleted successfully", map[string]interface{}{
|
||||
SendSuccessResponse(w, "Instance deleted successfully", map[string]interface{}{
|
||||
"name": instanceName,
|
||||
})
|
||||
}
|
||||
|
||||
func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName string) {
|
||||
if r.Method != http.MethodPost {
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "invalid request method")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Invalid request method: %s", r.Method))
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "failed to read request body")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to read request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
var reqMap map[string]interface{}
|
||||
if err := json.Unmarshal(body, &reqMap); err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "invalid request format")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to unmarshal request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
||||
return
|
||||
}
|
||||
|
||||
userID, _, err := ValidateRequestWithBody(w, r, body)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to validate request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := CheckPermission(userID, "superuser", "admin"); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to check permission: %v", err))
|
||||
SendErrorResponse(w, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
user, err := GetUserByID(userID)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to get user info")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -333,7 +359,8 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to query instance")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to query instance: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -368,7 +395,8 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName
|
||||
if newName != instance.Name || newRunUser != instance.RunUser {
|
||||
configDir, err := GetConfigDir()
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to get config directory")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to get config directory: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get config directory")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -378,7 +406,8 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName
|
||||
if oldConfigPath != newConfigPath {
|
||||
if _, err := os.Stat(oldConfigPath); err == nil {
|
||||
if err := os.Rename(oldConfigPath, newConfigPath); err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to rename config file")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to rename config file %s to %s: %v", oldConfigPath, newConfigPath, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to rename config file")
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -397,7 +426,8 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName
|
||||
|
||||
configContent := generateFrpcConfig(info)
|
||||
if err := os.WriteFile(newConfigPath, []byte(configContent), 0644); err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to update config file")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to update config file: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to update config file")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -408,7 +438,8 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName
|
||||
`, newName, newServerAddr, newServerPort, newAuthMethod, newBootAtStart, newRunUser, newConfigPath, instance.ID)
|
||||
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to update instance in database")
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to update instance in database: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to update instance in database")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -421,7 +452,7 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName
|
||||
createBootService(user.Username, newName, newConfigPath, newRunUser)
|
||||
}
|
||||
|
||||
SendSuccessResponse(w, "instance modified successfully", map[string]interface{}{
|
||||
SendSuccessResponse(w, "Instance modified successfully", map[string]interface{}{
|
||||
"name": newName,
|
||||
"configPath": newConfigPath,
|
||||
})
|
||||
@@ -429,19 +460,21 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, instanceName
|
||||
|
||||
func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "invalid request method")
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
|
||||
return
|
||||
}
|
||||
|
||||
userID, _, err := ValidateRequestWithHeader(w, r)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to validate request: %v", err))
|
||||
SendErrorResponse(w, http.StatusUnauthorized, "Failed to validate request")
|
||||
return
|
||||
}
|
||||
|
||||
userType, err := GetUserType(userID)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to get user type")
|
||||
postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to get user type: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user type")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -450,7 +483,8 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
FROM frpcInstances WHERE userID = ?
|
||||
`, userID)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to query instances")
|
||||
postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to query instances: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instances")
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
@@ -463,7 +497,8 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
&instance.ID, &instance.UserID, &instance.Name, &instance.ServerAddr, &instance.ServerPort,
|
||||
&instance.AuthMethod, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &createdAtStr,
|
||||
); err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "failed to scan instance")
|
||||
postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to scan instance: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to scan instance")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -491,7 +526,7 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
instances = []map[string]interface{}{}
|
||||
}
|
||||
|
||||
SendSuccessResponse(w, "instances retrieved successfully", instances)
|
||||
SendSuccessResponse(w, "Instances retrieved successfully", instances)
|
||||
}
|
||||
|
||||
func generateFrpcConfig(info InstanceInfo) string {
|
||||
@@ -511,6 +546,7 @@ func generateFrpcConfig(info InstanceInfo) string {
|
||||
func GetConfigDir() (string, error) {
|
||||
config, err := GetConfig()
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetConfigDir] Failed to get config: %v", err))
|
||||
return "", err
|
||||
}
|
||||
return config.InstancePath, nil
|
||||
@@ -519,6 +555,7 @@ func GetConfigDir() (string, error) {
|
||||
func GetFrpcPath() (string, error) {
|
||||
config, err := GetConfig()
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetFrpcPath] Failed to get config: %v", err))
|
||||
return "", err
|
||||
}
|
||||
return config.FrpcPath, nil
|
||||
|
||||
Reference in New Issue
Block a user