172 lines
3.9 KiB
Go
172 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"tianji-reporter/utils"
|
|
"time"
|
|
)
|
|
|
|
type ReportData struct {
|
|
WorkspaceId string `json:"workspaceId"`
|
|
Name string `json:"name"`
|
|
Hostname string `json:"hostname"`
|
|
Timeout int `json:"timeout"` // if service receive after timeout second, its means client are offline
|
|
Payload utils.ReportDataPayload `json:"payload"`
|
|
}
|
|
|
|
var (
|
|
Mode = flag.String("mode", "http", "The send mode of report data, you can select: 'http' or 'udp', default is 'http'")
|
|
Url = flag.String("url", "", "The http url of tianji, for example: https://tianji.msgbyte.com")
|
|
WorkspaceId = flag.String("workspace", "", "The workspace id for tianji, this should be a uuid")
|
|
Name = flag.String("name", "", "The identification name for this machine")
|
|
Interval = flag.Int("interval", 5.0, "Input the INTERVAL, seconed")
|
|
IsVnstat = flag.Bool("vnstat", false, "Use vnstat for traffic statistics, linux only")
|
|
)
|
|
|
|
var version = "1.0.0"
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
parsedURL, err := url.Parse(*Url)
|
|
|
|
if err != nil {
|
|
log.Fatal("Invalid URL:", err)
|
|
}
|
|
|
|
if parsedURL.Scheme == "" {
|
|
log.Fatal("Invalid URL: Missing scheme")
|
|
}
|
|
|
|
if *WorkspaceId == "" {
|
|
log.Fatal("WORKSPACE_ID must not be blank!")
|
|
}
|
|
|
|
hostname, _ := os.Hostname()
|
|
var name string
|
|
if *Name != "" {
|
|
name = *Name
|
|
} else {
|
|
name = hostname
|
|
}
|
|
|
|
interval := *Interval
|
|
|
|
ticker := time.NewTicker(time.Duration(interval) * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
httpClient := &http.Client{}
|
|
|
|
log.Println("Start reporting...")
|
|
log.Println("Mode:", *Mode)
|
|
log.Println("Version:", version)
|
|
|
|
for {
|
|
log.Println("Sending report data to:", parsedURL.String())
|
|
payload := ReportData{
|
|
WorkspaceId: *WorkspaceId,
|
|
Name: name,
|
|
Hostname: hostname,
|
|
Timeout: interval * 5,
|
|
Payload: utils.GetReportDataPaylod(interval, *IsVnstat),
|
|
}
|
|
|
|
if *Mode == "udp" {
|
|
sendUDPPack(*parsedURL, payload)
|
|
} else {
|
|
sendHTTPRequest(*parsedURL, payload, httpClient)
|
|
}
|
|
|
|
<-ticker.C
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send UDP Pack to report server data
|
|
*/
|
|
func sendUDPPack(url url.URL, payload ReportData) {
|
|
// parse target url
|
|
addr, err := net.ResolveUDPAddr("udp", url.Hostname()+":"+url.Port())
|
|
if err != nil {
|
|
log.Println("Error resolving address:", err)
|
|
return
|
|
}
|
|
|
|
// create UDP connection
|
|
conn, err := net.DialUDP("udp", nil, addr)
|
|
if err != nil {
|
|
log.Println("Error creating connection:", err)
|
|
return
|
|
}
|
|
defer conn.Close()
|
|
|
|
// serialized message
|
|
jsonData, err := jsoniter.Marshal(payload)
|
|
log.Printf("[Report] %s\n", jsonData)
|
|
if err != nil {
|
|
log.Println("Error encoding JSON:", err)
|
|
return
|
|
}
|
|
|
|
// Send message
|
|
_, err = conn.Write(jsonData)
|
|
if err != nil {
|
|
log.Println("Error sending message:", err)
|
|
return
|
|
}
|
|
|
|
log.Println("Message sent successfully!")
|
|
}
|
|
|
|
/**
|
|
* Send HTTP Request to report server data
|
|
*/
|
|
func sendHTTPRequest(_url url.URL, payload ReportData, client *http.Client) {
|
|
jsonData, err := jsoniter.Marshal(payload)
|
|
if err != nil {
|
|
log.Println("Error encoding JSON:", err)
|
|
return
|
|
}
|
|
log.Printf("[Report] %s\n", jsonData)
|
|
|
|
reportUrl, err := url.JoinPath(_url.String(), "/serverStatus/report")
|
|
if err != nil {
|
|
log.Println("Join url error:", err)
|
|
return
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", reportUrl, bytes.NewBuffer(jsonData))
|
|
if err != nil {
|
|
log.Println("Create request error:", err)
|
|
return
|
|
}
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("x-tianji-report-version", version)
|
|
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
log.Println("Send request error:", err)
|
|
return
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
// Read response
|
|
body := new(bytes.Buffer)
|
|
_, err = body.ReadFrom(resp.Body)
|
|
if err != nil {
|
|
log.Println("Read response error:", err)
|
|
return
|
|
}
|
|
|
|
log.Println("Response:", body)
|
|
}
|