summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <35781042+pbuetow@users.noreply.github.com>2020-12-27 19:46:24 +0000
committerGitHub <noreply@github.com>2020-12-27 19:46:24 +0000
commit495e9f38220a6d448b15882a235e7a9c21f21d18 (patch)
tree5b59cade83108c1855d07f1f869a0dcb3b9f0907
parentb4db37d8cbae8f0c3dec289b2e1b0cfe83731415 (diff)
parent2c7bdd09e8b7c58d98d631e32a24e4bd34d5bec9 (diff)
Merge pull request #16 from snonux/develop
Multiple minor enhancements.
-rw-r--r--cmd/dcat/main.go1
-rw-r--r--cmd/dgrep/main.go1
-rw-r--r--cmd/dmap/main.go1
-rw-r--r--cmd/dtail/main.go1
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rw-r--r--internal/clients/args.go1
-rw-r--r--internal/clients/baseclient.go6
-rw-r--r--internal/clients/catclient.go3
-rw-r--r--internal/clients/grepclient.go4
-rw-r--r--internal/clients/handlers/basehandler.go18
-rw-r--r--internal/clients/handlers/healthhandler.go1
-rw-r--r--internal/clients/maker.go3
-rw-r--r--internal/clients/maprclient.go9
-rw-r--r--internal/clients/runclient.go87
-rw-r--r--internal/clients/stats.go11
-rw-r--r--internal/clients/tailclient.go4
-rw-r--r--internal/color/colorfy.go12
-rw-r--r--internal/config/common.go10
-rw-r--r--internal/discovery/comma.go3
-rw-r--r--internal/discovery/file.go3
-rw-r--r--internal/io/fs/permissions/permission_linux.go2
-rw-r--r--internal/io/line/line.go6
-rw-r--r--internal/io/logger/logger.go24
-rw-r--r--internal/io/logger/modes.go1
-rw-r--r--internal/io/prompt/prompt.go6
-rw-r--r--internal/io/run/run.go150
-rw-r--r--internal/mapr/funcs/function.go1
-rw-r--r--internal/mapr/query.go6
-rw-r--r--internal/mapr/selectcondition.go1
-rw-r--r--internal/mapr/token.go3
-rw-r--r--internal/mapr/wherecondition.go2
-rw-r--r--internal/omode/mode.go3
-rw-r--r--internal/server/handlers/controlhandler.go4
-rw-r--r--internal/server/handlers/readcommand.go29
-rw-r--r--internal/server/handlers/runcommand.go111
-rw-r--r--internal/server/handlers/serverhandler.go70
-rw-r--r--internal/server/server.go24
-rw-r--r--internal/user/server/user.go4
-rw-r--r--internal/version/version.go2
-rw-r--r--samples/dtail.json.sample9
41 files changed, 147 insertions, 494 deletions
diff --git a/cmd/dcat/main.go b/cmd/dcat/main.go
index 05e46ab..c59a242 100644
--- a/cmd/dcat/main.go
+++ b/cmd/dcat/main.go
@@ -29,6 +29,7 @@ func main() {
flag.BoolVar(&debugEnable, "debug", false, "Activate debug messages")
flag.BoolVar(&displayVersion, "version", false, "Display version")
flag.BoolVar(&noColor, "noColor", false, "Disable ANSII terminal colors")
+ flag.BoolVar(&args.Quiet, "quiet", false, "Quiet output mode")
flag.IntVar(&args.ConnectionsPerCPU, "cpc", 10, "How many connections established per CPU core concurrently")
flag.IntVar(&sshPort, "port", 2222, "SSH server port")
flag.StringVar(&args.Discovery, "discovery", "", "Server discovery method")
diff --git a/cmd/dgrep/main.go b/cmd/dgrep/main.go
index 133631f..276dff4 100644
--- a/cmd/dgrep/main.go
+++ b/cmd/dgrep/main.go
@@ -31,6 +31,7 @@ func main() {
flag.BoolVar(&debugEnable, "debug", false, "Activate debug messages")
flag.BoolVar(&displayVersion, "version", false, "Display version")
flag.BoolVar(&noColor, "noColor", false, "Disable ANSII terminal colors")
+ flag.BoolVar(&args.Quiet, "quiet", false, "Quiet output mode")
flag.IntVar(&args.ConnectionsPerCPU, "cpc", 10, "How many connections established per CPU core concurrently")
flag.IntVar(&sshPort, "port", 2222, "SSH server port")
flag.StringVar(&args.Discovery, "discovery", "", "Server discovery method")
diff --git a/cmd/dmap/main.go b/cmd/dmap/main.go
index 9f9ca9d..a954e45 100644
--- a/cmd/dmap/main.go
+++ b/cmd/dmap/main.go
@@ -34,6 +34,7 @@ func main() {
flag.BoolVar(&debugEnable, "debug", false, "Activate debug messages")
flag.BoolVar(&displayVersion, "version", false, "Display version")
flag.BoolVar(&noColor, "noColor", false, "Disable ANSII terminal colors")
+ flag.BoolVar(&args.Quiet, "quiet", false, "Quiet output mode")
flag.IntVar(&args.ConnectionsPerCPU, "cpc", 10, "How many connections established per CPU core concurrently")
flag.IntVar(&args.Timeout, "timeout", 0, "Max time dtail server will collect data until disconnection")
flag.IntVar(&sshPort, "port", 2222, "SSH server port")
diff --git a/cmd/dtail/main.go b/cmd/dtail/main.go
index aefaa6a..5d4bad1 100644
--- a/cmd/dtail/main.go
+++ b/cmd/dtail/main.go
@@ -42,6 +42,7 @@ func main() {
flag.BoolVar(&debugEnable, "debug", false, "Activate debug messages")
flag.BoolVar(&displayVersion, "version", false, "Display version")
flag.BoolVar(&noColor, "noColor", false, "Disable ANSII terminal colors")
+ flag.BoolVar(&args.Quiet, "quiet", false, "Quiet output mode")
flag.IntVar(&args.ConnectionsPerCPU, "cpc", 10, "How many connections established per CPU core concurrently")
flag.IntVar(&args.Timeout, "timeout", 0, "Max time dtail server will collect data until disconnection")
flag.IntVar(&pprof, "pprof", -1, "Start PProf server this port")
diff --git a/go.mod b/go.mod
index 9c11b58..c19efe7 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.15
require (
github.com/DataDog/zstd v1.4.5
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c
- golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
+ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d // indirect
golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b // indirect
)
diff --git a/go.sum b/go.sum
index c0ef657..c423bb0 100644
--- a/go.sum
+++ b/go.sum
@@ -14,6 +14,8 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
diff --git a/internal/clients/args.go b/internal/clients/args.go
index 34fcfa2..7f782f1 100644
--- a/internal/clients/args.go
+++ b/internal/clients/args.go
@@ -22,4 +22,5 @@ type Args struct {
SSHAuthMethods []gossh.AuthMethod
SSHHostKeyCallback gossh.HostKeyCallback
PrivateKeyPathFile string
+ Quiet bool
}
diff --git a/internal/clients/baseclient.go b/internal/clients/baseclient.go
index 69055a3..f20156f 100644
--- a/internal/clients/baseclient.go
+++ b/internal/clients/baseclient.go
@@ -39,7 +39,7 @@ type baseClient struct {
}
func (c *baseClient) init() {
- logger.Info("Initiating base client")
+ logger.Debug("Initiating base client")
flag := regex.Default
if c.Args.RegexInvert {
@@ -70,7 +70,7 @@ func (c *baseClient) Start(ctx context.Context, statsCh <-chan string) (status i
// Periodically check for unknown hosts, and ask the user whether to trust them or not.
go c.hostKeyCallback.PromptAddHosts(ctx)
// Print client stats every time something on statsCh is recieved.
- go c.stats.Start(ctx, c.throttleCh, statsCh)
+ go c.stats.Start(ctx, c.throttleCh, statsCh, c.Args.Quiet)
// Keep count of active connections
active := make(chan struct{}, len(c.connections))
@@ -127,7 +127,7 @@ func (c *baseClient) makeConnection(server string, sshAuthMethods []gossh.AuthMe
}
func (c *baseClient) waitUntilDone(ctx context.Context, active chan struct{}) {
- defer logger.Info("Terminated connection")
+ defer logger.Debug("Terminated connection")
// We want to have at least one active connection
<-active
diff --git a/internal/clients/catclient.go b/internal/clients/catclient.go
index d8e9196..b7b6131 100644
--- a/internal/clients/catclient.go
+++ b/internal/clients/catclient.go
@@ -42,8 +42,9 @@ func (c CatClient) makeHandler(server string) handlers.Handler {
}
func (c CatClient) makeCommands() (commands []string) {
+ options := fmt.Sprintf("quiet=%v", c.Args.Quiet)
for _, file := range strings.Split(c.What, ",") {
- commands = append(commands, fmt.Sprintf("%s %s %s", c.Mode.String(), file, c.Regex.Serialize()))
+ commands = append(commands, fmt.Sprintf("%s:%s %s %s", c.Mode.String(), options, file, c.Regex.Serialize()))
}
return
}
diff --git a/internal/clients/grepclient.go b/internal/clients/grepclient.go
index 4024083..652c31b 100644
--- a/internal/clients/grepclient.go
+++ b/internal/clients/grepclient.go
@@ -41,8 +41,10 @@ func (c GrepClient) makeHandler(server string) handlers.Handler {
}
func (c GrepClient) makeCommands() (commands []string) {
+ options := fmt.Sprintf("quiet=%v", c.Args.Quiet)
for _, file := range strings.Split(c.What, ",") {
- commands = append(commands, fmt.Sprintf("%s %s %s", c.Mode.String(), file, c.Regex.Serialize()))
+ commands = append(commands, fmt.Sprintf("%s:%s %s %s", c.Mode.String(), options, file, c.Regex.Serialize()))
}
+
return
}
diff --git a/internal/clients/handlers/basehandler.go b/internal/clients/handlers/basehandler.go
index b5045e2..f07fd90 100644
--- a/internal/clients/handlers/basehandler.go
+++ b/internal/clients/handlers/basehandler.go
@@ -4,7 +4,6 @@ import (
"encoding/base64"
"fmt"
"io"
- "strconv"
"strings"
"time"
@@ -78,6 +77,7 @@ func (h *baseHandler) Read(p []byte) (n int, err error) {
case <-h.Done():
return 0, io.EOF
}
+
return
}
@@ -111,21 +111,5 @@ func (h *baseHandler) handleHiddenMessage(message string) {
case <-h.Done():
return
}
-
- case strings.HasPrefix(message, ".run exitstatus"):
- splitted := strings.Split(strings.TrimSuffix(message, "\n"), " ")
- if len(splitted) != 3 {
- logger.Error("Unable to retrieve exitstatus", message)
- return
- }
- i, err := strconv.Atoi(splitted[2])
- if err != nil {
- logger.Error("Unable to retrieve exitstatus", message, err)
- return
- }
- logger.Debug("Retrieved exitstatus", h.status)
- if i > h.status {
- h.status = i
- }
}
}
diff --git a/internal/clients/handlers/healthhandler.go b/internal/clients/handlers/healthhandler.go
index 08ed137..0440706 100644
--- a/internal/clients/handlers/healthhandler.go
+++ b/internal/clients/handlers/healthhandler.go
@@ -19,6 +19,7 @@ type HealthHandler struct {
receive chan<- string
// The remote server address
server string
+ // The return status.
status int
}
diff --git a/internal/clients/maker.go b/internal/clients/maker.go
index 1ba6482..d5ffd8b 100644
--- a/internal/clients/maker.go
+++ b/internal/clients/maker.go
@@ -4,6 +4,9 @@ import (
"github.com/mimecast/dtail/internal/clients/handlers"
)
+// maker interface helps to re-use code in all DTail client implementations.
+// All clients share the baseClient but have different connection handlers
+// and send different commands to the DTail server.
type maker interface {
makeHandler(server string) handlers.Handler
makeCommands() (commands []string)
diff --git a/internal/clients/maprclient.go b/internal/clients/maprclient.go
index 6aadd6b..1c0c2cc 100644
--- a/internal/clients/maprclient.go
+++ b/internal/clients/maprclient.go
@@ -99,7 +99,7 @@ func (c *MaprClient) Start(ctx context.Context, statsCh <-chan string) (status i
status = c.baseClient.Start(ctx, statsCh)
if c.cumulative {
- logger.Info("Received final mapreduce result")
+ logger.Debug("Received final mapreduce result")
c.reportResults()
}
@@ -112,6 +112,7 @@ func (c MaprClient) makeHandler(server string) handlers.Handler {
func (c MaprClient) makeCommands() (commands []string) {
commands = append(commands, fmt.Sprintf("map %s", c.query.RawQuery))
+ options := fmt.Sprintf("quiet=%v", c.Args.Quiet)
modeStr := "cat"
if c.Mode == omode.TailClient {
@@ -123,7 +124,7 @@ func (c MaprClient) makeCommands() (commands []string) {
commands = append(commands, fmt.Sprintf("timeout %d %s %s %s", c.Timeout, modeStr, file, c.Regex.Serialize()))
continue
}
- commands = append(commands, fmt.Sprintf("%s %s %s", modeStr, file, c.Regex.Serialize()))
+ commands = append(commands, fmt.Sprintf("%s:%s %s %s", modeStr, options, file, c.Regex.Serialize()))
}
return
@@ -133,7 +134,7 @@ func (c *MaprClient) periodicReportResults(ctx context.Context) {
for {
select {
case <-time.After(c.query.Interval):
- logger.Info("Gathering interim mapreduce result")
+ logger.Debug("Gathering interim mapreduce result")
c.reportResults()
case <-ctx.Done():
return
@@ -165,7 +166,7 @@ func (c *MaprClient) printResults() {
}
if numLines == 0 {
- logger.Info("Empty result set this time...")
+ logger.Warn("Empty result set this time...")
return
}
diff --git a/internal/clients/runclient.go b/internal/clients/runclient.go
deleted file mode 100644
index 5464d54..0000000
--- a/internal/clients/runclient.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package clients
-
-import (
- "crypto/sha256"
- "encoding/base64"
- "encoding/hex"
- "fmt"
- "runtime"
- "strings"
-
- "github.com/mimecast/dtail/internal/clients/handlers"
- "github.com/mimecast/dtail/internal/io/logger"
- "github.com/mimecast/dtail/internal/omode"
-)
-
-// RunClient is a client to run various commands on the server.
-type RunClient struct {
- baseClient
- jobName string
- background string
-}
-
-// NewRunClient returns a new run client to execute commands on the remote server.
-func NewRunClient(args Args, background, jobName string) (*RunClient, error) {
- args.Mode = omode.RunClient
-
- if jobName == "" {
- jobName = hash(strings.Join(args.Arguments, " "))
- }
-
- c := RunClient{
- baseClient: baseClient{
- Args: args,
- throttleCh: make(chan struct{}, args.ConnectionsPerCPU*runtime.NumCPU()),
- retry: false,
- },
- jobName: jobName,
- background: background,
- }
-
- c.init()
- c.makeConnections(c)
-
- return &c, nil
-}
-
-func (c RunClient) makeHandler(server string) handlers.Handler {
- return handlers.NewClientHandler(server)
-}
-
-func (c RunClient) makeCommands() (commands []string) {
- if c.Timeout > 0 {
- commands = append(commands, fmt.Sprintf("timeout %d run%s %s", c.Timeout, c.options(), c.What))
- return
- }
-
- commands = append(commands, fmt.Sprintf("run%s %s", c.options(), c.What))
- return
-}
-
-func (c RunClient) options() string {
- var sb strings.Builder
-
- logger.Debug("options", fmt.Sprintf(":background=%s", c.background))
- sb.WriteString(fmt.Sprintf(":background=%s", c.background))
-
- logger.Debug("options", fmt.Sprintf(":jobName=%s", c.jobName))
- sb.WriteString(fmt.Sprintf(":jobName=%s", c.jobName))
-
- if len(c.Arguments) > 0 {
- logger.Debug("options", fmt.Sprintf(":outerArgs=base64%%%s", strings.Join(c.Arguments, " ")))
- sb.WriteString(fmt.Sprintf(":outerArgs=base64%%%s", encode64(strings.Join(c.Arguments, " "))))
- }
-
- return sb.String()
-}
-
-func encode64(str string) string {
- return base64.StdEncoding.EncodeToString([]byte(str))
-}
-
-func hash(str string) string {
- h := sha256.New()
- h.Write([]byte(str))
-
- return hex.EncodeToString(h.Sum(nil))
-}
diff --git a/internal/clients/stats.go b/internal/clients/stats.go
index 17343b5..d8163d4 100644
--- a/internal/clients/stats.go
+++ b/internal/clients/stats.go
@@ -34,7 +34,7 @@ func newTailStats(connectionsTotal int) *stats {
// Start starts printing client connection stats every time a signal is recieved or
// connection count has changed.
-func (s *stats) Start(ctx context.Context, throttleCh <-chan struct{}, statsCh <-chan string) {
+func (s *stats) Start(ctx context.Context, throttleCh <-chan struct{}, statsCh <-chan string, quiet bool) {
var connectedLast int
for {
@@ -45,7 +45,7 @@ func (s *stats) Start(ctx context.Context, throttleCh <-chan struct{}, statsCh <
case message := <-statsCh:
messages = append(messages, message)
force = true
- case <-time.After(time.Second * 10):
+ case <-time.After(time.Second * 3):
case <-ctx.Done():
return
}
@@ -55,7 +55,7 @@ func (s *stats) Start(ctx context.Context, throttleCh <-chan struct{}, statsCh <
newConnections := connected - connectedLast
- if connected == connectedLast && !force {
+ if (connected == connectedLast || quiet) && !force {
continue
}
@@ -63,7 +63,7 @@ func (s *stats) Start(ctx context.Context, throttleCh <-chan struct{}, statsCh <
switch force {
case true:
messages = append(messages, fmt.Sprintf("Connection stats: %s", stats))
- s.printStatsOnInterrupt(messages)
+ s.printStatsDueInterrupt(messages)
default:
logger.Info(stats)
}
@@ -75,7 +75,7 @@ func (s *stats) Start(ctx context.Context, throttleCh <-chan struct{}, statsCh <
}
}
-func (s *stats) printStatsOnInterrupt(messages []string) {
+func (s *stats) printStatsDueInterrupt(messages []string) {
logger.Pause()
for _, message := range messages {
fmt.Println(fmt.Sprintf(" %s", message))
@@ -107,5 +107,6 @@ func percentOf(total float64, value float64) float64 {
if total == 0 || total == value {
return 100
}
+
return value / (total / 100.0)
}
diff --git a/internal/clients/tailclient.go b/internal/clients/tailclient.go
index 53b5ba4..cefbaa7 100644
--- a/internal/clients/tailclient.go
+++ b/internal/clients/tailclient.go
@@ -29,6 +29,7 @@ func NewTailClient(args Args) (*TailClient, error) {
c.init()
c.makeConnections(c)
+
return &c, nil
}
@@ -37,8 +38,9 @@ func (c TailClient) makeHandler(server string) handlers.Handler {
}
func (c TailClient) makeCommands() (commands []string) {
+ options := fmt.Sprintf("quiet=%v", c.Args.Quiet)
for _, file := range strings.Split(c.What, ",") {
- commands = append(commands, fmt.Sprintf("%s %s %s", c.Mode.String(), file, c.Regex.Serialize()))
+ commands = append(commands, fmt.Sprintf("%s:%s %s %s", c.Mode.String(), options, file, c.Regex.Serialize()))
}
logger.Debug(commands)
diff --git a/internal/color/colorfy.go b/internal/color/colorfy.go
index 9ae46f5..a2beb7a 100644
--- a/internal/color/colorfy.go
+++ b/internal/color/colorfy.go
@@ -41,16 +41,14 @@ func paintClientStats(line string) string {
// Colorfy a given line based on the line's content.
func Colorfy(line string) string {
- if strings.HasPrefix(line, "REMOTE") {
+ switch {
+ case strings.HasPrefix(line, "REMOTE"):
return paintRemote(line)
- }
- if strings.HasPrefix(line, "CLIENT") && strings.Contains(line, "|stats|") {
+ case strings.HasPrefix(line, "CLIENT") && strings.Contains(line, "|stats|"):
return paintClientStats(line)
- }
- if strings.Contains(line, "ERROR") {
+ case strings.Contains(line, "ERROR"):
return Paint(Magenta, line)
- }
- if strings.Contains(line, "WARN") {
+ case strings.Contains(line, "WARN"):
return Paint(Magenta, line)
}
diff --git a/internal/config/common.go b/internal/config/common.go
index 103b390..c3e203e 100644
--- a/internal/config/common.go
+++ b/internal/config/common.go
@@ -2,10 +2,14 @@ package config
// CommonConfig stores configuration keys shared by DTail server and client.
type CommonConfig struct {
- SSHPort int
+ // The SSH port number
+ SSHPort int
+ // Enable experimental features (mainly for dev purposes)
ExperimentalFeaturesEnable bool `json:",omitempty"`
- DebugEnable bool `json:",omitempty"`
- TraceEnable bool `json:",omitempty"`
+ // Enable debug logging. Don't enable in production.
+ DebugEnable bool `json:",omitempty"`
+ // Enable trace logging. Don't enable in production.
+ TraceEnable bool `json:",omitempty"`
// The log strategy to use, one of
// stdout: only log to stdout (useful when used with systemd)
// daily: create a log file for every day
diff --git a/internal/discovery/comma.go b/internal/discovery/comma.go
index 94276c7..4344240 100644
--- a/internal/discovery/comma.go
+++ b/internal/discovery/comma.go
@@ -1,8 +1,9 @@
package discovery
import (
- "github.com/mimecast/dtail/internal/io/logger"
"strings"
+
+ "github.com/mimecast/dtail/internal/io/logger"
)
// ServerListFromCOMMA retrieves a list of servers from comma separated input list.
diff --git a/internal/discovery/file.go b/internal/discovery/file.go
index c04173e..1250755 100644
--- a/internal/discovery/file.go
+++ b/internal/discovery/file.go
@@ -2,8 +2,9 @@ package discovery
import (
"bufio"
- "github.com/mimecast/dtail/internal/io/logger"
"os"
+
+ "github.com/mimecast/dtail/internal/io/logger"
)
// ServerListFromFILE retrieves a list of servers from a file.
diff --git a/internal/io/fs/permissions/permission_linux.go b/internal/io/fs/permissions/permission_linux.go
index feae729..bbc039b 100644
--- a/internal/io/fs/permissions/permission_linux.go
+++ b/internal/io/fs/permissions/permission_linux.go
@@ -11,7 +11,7 @@ import (
"unsafe"
)
-// To check whether user has Linux file system permissions to read a given file.
+// ToRead checks whether user has Linux file system permissions to read a given file.
func ToRead(user, filePath string) (bool, error) {
cUser := C.CString(user)
cFilePath := C.CString(filePath)
diff --git a/internal/io/line/line.go b/internal/io/line/line.go
index 9db93c0..715be34 100644
--- a/internal/io/line/line.go
+++ b/internal/io/line/line.go
@@ -15,7 +15,11 @@ type Line struct {
// lines if that happens but it will signal to the client how
// many log lines in % could be transmitted to the client.
TransmittedPerc int
- SourceID string
+ // Contains the unique identifier of the source log file.
+ // It could be the name of the log or it could be one of the parent
+ // directories in case multiple log files with the same basename are
+ // followed.
+ SourceID string
}
// Return a human readable representation of the followed line.
diff --git a/internal/io/logger/logger.go b/internal/io/logger/logger.go
index b7db0a7..4254eef 100644
--- a/internal/io/logger/logger.go
+++ b/internal/io/logger/logger.go
@@ -72,12 +72,15 @@ type buf struct {
func Start(ctx context.Context, mode Modes) {
Mode = mode
- if Mode.Nothing {
+ switch {
+ case Mode.Nothing:
return
- }
-
- if Mode.Trace {
+ case Mode.Quiet:
+ Mode.Trace = false
+ Mode.Debug = false
+ case Mode.Trace:
Mode.Debug = true
+ default:
}
strategy := logStrategy()
@@ -87,7 +90,7 @@ func Start(ctx context.Context, mode Modes) {
case DailyStrategy:
_, err := os.Stat(config.Common.LogDir)
Mode.logToFile = !os.IsNotExist(err)
- Mode.logToStdout = !Mode.Server || Mode.Debug || Mode.Trace
+ Mode.logToStdout = !Mode.Server || Mode.Debug || Mode.Trace || Mode.Quiet
case StdoutStrategy:
fallthrough
default:
@@ -131,11 +134,14 @@ func Info(args ...interface{}) string {
// Warn message logging.
func Warn(args ...interface{}) string {
- if Mode.Server {
- return log(serverStr, warnStr, args)
+ if !Mode.Quiet {
+ if Mode.Server {
+ return log(serverStr, warnStr, args)
+ }
+ return log(clientStr, warnStr, args)
}
- return log(clientStr, warnStr, args)
+ return ""
}
// Error message logging.
@@ -242,7 +248,7 @@ func log(what string, severity string, args []interface{}) string {
message := strings.Join(messages, "|")
write(what, severity, message)
- return message
+ return fmt.Sprintf("%s|%s", severity, message)
}
// Raw message logging.
diff --git a/internal/io/logger/modes.go b/internal/io/logger/modes.go
index 47dadfe..8864179 100644
--- a/internal/io/logger/modes.go
+++ b/internal/io/logger/modes.go
@@ -6,6 +6,7 @@ type Modes struct {
Trace bool
Debug bool
Nothing bool
+ Quiet bool
logToStdout bool
logToFile bool
}
diff --git a/internal/io/prompt/prompt.go b/internal/io/prompt/prompt.go
index a438d33..36ebdb5 100644
--- a/internal/io/prompt/prompt.go
+++ b/internal/io/prompt/prompt.go
@@ -3,9 +3,10 @@ package prompt
import (
"bufio"
"fmt"
- "github.com/mimecast/dtail/internal/io/logger"
"os"
"strings"
+
+ "github.com/mimecast/dtail/internal/io/logger"
)
// Answer is a user input of a prompt question.
@@ -18,8 +19,7 @@ type Answer struct {
Callback func()
// Runs after Callback and after logging resumes
EndCallback func()
-
- AskAgain bool
+ AskAgain bool
}
// Prompt used for interactive user input.
diff --git a/internal/io/run/run.go b/internal/io/run/run.go
deleted file mode 100644
index 2bb3756..0000000
--- a/internal/io/run/run.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package run
-
-import (
- "bufio"
- "context"
- "io"
- "os/exec"
- "sync"
- "syscall"
- "time"
-
- "github.com/mimecast/dtail/internal/io/line"
- "github.com/mimecast/dtail/internal/io/logger"
-)
-
-// Run is for execute a command.
-type Run struct {
- command string
- args []string
- cmd *exec.Cmd
- pgroupKilled chan struct{}
-}
-
-// New returns a new command runner.
-func New(command string, args []string) Run {
- return Run{
- command: