Merge branch 'sig-coolness'
This commit is contained in:
commit
19045d9b25
4 changed files with 154 additions and 10 deletions
90
cmd/circologctl/main.go
Normal file
90
cmd/circologctl/main.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var globalOpts struct {
|
||||||
|
ctlSock string
|
||||||
|
verbose bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type commandFunc func([]string) error
|
||||||
|
|
||||||
|
var cmdMap map[string]commandFunc
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmdMap = map[string]commandFunc{
|
||||||
|
// TODO: implement set and get of config at runtime
|
||||||
|
//"set": setCmd,
|
||||||
|
//"get": getCmd,
|
||||||
|
"pause": pauseCmd,
|
||||||
|
"reload": reloadCmd,
|
||||||
|
"restart": restartCmd,
|
||||||
|
"help": helpCmd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//func setCmd(ctlSock string, args []string) error {}
|
||||||
|
|
||||||
|
//func getCmd(ctlSock string, args []string) error {}
|
||||||
|
|
||||||
|
func pauseCmd(args []string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func reloadCmd(args []string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func restartCmd(args []string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func helpCmd(args []string) error {
|
||||||
|
usage(os.Stdout)
|
||||||
|
os.Exit(0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func usage(w io.Writer) {
|
||||||
|
fmt.Fprintf(w, "USAGE: %s [globalOpts] [SUBCOMMAND] [opts]\n", os.Args[0])
|
||||||
|
fmt.Fprintf(w, "\nSUBCOMMANDS:\n\n")
|
||||||
|
for command := range cmdMap {
|
||||||
|
fmt.Fprintf(w, "\t%s\n", command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseAndRun(args []string) {
|
||||||
|
cmdName := args[0]
|
||||||
|
cmdToRun, ok := cmdMap[cmdName]
|
||||||
|
if !ok {
|
||||||
|
fmt.Fprintf(os.Stderr, "Unknown subcommand: %s\n", cmdName)
|
||||||
|
usage(os.Stderr)
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
err := cmdToRun(args)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error:\n%s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.StringVar(&globalOpts.ctlSock, "ctl-socket", "/tmp/circologd-ctl.sock",
|
||||||
|
"Path to a unix domain socket for the control server; leave empty to disable")
|
||||||
|
flag.BoolVar(&globalOpts.verbose, "verbose", false, "Print more output")
|
||||||
|
flag.Parse()
|
||||||
|
args := flag.Args()
|
||||||
|
if globalOpts.verbose {
|
||||||
|
fmt.Fprintf(os.Stdout, "Args: %v", args)
|
||||||
|
}
|
||||||
|
if len(args) == 0 {
|
||||||
|
usage(os.Stderr)
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
parseAndRun(args)
|
||||||
|
}
|
|
@ -2,21 +2,30 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
fractal "git.lattuga.net/blallo/gotools/formatting"
|
||||||
"git.lattuga.net/boyska/circolog"
|
"git.lattuga.net/boyska/circolog"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupHTTPCtl(hub circolog.Hub) *mux.Router {
|
func setupHTTPCtl(hub circolog.Hub, verbose bool) *mux.Router {
|
||||||
mux := mux.NewRouter()
|
m := mux.NewRouter()
|
||||||
mux.HandleFunc("/pause/toggle", togglePause(hub)).Methods("POST")
|
m.HandleFunc("/pause/toggle", togglePause(hub, verbose)).Methods("POST")
|
||||||
mux.HandleFunc("/logs/clear", clearQueue(hub)).Methods("POST")
|
m.HandleFunc("/logs/clear", clearQueue(hub, verbose)).Methods("POST")
|
||||||
return mux
|
m.HandleFunc("/help", printHelp(verbose)).Methods("GET")
|
||||||
|
m.HandleFunc("/echo", echo(verbose)).Methods("GET")
|
||||||
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func togglePause(hub circolog.Hub) http.HandlerFunc {
|
func togglePause(hub circolog.Hub, verbose bool) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("[%s] %s - toggled pause", r.Method, r.RemoteAddr)
|
||||||
|
}
|
||||||
hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandPauseToggle}
|
hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandPauseToggle}
|
||||||
resp := <-hub.Responses
|
resp := <-hub.Responses
|
||||||
active := resp.Value.(bool)
|
active := resp.Value.(bool)
|
||||||
|
@ -26,8 +35,11 @@ func togglePause(hub circolog.Hub) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearQueue(hub circolog.Hub) http.HandlerFunc {
|
func clearQueue(hub circolog.Hub, verbose bool) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("[%s] %s - cleared queue", r.Method, r.RemoteAddr)
|
||||||
|
}
|
||||||
hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandClear}
|
hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandClear}
|
||||||
resp := <-hub.Responses
|
resp := <-hub.Responses
|
||||||
success := resp.Value.(bool)
|
success := resp.Value.(bool)
|
||||||
|
@ -36,3 +48,35 @@ func clearQueue(hub circolog.Hub) http.HandlerFunc {
|
||||||
enc.Encode(map[string]interface{}{"success": success})
|
enc.Encode(map[string]interface{}{"success": success})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printHelp(verbose bool) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("[%s] %s - asked for help", r.Method, r.RemoteAddr)
|
||||||
|
}
|
||||||
|
w.Header().Set("content-type", "application/json")
|
||||||
|
enc := json.NewEncoder(w)
|
||||||
|
var pathsWithDocs = map[string]string{
|
||||||
|
"/pause/toggle": "Toggle the server from pause state (not listening)",
|
||||||
|
"/logs/clear": "Wipe the buffer from all the messages",
|
||||||
|
"/help": "This help",
|
||||||
|
"/echo": "Answers to heartbeat",
|
||||||
|
}
|
||||||
|
fractal.EncodeJSON(pathsWithDocs, enc)
|
||||||
|
if verbose {
|
||||||
|
errEnc := json.NewEncoder(os.Stderr)
|
||||||
|
fractal.EncodeJSON(pathsWithDocs, errEnc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func echo(verbose bool) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("Echo")
|
||||||
|
if verbose {
|
||||||
|
log.Printf("[%s] %s - asked for echo", r.Method, r.RemoteAddr)
|
||||||
|
}
|
||||||
|
w.Header().Set("content-type", "text/plain")
|
||||||
|
fmt.Fprintln(w, "I am on!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,10 +29,11 @@ func main() {
|
||||||
queryAddr := flag.String("query-addr", "127.0.0.1:9080", "Address:port where to bind the query service")
|
queryAddr := flag.String("query-addr", "127.0.0.1:9080", "Address:port where to bind the query service")
|
||||||
querySocket := flag.String("query-socket", "", "Path to a unix domain socket for the HTTP server; recommended for security reasons!")
|
querySocket := flag.String("query-socket", "", "Path to a unix domain socket for the HTTP server; recommended for security reasons!")
|
||||||
ctlSocket := flag.String("ctl-socket", "/tmp/circologd-ctl.sock", "Path to a unix domain socket for the control server; leave empty to disable")
|
ctlSocket := flag.String("ctl-socket", "/tmp/circologd-ctl.sock", "Path to a unix domain socket for the control server; leave empty to disable")
|
||||||
|
verbose := flag.Bool("verbose", false, "Print more output executing the daemon")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
interrupt := make(chan os.Signal, 1)
|
interrupt := make(chan os.Signal, 1)
|
||||||
signal.Notify(interrupt, syscall.SIGINT, syscall.SIGUSR1, syscall.SIGTERM)
|
signal.Notify(interrupt, syscall.SIGINT, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGTERM)
|
||||||
|
|
||||||
hub := circolog.NewHub(*bufsize)
|
hub := circolog.NewHub(*bufsize)
|
||||||
handler := syslog.NewChannelHandler(hub.LogMessages)
|
handler := syslog.NewChannelHandler(hub.LogMessages)
|
||||||
|
@ -85,7 +86,7 @@ func main() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
httpCtlServer := http.Server{Handler: setupHTTPCtl(hub)}
|
httpCtlServer := http.Server{Handler: setupHTTPCtl(hub, *verbose)}
|
||||||
if *ctlSocket != "" {
|
if *ctlSocket != "" {
|
||||||
fmt.Printf("Binding address `%s` [http]\n", *ctlSocket)
|
fmt.Printf("Binding address `%s` [http]\n", *ctlSocket)
|
||||||
unixListener, err := net.Listen("unix", *ctlSocket)
|
unixListener, err := net.Listen("unix", *ctlSocket)
|
||||||
|
@ -115,6 +116,15 @@ func main() {
|
||||||
log.Println("paused")
|
log.Println("paused")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if sig == syscall.SIGUSR2 {
|
||||||
|
hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandClear}
|
||||||
|
resp := <-hub.Responses
|
||||||
|
if resp.Value.(bool) {
|
||||||
|
log.Println("buffer cleaned")
|
||||||
|
} else {
|
||||||
|
log.Println("buffer NOT cleaned")
|
||||||
|
}
|
||||||
|
}
|
||||||
if sig == syscall.SIGTERM || sig == syscall.SIGINT {
|
if sig == syscall.SIGTERM || sig == syscall.SIGINT {
|
||||||
log.Println("Quitting because of signal", sig)
|
log.Println("Quitting because of signal", sig)
|
||||||
server.Kill()
|
server.Kill()
|
||||||
|
|
2
hub.go
2
hub.go
|
@ -135,7 +135,7 @@ func (h *Hub) Run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear removes every all elements from the buffer
|
// Clear removes all elements from the buffer
|
||||||
func (h *Hub) clear() {
|
func (h *Hub) clear() {
|
||||||
buf := h.circbuf
|
buf := h.circbuf
|
||||||
for i := 0; i < buf.Len(); i++ {
|
for i := 0; i < buf.Len(); i++ {
|
||||||
|
|
Loading…
Reference in a new issue