package main import ( "encoding/json" "flag" "fmt" log "github.com/sirupsen/logrus" "os/exec" "strings" ) type TF2Stat struct { Name string `json:"name"` Map string `json:"map"` Password bool `json:"password"` MaxPlayers int `json:"maxplayers"` NumPlayers int `json:"numplayers"` QueryPort int `json:"queryPort"` Ping int `json:"ping"` Error *string `json:"error,omitempty"` } type TF2Server string var ( server = flag.String("server", "", "comma seperated list of addresses to query") oldIDs = flag.Bool("oldids", false, "use old gamedig IDs") ) func main() { flag.Parse() servers := strings.Split(*server, ",") var tServer []TF2Server for _, srv := range servers { tServer = append(tServer, TF2Server(strings.TrimSpace(srv))) } for _, ip := range tServer { tStat, err := ip.Stats() if err != nil { log.Debugf("error retrieving stats for %s: %v", ip, err) continue } escapedName := strings.ReplaceAll(tStat.Name, " ", `\ `) escapedName = strings.ReplaceAll(escapedName, ",", `\,`) escapedName = strings.ReplaceAll(escapedName, "=", `\=`) // myMeasurement,tag1=value1,tag2=value2 fieldKey="fieldValue" 1556813561098000000 fmt.Printf("tf2server,address=%s,name=%s player=%di maxplayer=%di map=%q ping=%di\n", string(ip), escapedName, tStat.NumPlayers, tStat.MaxPlayers, tStat.Map, tStat.Ping) } } func (ip TF2Server) Stats() (*TF2Stat, error) { gameID := "teamfortress2" if *oldIDs { gameID = "tf2" } cmd := exec.Command("gamedig", "--type", gameID, string(ip)) bOut, err := cmd.CombinedOutput() if err != nil { return nil, err } nStat := new(TF2Stat) if err = json.Unmarshal(bOut, &nStat); err != nil { return nil, err } if nStat.Error != nil { return nil, fmt.Errorf("gamedig returned error: %v", *nStat.Error) } return nStat, nil }