Browse Source

Merge branch 'sig-coolness'

Blallo 5 years ago
parent
commit
19045d9b25
4 changed files with 154 additions and 10 deletions
  1. 90 0
      cmd/circologctl/main.go
  2. 51 7
      cmd/circologd/http_ctl.go
  3. 12 2
      cmd/circologd/main.go
  4. 1 1
      hub.go

+ 90 - 0
cmd/circologctl/main.go

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

+ 51 - 7
cmd/circologd/http_ctl.go

@@ -2,21 +2,30 @@ package main
 
 import (
 	"encoding/json"
+	"fmt"
+	"log"
 	"net/http"
+	"os"
 
+	fractal "git.lattuga.net/blallo/gotools/formatting"
 	"git.lattuga.net/boyska/circolog"
 	"github.com/gorilla/mux"
 )
 
-func setupHTTPCtl(hub circolog.Hub) *mux.Router {
-	mux := mux.NewRouter()
-	mux.HandleFunc("/pause/toggle", togglePause(hub)).Methods("POST")
-	mux.HandleFunc("/logs/clear", clearQueue(hub)).Methods("POST")
-	return mux
+func setupHTTPCtl(hub circolog.Hub, verbose bool) *mux.Router {
+	m := mux.NewRouter()
+	m.HandleFunc("/pause/toggle", togglePause(hub, verbose)).Methods("POST")
+	m.HandleFunc("/logs/clear", clearQueue(hub, verbose)).Methods("POST")
+	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) {
+		if verbose {
+			log.Printf("[%s] %s - toggled pause", r.Method, r.RemoteAddr)
+		}
 		hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandPauseToggle}
 		resp := <-hub.Responses
 		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) {
+		if verbose {
+			log.Printf("[%s] %s - cleared queue", r.Method, r.RemoteAddr)
+		}
 		hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandClear}
 		resp := <-hub.Responses
 		success := resp.Value.(bool)
@@ -36,3 +48,35 @@ func clearQueue(hub circolog.Hub) http.HandlerFunc {
 		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!")
+	}
+}

+ 12 - 2
cmd/circologd/main.go

@@ -29,10 +29,11 @@ func main() {
 	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!")
 	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()
 
 	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)
 	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 != "" {
 		fmt.Printf("Binding address `%s` [http]\n", *ctlSocket)
 		unixListener, err := net.Listen("unix", *ctlSocket)
@@ -115,6 +116,15 @@ func main() {
 					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 {
 				log.Println("Quitting because of signal", sig)
 				server.Kill()

+ 1 - 1
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() {
 	buf := h.circbuf
 	for i := 0; i < buf.Len(); i++ {