Adds prosody endpoint

main
Yasen Pramatarov 2024-09-03 00:04:13 +03:00
parent abb4484731
commit 69eb72af8e
4 changed files with 71 additions and 29 deletions

View File

@ -14,8 +14,7 @@ All notable changes to this project will be documented in this file.
### Added ### Added
- Initial version in PHP - Initial version in PHP
- Added endpoint for /nginx, /prosody, /jicofo, /nginx
- Added a config file
- New version in folder "go", written in Go - 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 - Initial vesion of a build script

View File

@ -14,13 +14,7 @@ This project is licensed under the GNU General Public License version 2 (GPL-2.0
## installation ## installation
Clone the git repo. Either run the agent with Go or build it and run the executable. Clone the git repo.
Run it (for tests mainly):
```bash
go run main.go
```
Build the agent: Build the agent:
@ -40,10 +34,10 @@ Run the agent
./jilo-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 ```bash
curl -s http://localhost:8081/nginx curl -s http://localhost:8080/nginx
curl -s http://localhost:8081/jicofo curl -s http://localhost:8080/jicofo
etc... etc...
``` ```

View File

@ -1,5 +1,6 @@
{ {
"agent_port": 8080, "agent_port": 8081,
"nginx_port": 80, "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"
} }

View File

@ -27,7 +27,9 @@ import (
type Config struct { type Config struct {
AgentPort int `json:"agent_port"` AgentPort int `json:"agent_port"`
NginxPort int `json:"nginx_port"` NginxPort int `json:"nginx_port"`
ProsodyPort int `json:"prosody_port"`
JicofoStatsURL string `json:"jicofo_stats_url"` JicofoStatsURL string `json:"jicofo_stats_url"`
JVBStatsURL string `json:"jvb_stats_url"`
} }
// NginxData holds the nginx data structure for the API response to /nginx // NginxData holds the nginx data structure for the API response to /nginx
@ -36,12 +38,24 @@ type NginxData struct {
NginxConnections int `json:"nginx_connections"` 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 // JicofoData holds the Jicofo data structure for the API response to /jicofo
type JicofoData struct { type JicofoData struct {
JicofoState string `json:"jicofo_state"` JicofoState string `json:"jicofo_state"`
JicofoAPIData map[string]interface{} `json:"jicofo_api_data"` 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 // getServiceState checks the status of the speciied service
func getServiceState(service string) string { func getServiceState(service string) string {
output, err := exec.Command("systemctl", "is-active", service).Output() output, err := exec.Command("systemctl", "is-active", service).Output()
@ -56,12 +70,12 @@ func getServiceState(service string) string {
return "not running" return "not running"
} }
// getNginxConnections gets the number of active connections to the specified web port // getServiceConnections gets the number of active connections to the specified port
func getNginxConnections(port int) int { func getServiceConnections(service string, port int) int {
cmd := fmt.Sprintf("netstat -an | grep ':%d' | wc -l", port) cmd := fmt.Sprintf("netstat -an | grep ':%d' | wc -l", port)
output, err := exec.Command("bash", "-c", cmd).Output() output, err := exec.Command("bash", "-c", cmd).Output()
if err != nil { if err != nil {
log.Printf("Error counting the Nginx connections: %v", err) log.Printf("Error counting the \"%v\" connections: %v", service, err)
return -1 return -1
} }
connections := strings.TrimSpace(string(output)) 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 // loadConfig loads the configuration from a JSON config file
func loadConfig(filename string) (Config, error) { func loadConfig(filename string) (Config) {
var config 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) file, err := os.Open(filename)
if err != nil { if err != nil {
return config, err log.Printf("Can't open the config file \"%v\". Using default values.", filename)
return config
} }
defer file.Close() defer file.Close()
bytes, err := ioutil.ReadAll(file) bytes, err := ioutil.ReadAll(file)
if err != nil { 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 { 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 // nginxHandler handles the /nginx endpoint
func nginxHandler(config Config, w http.ResponseWriter, r *http.Request) { func nginxHandler(config Config, w http.ResponseWriter, r *http.Request) {
data := NginxData { data := NginxData {
NginxState: getServiceState("nginx"), 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") w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data) json.NewEncoder(w).Encode(data)
@ -131,23 +166,36 @@ func jicofoHandler(config Config, w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(data) 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 // main sets up the http server and the routes
func main() { func main() {
// load the configuration // load the configuration
config, err := loadConfig("jilo-agent.json") config := loadConfig("jilo-agent.json")
if err != nil {
log.Fatalf("Error loading the config file: %v\n", err)
}
// endpoints // endpoints
http.HandleFunc("/nginx", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/nginx", func(w http.ResponseWriter, r *http.Request) {
nginxHandler(config, w, r) 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) { http.HandleFunc("/jicofo", func(w http.ResponseWriter, r *http.Request) {
jicofoHandler(config, w, r) jicofoHandler(config, w, r)
}) })
http.HandleFunc("/jvb", func(w http.ResponseWriter, r *http.Request) {
jvbHandler(config, w, r)
})
// start the http server // start the http server
agentPortStr := fmt.Sprintf(":%d", config.AgentPort) agentPortStr := fmt.Sprintf(":%d", config.AgentPort)