tianji/reporter/main.go
2024-10-19 01:37:57 +08:00

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)
}