diff --git a/config/config.go b/config/config.go
index e1c2e84..13ec9c8 100644
--- a/config/config.go
+++ b/config/config.go
@@ -57,17 +57,29 @@ func LoadConfig(configPath string, getInitSystem func() string) error {
return fmt.Errorf("failed to parse config file: %w", err)
}
- if fileConfig.ListenAddr != "" {
- global.CurrentConfig.ListenAddr = fileConfig.ListenAddr
+ global.CurrentConfig.ListenAddr = fileConfig.ListenAddr
+ global.CurrentConfig.ListenPort = fileConfig.ListenPort
+ global.CurrentConfig.FrpcPath = fileConfig.FrpcPath
+ global.CurrentConfig.InstancePath = fileConfig.InstancePath
+ global.CurrentConfig.Debug = fileConfig.Debug
+ global.CurrentConfig.Watchdog.Enabled = fileConfig.Watchdog.Enabled
+ global.CurrentConfig.Watchdog.Port = fileConfig.Watchdog.Port
+ global.CurrentConfig.Notification.Enabled = fileConfig.Notification.Enabled
+ global.CurrentConfig.Notification.Method = fileConfig.Notification.Method
+ global.CurrentConfig.Webhook.Method = fileConfig.Webhook.Method
+ global.CurrentConfig.Webhook.URL = fileConfig.Webhook.URL
+ global.CurrentConfig.Webhook.Headers = fileConfig.Webhook.Headers
+ global.CurrentConfig.Webhook.Body = fileConfig.Webhook.Body
+
+ if fileConfig.ListenAddr == "" {
+ global.CurrentConfig.ListenAddr = "0.0.0.0"
}
- if fileConfig.ListenPort != "" {
- global.CurrentConfig.ListenPort = fileConfig.ListenPort
+ if fileConfig.ListenPort == "" {
+ global.CurrentConfig.ListenPort = "7000"
}
- if fileConfig.FrpcPath != "" {
- global.CurrentConfig.FrpcPath = fileConfig.FrpcPath
- } else {
+ if fileConfig.FrpcPath == "" {
if getInitSystem() == "windows" {
global.CurrentConfig.FrpcPath = "frp_client/frpc.exe"
} else {
@@ -75,22 +87,14 @@ func LoadConfig(configPath string, getInitSystem func() string) error {
}
}
- if fileConfig.InstancePath != "" {
- global.CurrentConfig.InstancePath = fileConfig.InstancePath
- } else {
+ if fileConfig.InstancePath == "" {
global.CurrentConfig.InstancePath = "./configs"
}
- global.CurrentConfig.Debug = fileConfig.Debug
-
- if fileConfig.Watchdog.Port != 0 {
- global.CurrentConfig.Watchdog.Port = fileConfig.Watchdog.Port
- } else {
+ if fileConfig.Watchdog.Port == 0 {
global.CurrentConfig.Watchdog.Port = 12380
}
- global.CurrentConfig.Watchdog.Enabled = fileConfig.Watchdog.Enabled
-
if err := os.MkdirAll(global.CurrentConfig.InstancePath, 0755); err != nil {
return fmt.Errorf("failed to create config directory: %w", err)
}
diff --git a/global/global.go b/global/global.go
index 39e3c5f..b89b840 100644
--- a/global/global.go
+++ b/global/global.go
@@ -51,53 +51,49 @@ type Config struct {
Debug bool `json:"debug"`
Watchdog struct {
Enabled bool `json:"enabled"`
- Port int `json:"port"`
+ Port int `json:"port"`
} `json:"watchdog"`
Notification struct {
- Enabled bool `json:"enabled"`
+ Enabled bool `json:"enabled"`
Method string `json:"method"`
} `json:"notification"`
Webhook struct {
- Method string `json:"method"`
- URL string `json:"url"`
- Headers map[string]string `json:"headers"`
- Body map[string]string `json:"body"`
+ Method string `json:"method"`
+ URL string `json:"url"`
+ Headers string `json:"headers"`
+ Body string `json:"body"`
} `json:"webhook"`
}
var CurrentConfig = Config{
- ListenAddr: "0.0.0.0",
- ListenPort: "7000",
- FrpcPath: "",
+ ListenAddr: "0.0.0.0",
+ ListenPort: "7000",
+ FrpcPath: "",
InstancePath: "",
Debug: false,
- Watchdog: struct {
+ Watchdog: struct {
Enabled bool `json:"enabled"`
- Port int `json:"port"`
+ Port int `json:"port"`
}{
Enabled: false,
- Port: 0,
+ Port: 0,
},
Notification: struct {
- Enabled bool `json:"enabled"`
+ Enabled bool `json:"enabled"`
Method string `json:"method"`
}{
Enabled: false,
Method: "webhook",
},
Webhook: struct {
- Method string `json:"method"`
- URL string `json:"url"`
- Headers map[string]string `json:"headers"`
- Body map[string]string `json:"body"`
+ Method string `json:"method"`
+ URL string `json:"url"`
+ Headers string `json:"headers"`
+ Body string `json:"body"`
}{
Method: "",
URL: "",
- Headers: map[string]string{
- "Content-Type": "",
- },
- Body: map[string]string{
- "text": "",
- },
+ Headers: "Content-Type: application/json",
+ Body: "",
},
}
diff --git a/watchdog/command.go b/watchdog/command.go
index d8e96a5..b61c854 100644
--- a/watchdog/command.go
+++ b/watchdog/command.go
@@ -3,6 +3,7 @@ package watchdog
import (
"fmt"
"super-frpc/postLog"
+ "super-frpc/utils"
)
func AddInstance(serviceName string) bool {
@@ -70,4 +71,17 @@ func Close() bool {
}
return false
+}
+
+func parseCommand(cmd string) (result string, err error) {
+ cmdType := utils.GetCmdType(cmd)
+ if cmdType == "Exception" {
+ // Watchdog msg: [Exception] ... ... ...
+ exceptionType := utils.GetCmdParams(cmd, "exceptionType")
+ serviceName := utils.GetCmdParams(cmd, "serviceName")
+ errorMsg := utils.GetCmdParams(cmd, "errorMsg")
+ postLog.Error(fmt.Sprintf("[Watchdog] Exception[%s]: %s, %s", serviceName, exceptionType, errorMsg))
+ exceptionHandle(exceptionType, serviceName, errorMsg)
+ }
+ return "", nil
}
\ No newline at end of file
diff --git a/watchdog/processor.go b/watchdog/processor.go
index 19744df..c9c1326 100644
--- a/watchdog/processor.go
+++ b/watchdog/processor.go
@@ -1,18 +1,26 @@
package watchdog
import (
+ "encoding/json"
"fmt"
"strings"
"super-frpc/global"
+ "super-frpc/postLog"
"super-frpc/webhook"
)
func exceptionHandle(exceptionType string, serviceName string, errorMsg string) {
if global.CurrentConfig.Notification.Enabled {
- body := make(map[string]string)
- if global.CurrentConfig.Notification.Method == "Webhook" {
- for k, v := range global.CurrentConfig.Webhook.Body {
+ if global.CurrentConfig.Notification.Method == "webhook" {
+ var bodyMap map[string]string
+ err := json.Unmarshal([]byte(global.CurrentConfig.Webhook.Body), &bodyMap)
+ if err != nil {
+ postLog.Error(fmt.Sprintf("[exceptionHandler] Failed to parse webhook body: %v", err))
+ return
+ }
+
+ for k, v := range bodyMap {
replaced := v
for strings.Contains(replaced, "{{ exceptionType }}") ||
strings.Contains(replaced, "{{ serviceName }}") ||
@@ -21,17 +29,33 @@ func exceptionHandle(exceptionType string, serviceName string, errorMsg string)
replaced = strings.ReplaceAll(replaced, "{{ serviceName }}", serviceName)
replaced = strings.ReplaceAll(replaced, "{{ exceptionMsg }}", errorMsg)
}
- body[k] = replaced
+ bodyMap[k] = replaced
}
- bodyJSON := ""
- for k, v := range body {
- bodyJSON = fmt.Sprintf(`{"%s": "%s"}`, k, v)
- break
+ bodyJSON, err := json.Marshal(bodyMap)
+ if err != nil {
+ postLog.Error(fmt.Sprintf("[exceptionHandler] Failed to marshal webhook body: %v", err))
+ return
}
- webhook.SendHook(global.CurrentConfig.Webhook.URL, global.CurrentConfig.Webhook.Method, global.CurrentConfig.Webhook.Headers, bodyJSON)
+ // Parse headers as map[string]string format
+ headersMap := make(map[string]string)
+ headerPairs := strings.Split(global.CurrentConfig.Webhook.Headers, ";")
+ for _, pair := range headerPairs {
+ pair = strings.TrimSpace(pair)
+ if pair == "" {
+ continue
+ }
+ parts := strings.SplitN(pair, ":", 2)
+ if len(parts) == 2 {
+ headersMap[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
+ }
+ }
+
+ webhook.SendHook(global.CurrentConfig.Webhook.URL, global.CurrentConfig.Webhook.Method, headersMap, string(bodyJSON))
}
+ } else {
+ postLog.Warning("[exceptionHandler] exception occoured, but notification is not enabled!")
}
-
+
}
diff --git a/watchdog/tcpClient.go b/watchdog/tcpClient.go
index 49fee22..7387e85 100644
--- a/watchdog/tcpClient.go
+++ b/watchdog/tcpClient.go
@@ -5,8 +5,6 @@ import (
"fmt"
"net"
"strings"
- "super-frpc/postLog"
- "super-frpc/utils"
"sync"
"time"
)
@@ -117,15 +115,8 @@ func recvMsg() {
}
// Here add logic to handle the message
if !isResponseMessage(line) {
- postLog.Debug(fmt.Sprintf("[Watchdog] TCP Socket received message: %s", line))
- cmdType := utils.GetCmdType(line)
- if cmdType == "Exception" {
- exceptionType := utils.GetCmdParams(line, "exceptionType")
- serviceName := utils.GetCmdParams(line, "serviceName")
- errorMsg := utils.GetCmdParams(line, "errorMsg")
- postLog.Error(fmt.Sprintf("[Watchdog] Exception[%s]: %s, %s", serviceName, exceptionType, errorMsg))
- exceptionHandle(exceptionType, serviceName, errorMsg)
- }
+ // postLog.Debug(fmt.Sprintf("[Watchdog] TCP Socket received message: %s", line))
+ parseCommand(line)
}
}
}
diff --git a/webhook/webhook.go b/webhook/webhook.go
index 4309cb1..32ab658 100644
--- a/webhook/webhook.go
+++ b/webhook/webhook.go
@@ -14,6 +14,7 @@ import (
// If the status code is not 200, it logs the error and returns the status code and response message.
// If the status code is 200, it returns an empty error message, status code, and response message.
func SendHook(url string, method string, headers map[string]string, body string) (err string, code int, msg string) {
+ postLog.Debug(fmt.Sprintf("[SendHook] SendHook { %s, %s, %s, %s }", url, method, headers, body))
req, reqErr := http.NewRequest(method, url, strings.NewReader(body))
if reqErr != nil {
return reqErr.Error(), 500, ""
@@ -34,6 +35,8 @@ func SendHook(url string, method string, headers map[string]string, body string)
if resp.StatusCode != http.StatusOK {
postLog.Debug(fmt.Sprintf("[SendHook] SendHook { %s, %s, %s, %s } failed, status code: %d, response: [%s]: %s", url, method, headers, body, resp.StatusCode, resp.Status, respMsg))
return fmt.Sprintf("unexpected status code: %d, response: [%s]: %s", resp.StatusCode, resp.Status, respMsg), resp.StatusCode, respMsg
+ } else {
+ postLog.Debug(fmt.Sprintf("[SendHook] SendHook { %s, %s, %s, %s } success, status code: %d, response: [%s]: %s", url, method, headers, body, resp.StatusCode, resp.Status, respMsg))
}
return "", 200, ""
}