Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite sgcollect in go #5783

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Port over all OS tasks
  • Loading branch information
markspolakovs committed Sep 21, 2022
commit a72be089783cfce1f0ab817900ba9c74c54aa562
103 changes: 70 additions & 33 deletions tools/sgcollect/task_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,28 @@ type SGCollectTask interface {
Run(ctx context.Context, opts *SGCollectOptions, out io.Writer) error
}

// SGCollectTaskEx wraps a SGCollectTask with information about how it should be run.
type SGCollectTaskEx interface {
type SGCollectTaskEx struct {
SGCollectTask
ShouldRun(platform string) bool
RequiresRoot() bool
NumSamples() int
Interval() time.Duration
Timeout() time.Duration
platforms []string
root bool
samples int
interval time.Duration
timeout time.Duration
outputFileOverride string
noHeader bool
}

// TaskEx wraps the given SGCollectTask in a SGCollectTaskEx if necessary.
func TaskEx(t SGCollectTask) SGCollectTaskEx {
if ex, ok := t.(SGCollectTaskEx); ok {
return ex
}
return ex{
return SGCollectTaskEx{
SGCollectTask: t,
}
}

type ex struct {
SGCollectTask
platforms []string
root bool
samples int
interval time.Duration
timeout time.Duration
}

func (e ex) ShouldRun(platform string) bool {
func (e SGCollectTaskEx) ShouldRun(platform string) bool {
if len(e.platforms) == 0 {
return true
}
Expand All @@ -62,57 +54,93 @@ func (e ex) ShouldRun(platform string) bool {
return false
}

func (e ex) RequiresRoot() bool {
func (e SGCollectTaskEx) RequiresRoot() bool {
return e.root
}

func (e ex) NumSamples() int {
func (e SGCollectTaskEx) NumSamples() int {
return e.samples
}

func (e ex) Interval() time.Duration {
func (e SGCollectTaskEx) Interval() time.Duration {
return e.interval
}

func (e ex) Timeout() time.Duration {
func (e SGCollectTaskEx) Timeout() time.Duration {
return e.timeout
}

func (e SGCollectTaskEx) Header() string {
if e.noHeader {
return ""
}
return e.SGCollectTask.Header()
}

func (e SGCollectTaskEx) OutputFile() string {
if e.outputFileOverride != "" {
return e.outputFileOverride
}
return e.SGCollectTask.OutputFile()
}

func Sample(t SGCollectTask, samples int, interval time.Duration) SGCollectTaskEx {
if ex, ok := t.(ex); ok {
if ex, ok := t.(SGCollectTaskEx); ok {
ex.samples = samples
ex.interval = interval
return ex
}
return ex{
return SGCollectTaskEx{
SGCollectTask: t,
samples: samples,
interval: interval,
}
}

func Timeout(t SGCollectTask, timeout time.Duration) SGCollectTaskEx {
if ex, ok := t.(ex); ok {
if ex, ok := t.(SGCollectTaskEx); ok {
ex.timeout = timeout
return ex
}
return ex{
return SGCollectTaskEx{
SGCollectTask: t,
timeout: timeout,
}
}

func Privileged(t SGCollectTask) SGCollectTaskEx {
if ex, ok := t.(ex); ok {
if ex, ok := t.(SGCollectTaskEx); ok {
ex.root = true
return ex
}
return ex{
return SGCollectTaskEx{
SGCollectTask: t,
root: true,
}
}

func OverrideOutput(t SGCollectTask, out string) SGCollectTaskEx {
if ex, ok := t.(SGCollectTaskEx); ok {
ex.outputFileOverride = out
return ex
}
return SGCollectTaskEx{
SGCollectTask: t,
outputFileOverride: out,
}
}

func NoHeader(t SGCollectTask) SGCollectTaskEx {
if ex, ok := t.(SGCollectTaskEx); ok {
ex.noHeader = true
return ex
}
return SGCollectTaskEx{
SGCollectTask: t,
noHeader: true,
}
}

type URLTask struct {
name string
url string
Expand Down Expand Up @@ -301,17 +329,26 @@ func (o *osTask) ShouldRun(platform string) bool {
}

// OSTask is a helper to return a task for the given platform, which can be one of
// "unix", "linux, "windows", "solaris", or "" for all platforms.
// "unix", "linux, "windows", "darwin", "solaris", or "" for all platforms.
func OSTask(platform string, name, cmd string) SGCollectTask {
switch platform {
case "":
return &OSCommandTask{name, cmd, ""}
case "linux", "windows":
return &osTask{OSCommandTask{name, cmd, ""}, []string{platform}}
case "linux", "windows", "darwin":
return SGCollectTaskEx{
SGCollectTask: &OSCommandTask{name, cmd, ""},
platforms: []string{platform},
}
case "unix":
return &osTask{OSCommandTask{name, cmd, ""}, []string{"linux", "darwin", "freebsd", "netbsd", "openbsd"}}
return SGCollectTaskEx{
SGCollectTask: &OSCommandTask{name, cmd, ""},
platforms: []string{"linux", "darwin", "freebsd", "netbsd", "openbsd"},
}
case "solaris":
return &osTask{OSCommandTask{name, cmd, ""}, []string{"illumos", "solaris"}}
return SGCollectTaskEx{
SGCollectTask: &OSCommandTask{name, cmd, ""},
platforms: []string{"illumos", "solaris"},
}
default:
panic(fmt.Sprintf("unknown platform %s", platform))
}
Expand Down
66 changes: 66 additions & 0 deletions tools/sgcollect/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,72 @@ func makeOSTasks() []SGCollectTask {
OSTask("linux", "Extended iostat", "iostat -x -p ALL 1 10 || iostat -x 1 10"),
OSTask("linux", "Core dump settings", "find /proc/sys/kernel -type f -name '*core*' -print -exec cat '{}' ';'"),
OSTask("unix", "sysctl settings", "sysctl -a"),
OSTask("linux", "lsof output", "echo sync_gateway | xargs -n1 pgrep | xargs -n1 -r -- lsof -n -p"),
OSTask("linux", "LVM info", "lvdisplay"),
OSTask("linux", "LVM info", "vgdisplay"),
OSTask("linux", "LVM info", "pvdisplay"),
OSTask("darwin", "Process list snapshot", "top -l 1"),
OSTask("darwin", "Disk activity", "iostat 1 10"),
OSTask("darwin", "Process list", "ps -Aww -o user,pid,lwp,ppid,nlwp,pcpu,pri,nice,vsize,rss,tty,stat,wchan:12,start,bsdtime,command"),
OSTask("windows", "Installed software", "wmic product get name, version"),
OSTask("windows", "Service list", "wmic service where state=\"running\" GET caption, name, state"),
OSTask("windows", "Process list", "wmic process"),
OSTask("windows", "Process usage", "tasklist /V /fo list"),
OSTask("windows", "Swap settings", "wmic pagefile"),
OSTask("windows", "Disk partition", "wmic partition"),
OSTask("windows", "Disk volumes", "wmic volume"),
Sample(OSTask("unix", "Network configuration", "ifconfig -a"), 2, 10*time.Second),
OSTask("linux", "Network configuration", "echo link addr neigh rule route netns | xargs -n1 -- sh -x -c 'ip $1 list' --"),
Sample(OSTask("windows", "Network configuration", "ipconfig /all"), 2, 10*time.Second),
OSTask("linux", "Raw /proc/net/dev", "cat /proc/net/dev"),
OSTask("linux", "Network link statistics", "ip -s link"),
OSTask("unix", "Network status", "netstat -anp || netstat -an"),
OSTask("windows", "Network status", "netstat -ano"),
OSTask("unix", "Network routing table", "netstat -rn"),
OSTask("linux", "Network socket statistics", "ss -an"),
OSTask("linux", "Extended socket statistics", "ss -an --info --processes"),
OSTask("unix", "Arp cache", "arp -na"),
OSTask("linux", "Iptables dump", "iptables-save"),
OSTask("unix", "Raw /etc/hosts", "cat /etc/hosts"),
OSTask("unix", "Raw /etc/resolv.conf", "cat /etc/resolv.conf"),
OSTask("unix", "Raw /etc/nsswitch.conf", "cat /etc/nsswitch.conf"),
OSTask("windows", "Arp cache", "arp -a"),
OSTask("windows", "Network Interface Controller", "wmic nic"),
OSTask("windows", "Network Adapter", "wmic nicconfig"),
OSTask("windows", "Active network connection", "wmic netuse"),
OSTask("windows", "Protocols", "wmic netprotocol"),
OSTask("windows", "Hosts file", `type %SystemRoot%\system32\drivers\etc\hosts`),
OSTask("windows", "Cache memory", "wmic memcache"),
OSTask("windows", "Physical memory", "wmic memphysical"),
OSTask("windows", "Physical memory chip info", "wmic memorychip"),
OSTask("windows", "Local storage devices", "wmic logicaldisk"),
OSTask("unix", "Filesystem", "df -ha"),
OSTask("unix", "System activity reporter", "sar 1 10"),
OSTask("unix", "System paging activity", "vmstat 1 10"),
OSTask("unix", "System uptime", "uptime"),
OSTask("unix", "couchbase user definition", "getent passwd couchbase"),
Privileged(OSTask("unix", "couchbase user limits", `su couchbase -c "ulimit -a"`)),
OSTask("unix", "sync_gateway user definition", "getent passwd sync_gateway"),
Privileged(OSTask("unix", "sync_gateway user limits", `su sync_gateway -c "ulimit -a"`)),
OSTask("unix", "Interrupt status", "intrstat 1 10"),
OSTask("unix", "Processor status", "mpstat 1 10"),
OSTask("unix", "System log", "cat /var/adm/messages"),
OSTask("linux", "Raw /proc/uptime", "cat /proc/uptime"),
NoHeader(OverrideOutput(OSTask("linux", "Systemd journal", "journalctl 2>&1 | gzip -c"), "systemd_journal.gz")),
NoHeader(OverrideOutput(OSTask("linux", "All logs", "tar cz /var/log/syslog* /var/log/dmesg /var/log/messages* /var/log/daemon* /var/log/debug* /var/log/kern.log* 2>/dev/null"), "syslog.tar.gz")),
OSTask("linux", "Relevant proc data", "echo sync_gateway | xargs -n1 pgrep | xargs -n1 -- sh -c 'echo $1; cat /proc/$1/status; cat /proc/$1/limits; cat /proc/$1/smaps; cat /proc/$1/numa_maps; cat /proc/$1/task/*/sched; echo' --"),
OSTask("linux", "Processes' environment", "echo sync_gateway | xargs -n1 pgrep | xargs -n1 -- sh -c 'echo $1; ( cat /proc/$1/environ | tr \\0 \\n ); echo' --"),
OSTask("linux", "NUMA data", "numactl --hardware"),
OSTask("linux", "NUMA data", "numactl --show"),
OSTask("linux", "NUMA data", "cat /sys/devices/system/node/node*/numastat"),
OSTask("unix", "Kernel log buffer", "dmesg -H || dmesg"),
OSTask("linux", "Transparent Huge Pages data", "cat /sys/kernel/mm/transparent_hugepage/enabled"),
OSTask("linux", "Transparent Huge Pages data", "cat /sys/kernel/mm/transparent_hugepage/defrag"),
OSTask("linux", "Transparent Huge Pages data", "cat /sys/kernel/mm/redhat_transparent_hugepage/enabled"),
OSTask("linux", "Transparent Huge Pages data", "cat /sys/kernel/mm/redhat_transparent_hugepage/defrag"),
OSTask("linux", "Network statistics", "netstat -s"),
OSTask("linux", "Full raw netstat", "cat /proc/net/netstat"),
OSTask("linux", "CPU throttling info", "echo /sys/devices/system/cpu/cpu*/thermal_throttle/* | xargs -n1 -- sh -c 'echo $1; cat $1' --"),
}
}

Expand Down