From 69eb72af8e1a4fa9b4d3058455fffc5dc614d069 Mon Sep 17 00:00:00 2001 From: Yasen Pramatarov Date: Tue, 3 Sep 2024 00:04:13 +0300 Subject: [PATCH] Adds prosody endpoint --- CHANGELOG.md | 5 ++- README.md | 14 +++------ go/jilo-agent.json | 5 +-- go/main.go | 76 +++++++++++++++++++++++++++++++++++++--------- 4 files changed, 71 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cea70c3..fd5d239 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,7 @@ All notable changes to this project will be documented in this file. ### Added - Initial version in PHP -- Added endpoint for /nginx, /prosody, /jicofo, /nginx -- Added a config file - New version in folder "go", written in Go -- Added endpoint for /nginx +- Added endpoints for /nginx, /prosody, /jicofo, /jvb +- Added a config file and default values - Initial vesion of a build script diff --git a/README.md b/README.md index cb31af3..9880674 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,7 @@ This project is licensed under the GNU General Public License version 2 (GPL-2.0 ## installation -Clone the git repo. Either run the agent with Go or build it and run the executable. - -Run it (for tests mainly): - -```bash -go run main.go -``` +Clone the git repo. Build the agent: @@ -40,10 +34,10 @@ Run the agent ./jilo-agent ``` -Send queries to its port (by default 8081, in order to avoid 80, 8080, 8888; configurable in jilo-agent.json): +Send queries to its port (by default 8080, configurable in jilo-agent.json): ```bash -curl -s http://localhost:8081/nginx -curl -s http://localhost:8081/jicofo +curl -s http://localhost:8080/nginx +curl -s http://localhost:8080/jicofo etc... ``` diff --git a/go/jilo-agent.json b/go/jilo-agent.json index 58695b4..7800538 100644 --- a/go/jilo-agent.json +++ b/go/jilo-agent.json @@ -1,5 +1,6 @@ { - "agent_port": 8080, + "agent_port": 8081, "nginx_port": 80, - "jicofo_stats_url": "http://localhost:8888/stats" + "jicofo_stats_url": "http://localhost:8888/stats", + "jvb_stats_url": "http://localhost:8080/colibri/stats" } diff --git a/go/main.go b/go/main.go index 86210ac..c0797cc 100644 --- a/go/main.go +++ b/go/main.go @@ -27,7 +27,9 @@ import ( type Config struct { AgentPort int `json:"agent_port"` NginxPort int `json:"nginx_port"` + ProsodyPort int `json:"prosody_port"` JicofoStatsURL string `json:"jicofo_stats_url"` + JVBStatsURL string `json:"jvb_stats_url"` } // NginxData holds the nginx data structure for the API response to /nginx @@ -36,12 +38,24 @@ type NginxData struct { NginxConnections int `json:"nginx_connections"` } +// ProsodyData holds the prosody data structure for the API response to /prosody +type ProsodyData struct { + ProsodyState string `json:"prosody_state"` + ProsodyConnections int `json:"prosody_connections"` +} + // JicofoData holds the Jicofo data structure for the API response to /jicofo type JicofoData struct { JicofoState string `json:"jicofo_state"` JicofoAPIData map[string]interface{} `json:"jicofo_api_data"` } +// JVBData holds the JVB data structure for the API response to /jvb +type JVBData struct { + JVBState string `json:"jvb_state"` + JVBAPIData map[string]interface{} `json:"jvb_api_data"` +} + // getServiceState checks the status of the speciied service func getServiceState(service string) string { output, err := exec.Command("systemctl", "is-active", service).Output() @@ -56,12 +70,12 @@ func getServiceState(service string) string { return "not running" } -// getNginxConnections gets the number of active connections to the specified web port -func getNginxConnections(port int) int { +// getServiceConnections gets the number of active connections to the specified port +func getServiceConnections(service string, port int) int { cmd := fmt.Sprintf("netstat -an | grep ':%d' | wc -l", port) output, err := exec.Command("bash", "-c", cmd).Output() if err != nil { - log.Printf("Error counting the Nginx connections: %v", err) + log.Printf("Error counting the \"%v\" connections: %v", service, err) return -1 } connections := strings.TrimSpace(string(output)) @@ -90,32 +104,53 @@ func getJitsiAPIData(service string, url string) map[string]interface{} { } // loadConfig loads the configuration from a JSON config file -func loadConfig(filename string) (Config, error) { - var config Config +func loadConfig(filename string) (Config) { + // default config values + config := Config { + AgentPort: 8081, // default Agent port (we avoid 80, 443, 8080 and 8888) + NginxPort: 80, // default nginx port + ProsodyPort: 5222, // default prosody port + JicofoStatsURL: "http://localhost:8888/stats", // default Jicofo stats URL + JVBStatsURL: "http://localhost:8080/colibri/stats", // default JVB stats URL + } + + // we try to load the config file; use default values otherwise file, err := os.Open(filename) if err != nil { - return config, err + log.Printf("Can't open the config file \"%v\". Using default values.", filename) + return config } defer file.Close() bytes, err := ioutil.ReadAll(file) if err != nil { - return config, err + log.Printf("There was an error reading the config file. Using default values") + return config } if err := json.Unmarshal(bytes, &config); err != nil { - return config, err + log.Printf("Error parsing the config file. Using default values.") } - return config, nil + return config } // nginxHandler handles the /nginx endpoint func nginxHandler(config Config, w http.ResponseWriter, r *http.Request) { data := NginxData { NginxState: getServiceState("nginx"), - NginxConnections: getNginxConnections(config.NginxPort), + NginxConnections: getServiceConnections("nginx", config.NginxPort), + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(data) +} + +// prosodyHandler handles the /prosody endpoint +func prosodyHandler(config Config, w http.ResponseWriter, r *http.Request) { + data := ProsodyData { + ProsodyState: getServiceState("prosody"), + ProsodyConnections: getServiceConnections("prosody", config.ProsodyPort), } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(data) @@ -131,23 +166,36 @@ func jicofoHandler(config Config, w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(data) } +// jvbHandler handles the /jvb endpoint +func jvbHandler(config Config, w http.ResponseWriter, r *http.Request) { + data := JVBData { + JVBState: getServiceState("jitsi-videobridge2"), + JVBAPIData: getJitsiAPIData("jitsi-videobridge2", config.JVBStatsURL), + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(data) +} + // main sets up the http server and the routes func main() { // load the configuration - config, err := loadConfig("jilo-agent.json") - if err != nil { - log.Fatalf("Error loading the config file: %v\n", err) - } + config := loadConfig("jilo-agent.json") // endpoints http.HandleFunc("/nginx", func(w http.ResponseWriter, r *http.Request) { nginxHandler(config, w, r) }) + http.HandleFunc("/prosody", func(w http.ResponseWriter, r *http.Request) { + prosodyHandler(config, w, r) + }) http.HandleFunc("/jicofo", func(w http.ResponseWriter, r *http.Request) { jicofoHandler(config, w, r) }) + http.HandleFunc("/jvb", func(w http.ResponseWriter, r *http.Request) { + jvbHandler(config, w, r) + }) // start the http server agentPortStr := fmt.Sprintf(":%d", config.AgentPort)