summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--TODO.md3
-rw-r--r--cmd/dcat/main.go5
-rw-r--r--cmd/dgrep/main.go5
-rw-r--r--cmd/dmap/main.go7
-rw-r--r--cmd/dserver/main.go14
-rw-r--r--cmd/dtail/main.go6
-rw-r--r--docker/Makefile6
-rw-r--r--internal/clients/connectors/serverless.go7
-rw-r--r--internal/clients/handlers/basehandler.go2
-rw-r--r--internal/config/args.go25
-rw-r--r--internal/config/common.go2
-rw-r--r--internal/config/config.go61
-rw-r--r--internal/config/setup.go32
-rw-r--r--internal/io/dlog/dlog.go37
-rw-r--r--internal/io/logger/logger.go2
-rw-r--r--internal/mapr/logformat/default.go2
-rw-r--r--internal/server/continuous.go2
-rw-r--r--internal/server/handlers/readcommand.go2
-rw-r--r--internal/server/scheduler.go2
-rw-r--r--internal/server/server.go12
-rw-r--r--internal/ssh/server/publickeycallback.go5
-rw-r--r--internal/user/server/user.go37
23 files changed, 163 insertions, 119 deletions
diff --git a/Makefile b/Makefile
index b544388..b3c3f38 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ vet:
echo ${GO} vet $$dir; \
${GO} vet $$dir; \
done
- grep -R TODO .
+ grep -R TODO: .
lint:
${GO} get golang.org/x/lint/golint
find . -type d | while read dir; do \
@@ -43,7 +43,7 @@ lint:
done
test:
ifndef USE_ACL
- ${GO} test ./... -v
+ ${GO} test -race ./... -v
else
- ${GO} test -tags linuxacl ./... -v
+ ${GO} test -race -tags linuxacl ./... -v
endif
diff --git a/TODO.md b/TODO.md
index 49fc9b9..d91c859 100644
--- a/TODO.md
+++ b/TODO.md
@@ -22,6 +22,9 @@ This is a loose list of what to do. Maybe for the next releae or maybe for a lat
[x] Implement spartan mode
[ ] Document serverless mode
[x] Implement serverless mode
+[ ] test dtail colors (Again)
+[ ] test server health check
+[ ] test spartan mode
[ ] document spartan mode
[ ] Default client log dir is ~/log not ./log
[ ] Integration test for dcat in serverless mode
diff --git a/cmd/dcat/main.go b/cmd/dcat/main.go
index d5dfba4..43549b3 100644
--- a/cmd/dcat/main.go
+++ b/cmd/dcat/main.go
@@ -26,10 +26,11 @@ func main() {
flag.BoolVar(&args.Spartan, "spartan", false, "Spartan output mode")
flag.BoolVar(&args.TrustAllHosts, "trustAllHosts", false, "Trust all unknown host keys")
flag.BoolVar(&displayVersion, "version", false, "Display version")
- flag.IntVar(&args.ConnectionsPerCPU, "cpc", 10, "How many connections established per CPU core concurrently")
- flag.IntVar(&args.SSHPort, "port", 2222, "SSH server port")
+ flag.IntVar(&args.ConnectionsPerCPU, "cpc", config.DefaultConnectionsPerCPU, "How many connections established per CPU core concurrently")
+ flag.IntVar(&args.SSHPort, "port", config.DefaultSSHPort, "SSH server port")
flag.StringVar(&args.ConfigFile, "cfg", "", "Config file path")
flag.StringVar(&args.Discovery, "discovery", "", "Server discovery method")
+ flag.StringVar(&args.LogDir, "logDir", "", "Log dir")
flag.StringVar(&args.LogLevel, "logLevel", "", "Log level")
flag.StringVar(&args.PrivateKeyPathFile, "key", "", "Path to private key")
flag.StringVar(&args.ServersStr, "servers", "", "Remote servers to connect")
diff --git a/cmd/dgrep/main.go b/cmd/dgrep/main.go
index c6bece0..36efe4e 100644
--- a/cmd/dgrep/main.go
+++ b/cmd/dgrep/main.go
@@ -28,10 +28,11 @@ func main() {
flag.BoolVar(&args.Spartan, "spartan", false, "Spartan output mode")
flag.BoolVar(&args.TrustAllHosts, "trustAllHosts", false, "Trust all unknown host keys")
flag.BoolVar(&displayVersion, "version", false, "Display version")
- flag.IntVar(&args.ConnectionsPerCPU, "cpc", 10, "How many connections established per CPU core concurrently")
- flag.IntVar(&args.SSHPort, "port", 2222, "SSH server port")
+ flag.IntVar(&args.ConnectionsPerCPU, "cpc", config.DefaultConnectionsPerCPU, "How many connections established per CPU core concurrently")
+ flag.IntVar(&args.SSHPort, "port", config.DefaultSSHPort, "SSH server port")
flag.StringVar(&args.ConfigFile, "cfg", "", "Config file path")
flag.StringVar(&args.Discovery, "discovery", "", "Server discovery method")
+ flag.StringVar(&args.LogDir, "logDir", "", "Log dir")
flag.StringVar(&args.LogLevel, "logLevel", "", "Log level")
flag.StringVar(&args.PrivateKeyPathFile, "key", "", "Path to private key")
flag.StringVar(&args.RegexStr, "regex", ".", "Regular expression")
diff --git a/cmd/dmap/main.go b/cmd/dmap/main.go
index 061d859..b895964 100644
--- a/cmd/dmap/main.go
+++ b/cmd/dmap/main.go
@@ -31,13 +31,12 @@ func main() {
flag.BoolVar(&args.Spartan, "spartan", false, "Spartan output mode")
flag.BoolVar(&args.TrustAllHosts, "trustAllHosts", false, "Trust all unknown host keys")
flag.BoolVar(&displayVersion, "version", false, "Display version")
- // TODO: Make ConnectionsPerCPU default value as a constant in config package.
- flag.IntVar(&args.ConnectionsPerCPU, "cpc", 10, "How many connections established per CPU core concurrently")
- // TODO: make default ssh port a constant in the config package.
- flag.IntVar(&args.SSHPort, "port", 2222, "SSH server port")
+ flag.IntVar(&args.ConnectionsPerCPU, "cpc", config.DefaultConnectionsPerCPU, "How many connections established per CPU core concurrently")
+ flag.IntVar(&args.SSHPort, "port", config.DefaultSSHPort, "SSH server port")
flag.IntVar(&args.Timeout, "timeout", 0, "Max time dtail server will collect data until disconnection")
flag.StringVar(&args.ConfigFile, "cfg", "", "Config file path")
flag.StringVar(&args.Discovery, "discovery", "", "Server discovery method")
+ flag.StringVar(&args.LogDir, "logDir", "", "Log dir")
flag.StringVar(&args.LogLevel, "logLevel", "", "Log level")
flag.StringVar(&args.PrivateKeyPathFile, "key", "", "Path to private key")
flag.StringVar(&args.ServersStr, "servers", "", "Remote servers to connect")
diff --git a/cmd/dserver/main.go b/cmd/dserver/main.go
index 5788a87..a3add5b 100644
--- a/cmd/dserver/main.go
+++ b/cmd/dserver/main.go
@@ -25,7 +25,6 @@ func main() {
var args config.Args
var color bool
var displayVersion bool
- var logDir string
var pprof int
var shutdownAfter int
@@ -34,25 +33,18 @@ func main() {
flag.BoolVar(&color, "color", false, "Enable ANSII terminal colors")
flag.BoolVar(&config.ServerRelaxedAuthEnable, "relaxedAuth", false, "Enable relaxced SSH auth mode (don't use in production!)")
flag.BoolVar(&displayVersion, "version", false, "Display version")
- flag.IntVar(&args.SSHPort, "port", 2222, "SSH server port")
+ flag.IntVar(&args.SSHPort, "port", config.DefaultSSHPort, "SSH server port")
flag.IntVar(&pprof, "pprof", -1, "Start PProf server this port")
flag.IntVar(&shutdownAfter, "shutdownAfter", 0, "Shutdown after so many seconds")
flag.StringVar(&args.ConfigFile, "cfg", "", "Config file path")
+ flag.StringVar(&args.LogDir, "logDir", "", "Log dir")
flag.StringVar(&args.LogLevel, "logLevel", "", "Log level")
- flag.StringVar(&logDir, "logDir", "", "Log dir path")
+ flag.StringVar(&args.LogDir, "logDir", "", "Log dir path")
flag.Parse()
args.NoColor = !color
config.Setup(&args, flag.Args())
- if logDir != "" {
- // TODO: Re-Implement log strategy support.
- config.Common.LogDir = logDir
- if config.Common.LogStrategy == "" {
- config.Common.LogStrategy = "daily"
- }
- }
-
if displayVersion {
version.PrintAndExit()
}
diff --git a/cmd/dtail/main.go b/cmd/dtail/main.go
index dcf1fab..0794f96 100644
--- a/cmd/dtail/main.go
+++ b/cmd/dtail/main.go
@@ -40,18 +40,18 @@ func main() {
flag.BoolVar(&args.RegexInvert, "invert", false, "Invert regex")
flag.BoolVar(&args.Spartan, "spartan", false, "Spartan output mode")
flag.BoolVar(&args.TrustAllHosts, "trustAllHosts", false, "Trust all unknown host keys")
- // TODO: Check whether the health check still works.
flag.BoolVar(&checkHealth, "checkHealth", false, "Only check for server health")
flag.BoolVar(&displayColorTable, "colorTable", false, "Show color table")
flag.BoolVar(&displayWideColorTable, "wideColorTable", false, "Show a large color table")
flag.BoolVar(&displayVersion, "version", false, "Display version")
- flag.IntVar(&args.ConnectionsPerCPU, "cpc", 10, "How many connections established per CPU core concurrently")
- flag.IntVar(&args.SSHPort, "port", 2222, "SSH server port")
+ flag.IntVar(&args.ConnectionsPerCPU, "cpc", config.DefaultConnectionsPerCPU, "How many connections established per CPU core concurrently")
+ flag.IntVar(&args.SSHPort, "port", config.DefaultSSHPort, "SSH server port")
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")
flag.IntVar(&shutdownAfter, "shutdownAfter", 3600*24, "Shutdown after so many seconds")
flag.StringVar(&args.ConfigFile, "cfg", "", "Config file path")
flag.StringVar(&args.Discovery, "discovery", "", "Server discovery method")
+ flag.StringVar(&args.LogDir, "logDir", "", "Log dir")
flag.StringVar(&args.LogLevel, "logLevel", "", "Log level")
flag.StringVar(&args.PrivateKeyPathFile, "key", "", "Path to private key")
flag.StringVar(&args.RegexStr, "regex", ".", "Regular expression")
diff --git a/docker/Makefile b/docker/Makefile
index c89467c..68e7ad8 100644
--- a/docker/Makefile
+++ b/docker/Makefile
@@ -11,9 +11,9 @@ spinup:
spindown:
./spindown.sh 10
dtail:
- ../dtail --servers serverlist.txt --files '/var/log/dserver/*' --trustAllHosts --debug
+ ../dtail --servers serverlist.txt --files '/var/log/dserver/*' --trustAllHosts --logLevel DEBUG
dtail2:
- ../dtail --servers serverlist.txt --files '/var/log/dserver/*' --trustAllHosts --debug --query 'from stats select max(goroutines),count($$hostname),$$hostname,last($$time) group by $$hostname order by max(goroutines)'
+ ../dtail --servers serverlist.txt --files '/var/log/dserver/*' --trustAllHosts --logLevel DEBUG --query 'from stats select max(goroutines),count($$hostname),$$hostname,last($$time) group by $$hostname order by max(goroutines)'
dgrep:
../dgrep --servers serverlist.txt --files '/var/log/dserver/*' --regex MAPREDUCE --trustAllHosts
dcat:
@@ -28,10 +28,8 @@ dmap:
dmap2:
../dmap --servers serverlist.txt --files '/var/log/mapr_testdata.log' --trustAllHosts --query 'from stats select count($$time),last($$time) group by $$time order by count($$time) outfile dmap2-A.csv'
../dmap --servers serverlist.txt --files '/var/log/mapr_testdata.log' --trustAllHosts --query 'from stats select count($$time),last($$time) group by $$time order by count($$time) outfile dmap2-B.csv'
- ../dmap --query 'from stats select count($$time),last($$time) group by $$time order by count($$time) outfile dmap2-serverless.csv' ./mapr_testdata.log
@echo Expecting zero diff!
diff -u <(sort dmap2-A.csv) <(sort dmap2-B.csv)
- diff -u <(sort dmap2-A.csv) <(sort dmap2-serverless.csv)
dmap3:
../dmap --servers <(head -n 1 serverlist.txt) --files '/var/log/mapr_testdata.log' --trustAllHosts --query 'from stats select count($$time),last($$time) group by $$time order by count($$time) outfile dmap2-A.csv'
../dmap --query 'from stats select count($$time),last($$time) group by $$time order by count($$time) outfile dmap2-serverless.csv' ./mapr_testdata.log
diff --git a/internal/clients/connectors/serverless.go b/internal/clients/connectors/serverless.go
index c7b5f62..7740aab 100644
--- a/internal/clients/connectors/serverless.go
+++ b/internal/clients/connectors/serverless.go
@@ -53,8 +53,13 @@ func (s *Serverless) Start(ctx context.Context, cancel context.CancelFunc, throt
func (s *Serverless) handle(ctx context.Context, cancel context.CancelFunc) error {
dlog.Client.Debug("Creating server handler for a serverless session")
+ user, err := user.New(s.userName, s.Server())
+ if err != nil {
+ return err
+ }
+
serverHandler := serverHandlers.NewServerHandler(
- user.New(s.userName, s.Server()),
+ user,
make(chan struct{}, config.Server.MaxConcurrentCats),
make(chan struct{}, config.Server.MaxConcurrentTails),
)
diff --git a/internal/clients/handlers/basehandler.go b/internal/clients/handlers/basehandler.go
index 3291b43..8acb45f 100644
--- a/internal/clients/handlers/basehandler.go
+++ b/internal/clients/handlers/basehandler.go
@@ -69,7 +69,7 @@ func (h *baseHandler) Write(p []byte) (n int, err error) {
for _, b := range p {
switch b {
/*
- // TODO: Next DTail version make it so that '\n' gets ignored. For now
+ // NEXT: Next DTail version make it so that '\n' gets ignored. For now
// leave it for compatibility with older DTail server + ability to display
// the protocol mismatch warn message.
case '\n' {
diff --git a/internal/config/args.go b/internal/config/args.go
index 89e4bc9..767cc65 100644
--- a/internal/config/args.go
+++ b/internal/config/args.go
@@ -16,6 +16,7 @@ type Args struct {
ConfigFile string
ConnectionsPerCPU int
Discovery string
+ LogDir string
LogLevel string
Mode omode.Mode
NoColor bool
@@ -39,6 +40,8 @@ func (a *Args) String() string {
var sb strings.Builder
sb.WriteString("Args(")
+ // TODO: All commands should make use of this
+ sb.WriteString(fmt.Sprintf("%s:%s,", "LogDir", a.LogDir))
sb.WriteString(fmt.Sprintf("%s:%s,", "LogLevel", a.LogLevel))
sb.WriteString(fmt.Sprintf("%s:%v,", "Arguments", a.Arguments))
sb.WriteString(fmt.Sprintf("%s:%v,", "ConfigFile", a.ConfigFile))
@@ -66,16 +69,24 @@ func (a *Args) String() string {
}
// Based on the argument list, transform/manipulate some of the arguments.
-func (a *Args) transform(args []string) {
+func (a *Args) transformConfig(args []string, client *ClientConfig, server *ServerConfig, common *CommonConfig) (*ClientConfig, *ServerConfig, *CommonConfig) {
+ if a.LogDir != "" {
+ common.LogDir = a.LogDir
+ if common.LogStrategy == "" {
+ // TODO: Implement the other (not-daily) log strategy for the server.
+ common.LogStrategy = "daily"
+ }
+ }
+
if a.LogLevel != "" {
- Common.LogLevel = a.LogLevel
+ common.LogLevel = a.LogLevel
}
- if a.SSHPort != 2222 {
- Common.SSHPort = a.SSHPort
+ if a.SSHPort != DefaultSSHPort {
+ common.SSHPort = a.SSHPort
}
if a.NoColor {
- Client.TermColorsEnable = false
+ client.TermColorsEnable = false
}
if a.Spartan {
@@ -95,6 +106,8 @@ func (a *Args) transform(args []string) {
}
a.What = strings.Join(files, ",")
}
+
+ return client, server, common
}
// SerializeOptions returns a string ready to be sent over the wire to the server.
@@ -102,4 +115,4 @@ func (a *Args) SerializeOptions() string {
return fmt.Sprintf("quiet=%v:spartan=%v", a.Quiet, a.Spartan)
}
-// TODO: Put the DeseializeOptions function here (move it away from the internal/server package)
+// NEXT: Put the DeseializeOptions function here (move it away from the internal/server package)
diff --git a/internal/config/common.go b/internal/config/common.go
index 7d45261..acc8e6a 100644
--- a/internal/config/common.go
+++ b/internal/config/common.go
@@ -23,7 +23,7 @@ type CommonConfig struct {
// Create a new default configuration.
func newDefaultCommonConfig() *CommonConfig {
return &CommonConfig{
- SSHPort: 2222,
+ SSHPort: DefaultSSHPort,
ExperimentalFeaturesEnable: false,
LogDir: "log",
CacheDir: "cache",
diff --git a/internal/config/config.go b/internal/config/config.go
index 2d77041..c9f411c 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -2,24 +2,26 @@ package config
import (
"encoding/json"
+ "fmt"
"io/ioutil"
"os"
+ "strings"
)
-// ControlUser is used for various DTail specific operations.
-const ControlUser string = "DTAIL-CONTROL"
-
-// ScheduleUser is used for non-interactive scheduled mapreduce queries.
-const ScheduleUser string = "DTAIL-SCHEDULE"
-
-// ContinuousUser is used for non-interactive continuous mapreduce queries.
-const ContinuousUser string = "DTAIL-CONTINUOUS"
-
-// TestUser is used for unit tests and potentially also for integration tests.
-const TestUser string = "DTAIL-TEST"
-
-// InterruptTimeoutS is used to terminate DTail when Ctrl+C was pressed twice within a given interval.
-const InterruptTimeoutS int = 3
+const (
+ // ControlUser is used for various DTail specific operations.
+ ControlUser string = "DTAIL-CONTROL"
+ // ScheduleUser is used for non-interactive scheduled mapreduce queries.
+ ScheduleUser string = "DTAIL-SCHEDULE"
+ // ContinuousUser is used for non-interactive continuous mapreduce queries.
+ ContinuousUser string = "DTAIL-CONTINUOUS"
+ // InterruptTimeoutS is used to terminate DTail when Ctrl+C was pressed twice within a given interval.
+ InterruptTimeoutS int = 3
+ // ConnectionsPerCPU controls how many connections are established concurrently as a start (slow start)
+ DefaultConnectionsPerCPU int = 10
+ // DTailSSHServerDefaultPort is the default DServer port.
+ DefaultSSHPort int = 2222
+)
// Client holds a DTail client configuration.
var Client *ClientConfig
@@ -37,21 +39,42 @@ type configInitializer struct {
Client *ClientConfig
}
-// Parse and read a given config file in JSON format.
-func (c *configInitializer) parseConfig(configFile string) {
+func (c *configInitializer) parseConfig(args *Args) {
+ if strings.ToUpper(args.ConfigFile) == "NONE" {
+ return
+ }
+
+ if args.ConfigFile != "" {
+ c.parseSpecificConfig(args.ConfigFile)
+ return
+ }
+
+ if homeDir, err := os.UserHomeDir(); err != nil {
+ var paths []string
+ paths = append(paths, fmt.Sprintf("%s/.config/dtail/dtail.conf", homeDir))
+ paths = append(paths, fmt.Sprintf("%s/.dtail.conf", homeDir))
+ for _, configPath := range paths {
+ if _, err := os.Stat(configPath); !os.IsNotExist(err) {
+ c.parseSpecificConfig(configPath)
+ }
+ }
+ }
+}
+
+func (c *configInitializer) parseSpecificConfig(configFile string) {
fd, err := os.Open(configFile)
if err != nil {
- panic(err)
+ panic(fmt.Sprintf("Unable to read config file: %v", err))
}
defer fd.Close()
cfgBytes, err := ioutil.ReadAll(fd)
if err != nil {
- panic(err)
+ panic(fmt.Sprintf("Unable to read config file %s: %v", configFile, err))
}
err = json.Unmarshal([]byte(cfgBytes), c)
if err != nil {
- panic(err)
+ panic(fmt.Sprintf("Unable to parse config file %s: %v", configFile, err))
}
}
diff --git a/internal/config/setup.go b/internal/config/setup.go
index 3c4bcc4..be8e867 100644
--- a/internal/config/setup.go
+++ b/internal/config/setup.go
@@ -1,11 +1,5 @@
package config
-import (
- "os"
-)
-
-const NoConfigFile string = "Don't read a config file - use defaults only"
-
// Setup the DTail configuration.
func Setup(args *Args, additionalArgs []string) {
initializer := configInitializer{
@@ -13,23 +7,11 @@ func Setup(args *Args, additionalArgs []string) {
Server: newDefaultServerConfig(),
Client: newDefaultClientConfig(),
}
-
- if args.ConfigFile == "" {
- // TODO: Search more paths for config file (e.g. in /etc and in ~/.config/...
- args.ConfigFile = "./cfg/dtail.json"
- }
-
- if args.ConfigFile != NoConfigFile {
- if _, err := os.Stat(args.ConfigFile); !os.IsNotExist(err) {
- initializer.parseConfig(args.ConfigFile)
- }
- }
-
- // Assign pointers to global variables, so that we can access the
- // configuration from any place of the program.
- Common = initializer.Common
- Server = initializer.Server
- Client = initializer.Client
-
- args.transform(additionalArgs)
+ initializer.parseConfig(args)
+ Client, Server, Common = args.transformConfig(
+ additionalArgs,
+ initializer.Client,
+ initializer.Server,
+ initializer.Common,
+ )
}
diff --git a/internal/io/dlog/dlog.go b/internal/io/dlog/dlog.go
index 7282741..49b405d 100644
--- a/internal/io/dlog/dlog.go
+++ b/internal/io/dlog/dlog.go
@@ -3,6 +3,7 @@ package dlog
import (
"context"
"fmt"
+ "os"
"strings"
"sync"
"time"
@@ -21,7 +22,6 @@ var Client *DLog
var Server *DLog
// Common is the log handler for all other packages.
-// TODO: Rename Common to Common
var Common *DLog
var mutex sync.Mutex
@@ -75,15 +75,22 @@ type DLog struct {
sourcePackage source
// Max log level to log.
maxLevel level
+ // Current hostname.
+ hostname string
}
// New creates a new DTail logger.
func New(sourceProcess, sourcePackage source, impl loggers.Impl, maxLevel level) *DLog {
+ hostname, err := os.Hostname()
+ if err != nil {
+ panic(err)
+ }
return &DLog{
logger: loggers.Factory(sourceProcess.String(), impl),
sourceProcess: sourceProcess,
sourcePackage: sourcePackage,
maxLevel: maxLevel,
+ hostname: hostname,
}
}
@@ -106,11 +113,18 @@ func (d *DLog) log(level level, args []interface{}) string {
defer pool.RecycleBuilderBuffer(sb)
now := time.Now()
- sb.WriteString(d.sourcePackage.String())
- sb.WriteString(protocol.FieldDelimiter)
- sb.WriteString(now.Format("20060102-150405"))
- sb.WriteString(protocol.FieldDelimiter)
- sb.WriteString(level.String())
+ switch d.sourceProcess {
+ case CLIENT:
+ sb.WriteString(d.sourcePackage.String())
+ sb.WriteString(protocol.FieldDelimiter)
+ sb.WriteString(d.hostname)
+ sb.WriteString(protocol.FieldDelimiter)
+ sb.WriteString(level.String())
+ default:
+ sb.WriteString(level.String())
+ sb.WriteString(protocol.FieldDelimiter)
+ sb.WriteString(now.Format("20060102-150405"))
+ }
sb.WriteString(protocol.FieldDelimiter)
d.writeArgStrings(sb, args)
@@ -159,6 +173,11 @@ func (d *DLog) Warn(args ...interface{}) string {
}
func (d *DLog) Info(args ...interface{}) string {
+ if d.sourcePackage == SERVER && d.sourceProcess != CLIENT {
+ // This can be dtail client in serverless mode. In this case log all
+ // info server messages as verbose.
+ return d.log(VERBOSE, args)
+ }
return d.log(INFO, args)
}
@@ -183,13 +202,14 @@ func (d *DLog) Raw(message string) string {
d.logger.Log(time.Now(), message)
return message
}
-
- d.logger.Log(time.Now(), brush.Colorfy(message))
+ d.logger.LogWithColors(time.Now(), message, brush.Colorfy(message))
return message
}
func (d *DLog) Mapreduce(table string, data map[string]interface{}) string {
args := make([]interface{}, len(data)+1)
+
+ // TODO: mC compatible SERVER mapreduce fields, no MAPREDUCE keyword in CLIENT mode
args[0] = fmt.Sprintf("%s:%s", "MAPREDUCE", strings.ToUpper(table))
i := 1
@@ -197,7 +217,6 @@ func (d *DLog) Mapreduce(table string, data map[string]interface{}) string {
args[i] = fmt.Sprintf("%s=%v", k, v)
i++
}
-
return d.log(INFO, args)
}
diff --git a/internal/io/logger/logger.go b/internal/io/logger/logger.go
index 6a6b5ec..905d1cf 100644
--- a/internal/io/logger/logger.go
+++ b/internal/io/logger/logger.go
@@ -1,7 +1,5 @@
package logger
-// TODO: Rewrite this logger
-
import (
"bufio"
"context"
diff --git a/internal/mapr/logformat/default.go b/internal/mapr/logformat/default.go
index e0bbc30..7fb1700 100644
--- a/internal/mapr/logformat/default.go
+++ b/internal/mapr/logformat/default.go
@@ -27,7 +27,7 @@ func (p *Parser) MakeFieldsDEFAULT(maprLine string) (map[string]string, error) {
fields["$severity"] = splitted[0]
fields["$loglevel"] = splitted[0]
- // TODO: Parse time like we do at Mimecast
+ // NEXT: Parse time like we do at Mimecast
fields["$time"] = splitted[1]
for _, kv := range splitted[4:] {
diff --git a/internal/server/continuous.go b/internal/server/continuous.go
index 5f4c454..87c8889 100644
--- a/internal/server/continuous.go
+++ b/internal/server/continuous.go
@@ -61,7 +61,7 @@ func (c *continuous) runJob(ctx context.Context, job config.Continuous) {
}
args := config.Args{
- ConnectionsPerCPU: 10,
+ ConnectionsPerCPU: config.DefaultConnectionsPerCPU,
Discovery: job.Discovery,
ServersStr: servers,
What: files,
diff --git a/internal/server/handlers/readcommand.go b/internal/server/handlers/readcommand.go
index 60ad2a0..c76ae2a 100644
--- a/internal/server/handlers/readcommand.go
+++ b/internal/server/handlers/readcommand.go
@@ -7,9 +7,9 @@ import (
"sync"
"time"
+ "github.com/mimecast/dtail/internal/io/dlog"
"github.com/mimecast/dtail/internal/io/fs"
"github.com/mimecast/dtail/internal/io/line"
- "github.com/mimecast/dtail/internal/io/dlog"
"github.com/mimecast/dtail/internal/omode"
"github.com/mimecast/dtail/internal/regex"
)
diff --git a/internal/server/scheduler.go b/internal/server/scheduler.go
index f474cc8..64e6573 100644
--- a/internal/server/scheduler.go
+++ b/internal/server/scheduler.go
@@ -72,7 +72,7 @@ func (s *scheduler) runJobs(ctx context.Context) {
}
args := config.Args{
- ConnectionsPerCPU: 10,
+ ConnectionsPerCPU: config.DefaultConnectionsPerCPU,
Discovery: job.Discovery,
ServersStr: servers,
What: files,
diff --git a/internal/server/server.go b/internal/server/server.go
index a8f541b..d1cd57d 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -124,7 +124,12 @@ func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
}
func (s *Server) handleChannel(ctx context.Context, sshConn gossh.Conn, newChannel gossh.NewChannel) {
- user := user.New(sshConn.User(), sshConn.RemoteAddr().String())
+ user, err := user.New(sshConn.User(), sshConn.RemoteAddr().String())
+ if err != nil {
+ dlog.Server.Error(user, err)
+ newChannel.Reject(gossh.Prohibited, err.Error())
+ return
+ }
dlog.Server.Info(user, "Invoking channel handler")
if newChannel.ChannelType() != "session" {
@@ -213,7 +218,10 @@ func (s *Server) handleRequests(ctx context.Context, sshConn gossh.Conn, in <-ch
// Callback for SSH authentication.
func (s *Server) Callback(c gossh.ConnMetadata, authPayload []byte) (*gossh.Permissions, error) {
- user := user.New(c.User(), c.RemoteAddr().String())
+ user, err := user.New(c.User(), c.RemoteAddr().String())
+ if err != nil {
+ return nil, err
+ }
if config.ServerRelaxedAuthEnable {
dlog.Server.Fatal(user, "Granting permissions via relaxed-auth")
diff --git a/internal/ssh/server/publickeycallback.go b/internal/ssh/server/publickeycallback.go
index 65ecdd1..59d1f31 100644
--- a/internal/ssh/server/publickeycallback.go
+++ b/internal/ssh/server/publickeycallback.go
@@ -15,7 +15,10 @@ import (
// PublicKeyCallback is for the server to check whether a public SSH key is authorized ot not.
func PublicKeyCallback(c gossh.ConnMetadata, offeredPubKey gossh.PublicKey) (*gossh.Permissions, error) {
- user := user.New(c.User(), c.RemoteAddr().String())
+ user, err := user.New(c.User(), c.RemoteAddr().String())
+ if err != nil {
+ return nil, err
+ }
dlog.Common.Info(user, "Incoming authorization")
cwd, err := os.Getwd()
diff --git a/internal/user/server/user.go b/internal/user/server/user.go
index 99cd211..70ead1c 100644
--- a/internal/user/server/user.go
+++ b/internal/user/server/user.go
@@ -8,8 +8,8 @@ import (
"strings"
"github.com/mimecast/dtail/internal/config"
- "github.com/mimecast/dtail/internal/io/fs/permissions"
"github.com/mimecast/dtail/internal/io/dlog"
+ "github.com/mimecast/dtail/internal/io/fs/permissions"
)
const maxLinkDepth int = 100
@@ -25,11 +25,16 @@ type User struct {
}
// New returns a new user.
-func New(name, remoteAddress string) *User {
+func New(name, remoteAddress string) (*User, error) {
+ permissions, err := config.ServerUserPermissions(name)
+ if err != nil {
+ return nil, err
+ }
return &User{
Name: name,
remoteAddress: remoteAddress,
- }
+ permissions: permissions,
+ }, nil
}
// String representation of the user.
@@ -39,9 +44,9 @@ func (u *User) String() string {
// HasFilePermission is used to determine whether user is alowed to read a file.
func (u *User) HasFilePermission(filePath, permissionType string) (hasPermission bool) {
- dlog.Common.Debug(u, filePath, permissionType, "Checking config permissions")
+ dlog.Server.Debug(u, filePath, permissionType, "Checking config permissions")
if config.ServerRelaxedAuthEnable {
- dlog.Common.Fatal(u, filePath, permissionType, "Server releaxed auth enabled")
+ dlog.Server.Fatal(u, filePath, permissionType, "Server releaxed auth enabled")
return true
}
@@ -52,25 +57,25 @@ func (u *User) HasFilePermission(filePath, permissionType string) (hasPermission
cleanPath, err := filepath.EvalSymlinks(filePath)
if err != nil {
- dlog.Common.Error(u, filePath, permissionType, "Unable to evaluate symlinks", err)
+ dlog.Server.Error(u, filePath, permissionType, "Unable to evaluate symlinks", err)
hasPermission = false
return
}
cleanPath, err = filepath.Abs(cleanPath)
if err != nil {
- dlog.Common.Error(u, cleanPath, permissionType, "Unable to make file path absolute", err)
+ dlog.Server.Error(u, cleanPath, permissionType, "Unable to make file path absolute", err)
hasPermission = false
return
}
if cleanPath != filePath {
- dlog.Common.Info(u, filePath, cleanPath, permissionType, "Calculated new clean path from original file path (possibly symlink)")
+ dlog.Server.Info(u, filePath, cleanPath, permissionType, "Calculated new clean path from original file path (possibly symlink)")
}
hasPermission, err = u.hasFilePermission(cleanPath, permissionType)
if err != nil {
- dlog.Common.Warn(u, cleanPath, err)
+ dlog.Server.Warn(u, cleanPath, err)
}
return
@@ -81,7 +86,7 @@ func (u *User) hasFilePermission(cleanPath, permissionType string) (bool, error)
if _, err := permissions.ToRead(u.Name, cleanPath); err != nil {
return false, fmt.Errorf("User without OS file system permissions to read path: '%v'", err)
}
- dlog.Common.Info(u, cleanPath, permissionType, "User with OS file system permissions to path")
+ dlog.Server.Info(u, cleanPath, permissionType, "User with OS file system permissions to path")
// Only allow to follow regular files or symlinks.
info, err := os.Lstat(cleanPath)
@@ -93,12 +98,6 @@ func (u *User) hasFilePermission(cleanPath, permissionType string) (bool, error)
return false, fmt.Errorf("Can only open regular files or follow symlinks")
}
- permissions, err := config.ServerUserPermissions(u.Name)
- if err != nil {
- return false, err
- }
- u.permissions = permissions
-
hasPermission, err := u.iteratePaths(cleanPath, permissionType)
if err != nil {
return false, err
@@ -123,7 +122,7 @@ func (u *User) iteratePaths(cleanPath, permissionType string) (bool, error) {
permission = strings.Join(splitted[1:], ":")
}
- dlog.Common.Debug(u, cleanPath, typeStr, permission)
+ dlog.Server.Debug(u, cleanPath, typeStr, permission)
if typeStr != permissionType {
continue
@@ -141,12 +140,12 @@ func (u *User) iteratePaths(cleanPath, permissionType string) (bool, error) {
}
if negate && re.MatchString(cleanPath) {
- dlog.Common.Info(u, cleanPath, "Permission test failed partially, matching negative pattern '%s'", permission)
+ dlog.Server.Info(u, cleanPath, "Permission test failed partially, matching negative pattern '%s'", permission)
hasPermission = false
}
if !negate && re.MatchString(cleanPath) {
- dlog.Common.Info(u, cleanPath, "Permission test passed partially, matching positive pattern", permission)
+ dlog.Server.Info(u, cleanPath, "Permission test passed partially, matching positive pattern", permission)
hasPermission = true
}
}