Files
nomad/command/agent_monitor.go
Drew Bailey f74bd99b2a monitor command takes no args
rm extra new line

fix lint errors

return after close

fix, simplify test
2019-11-05 09:51:55 -05:00

136 lines
2.8 KiB
Go

package command
import (
"fmt"
"io"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"
"github.com/hashicorp/nomad/api"
"github.com/mitchellh/cli"
)
type MonitorCommand struct {
Meta
}
func (c *MonitorCommand) Help() string {
helpText := `
Usage: nomad monitor [options]
Shows recent log messages of a nomad agent, and attaches to the agent,
outputting log messagse as they occur in real time. The monitor lets you
listen for log levels that may be filtered out of the Nomad agent. For
example your agent may only be logging at INFO level, but with the monitor
command you can set -log-level DEBUG
General Options:
` + generalOptionsUsage() + `
Monitor Specific Options:
-log-level <level>
Sets the log level to monitor (default: INFO)
-node-id <node-id>
Sets the specific node to monitor
-log-json <true|false>
Sets log output to JSON format
`
return strings.TrimSpace(helpText)
}
func (c *MonitorCommand) Synopsis() string {
return "stream logs from a nomad agent"
}
func (c *MonitorCommand) Name() string { return "monitor" }
func (c *MonitorCommand) Run(args []string) int {
c.Ui = &cli.PrefixedUi{
OutputPrefix: " ",
InfoPrefix: " ",
ErrorPrefix: "==> ",
Ui: c.Ui,
}
var logLevel string
var nodeID string
var logJSON bool
flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.StringVar(&logLevel, "log-level", "", "")
flags.StringVar(&nodeID, "node-id", "", "")
flags.BoolVar(&logJSON, "log-json", false, "")
if err := flags.Parse(args); err != nil {
return 1
}
args = flags.Args()
if l := len(args); l != 0 {
c.Ui.Error("This command takes no arguments")
c.Ui.Error(commandErrorText(c))
return 1
}
client, err := c.Meta.Client()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
c.Ui.Error(commandErrorText(c))
return 1
}
params := map[string]string{
"log_level": logLevel,
"node_id": nodeID,
"log_json": strconv.FormatBool(logJSON),
}
query := &api.QueryOptions{
Params: params,
}
eventDoneCh := make(chan struct{})
frames, errCh := client.Agent().Monitor(eventDoneCh, query)
select {
case err := <-errCh:
c.Ui.Error(fmt.Sprintf("Error starting monitor: %s", err))
c.Ui.Error(commandErrorText(c))
return 1
default:
}
// Create a reader
var r io.ReadCloser
frameReader := api.NewFrameReader(frames, errCh, eventDoneCh)
frameReader.SetUnblockTime(500 * time.Millisecond)
r = frameReader
defer r.Close()
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
go func() {
<-signalCh
// End the streaming
r.Close()
}()
_, err = io.Copy(os.Stdout, r)
if err != nil {
c.Ui.Error(fmt.Sprintf("error monitoring logs: %s", err))
return 1
}
return 0
}