/* httpprocwatchd provides HTTP interface to a list of process' statuses formatted as JSON. Copyright (c) 2021 Alexander "Arav" Andreev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package prog import ( "encoding/xml" "os/exec" "strconv" "strings" ) // ProcessList is a map of processes' statuses. type ProcessList map[string]bool // NewProcessList returns a ProcessList with initialised map. func NewProcessList() *ProcessList { pl := make(ProcessList) return &pl } // AddProcess appends a process to a ProcessList func (pl *ProcessList) AddProcess(name string, isup bool) { (*pl)[name] = isup } // ProcessXMLEntry is a XML representation of a process stored in ProcessList. type ProcessXMLEntry struct { XMLName xml.Name Name string `xml:"name,attr"` IsUp bool `xml:",chardata"` } // MarshalXML implements Marshaler interface for a ProcessList. func (l ProcessList) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if len(l) == 0 { return nil } if err := e.EncodeToken(start); err != nil { return err } for key, val := range l { e.Encode(ProcessXMLEntry{ XMLName: xml.Name{Local: "Process"}, Name: key, IsUp: val}) } return e.EncodeToken(start.End()) } // IsProcessUp returns true if process is up, and a list of PIDs for // that process name. Uses pgrep to get PID of a process and if // a process is not working, then pgrep returns nothing. func IsProcessUp(name string) (bool, []int, error) { out, err := exec.Command("pgrep", "-f", name).Output() if err != nil || len(out) < 2 { return false, nil, err } spids := strings.Split(string(out[:len(out)-1]), "\n") pids := make([]int, len(spids)) for i, v := range spids { pids[i], err = strconv.Atoi(v) if err != nil { return false, nil, nil } } return true, pids, nil }