With my supervision, primordial nature brings forth the moving and the nonmoving.
– Bhagavad Gita
Acksin STRUM is the tool to diagnose Linux issues quickly. It gives you a complete picture of the CPU, Memory, IO, Networking, Processes, Kernel Limits, etc. of a system. STRUM was born out of the frustration that diagnosing an issue was to go through a mental checklist and dealing with fallible human memory (especially at 3am when the pager goes off). We hope that this tool will help.
We will reference the different keys of the output with the following syntax.
.System.Attribute
refers to
{
"System": {
"Attribute": "foobar"
}
}
.Processes.0.PID
refers to the first item in the array Processes.
{
"Processes": [
{
"Exe": "systemd",
"PID": 1,
"Memory": {
"Swap": {
"Size": 0,
"Unit": "kb"
}
},
"IO": {
"Limits": {
"OpenFiles": 65536,
"FileSize": 0,
"CPUTime": -1
},
"FD": null
}
}
]
}
./strum --help
./strum
./strum 1505
./strum --output=flat
Ackin STRUM is a tool for diagnosing issues quickly. It deals with things at the system level, the cloud level, and at the process level. The output of STRUM therefore has the following output:
{
"System": ...
"Cloud": ...
"Processes": ...
}
The output of the .System
section looks like the following:
strum | jq '.System'
{
"Memory": {
"Unit": "kb",
"Physical": {
"Total": 1014572,
"Free": 219952,
"Used": 794620,
"Cached": 189676,
"Buffers": 199680
},
"Swap": {
"Total": 0,
"Free": 0,
"Used": 0,
"Cached": 0
},
"Virtual": {
"Total": 34359738367,
"Used": 0,
"Chunk": 0
},
"Dirty": 44,
"Writeback": 0,
"Mapped": 42024
},
"Network": {
"Total": 268,
"RAW": {},
"UDP": {},
"TCP": {
"Total": 0,
"Established": 6,
"Closed": 0,
"Orphaned": 0,
"Synrecv": 0,
"Timewait": 0
}
}
}
strum | jq '.System.Memory'
{
"Unit": "kb",
"Physical": {
"Total": 1014572,
"Free": 219832,
"Used": 794740,
"Cached": 189672,
"Buffers": 199756
},
"Swap": {
"Total": 0,
"Free": 0,
"Used": 0,
"Cached": 0
},
"Virtual": {
"Total": 34359738367,
"Used": 0,
"Chunk": 0
},
"Dirty": 72,
"Writeback": 0,
"Mapped": 42024
}
The main thing to worry about when doing diagnostics is to see if the
.System.Memory.Swap
is being used. A swapping system means that
memory is being moved from disk to memory and back again which can
lead to high CPU usage and poor performance.
NOT IMPLEMENTED
INCOMPLETE
NOT IMPLEMENTED
NOT IMPLEMENTED
The Cloud section gives various information about the cloud provider and cloud attributes that the machine has. This information can be useful for quickly figuring out if the machine is on an underpowered machine for the tasks of te application.
The key .Cloud.AWS
provides the following output.
{
"AWS": {
"AmiID": "ami-1121ca71",
"AmiLaunchIndex": "0",
"AmiManifestPath": "(unknown)",
"Hostname": "ip-172-32-27-88.us-west-2.compute.internal",
"InstanceAction": "none",
"InstanceID": "i-05bdde3e3563e1039",
"InstanceType": "t2.micro",
"LocalHostname": "ip-172-32-27-88.us-west-2.compute.internal",
"LocalIpv4": "172.32.27.88",
"MAC": "02:3e:a9:c6:1e:5f",
"Profile": "default-hvm",
"PublicHostname": "ec2-53-39-40-117.us-west-2.compute.amazonaws.com",
"PublicIpv4": "53.39.40.117",
"ReservationID": "r-0555ad3d4b37c692f",
"SecurityGroups": "launch-wizard-1"
}
}
Here we want to get information about the process with the PID
2277.
strum 2277 | jq '.Processes[0]'
{
"Exe": "/lib/systemd/systemd",
"PID": 2277,
"Memory": {
"Swap": {
"Size": 0,
"Unit": "kb"
}
},
"IO": {
"Limits": {
"OpenFiles": 1024,
"FileSize": 0,
"CPUTime": -1
},
"FD": {
"0": "/dev/null",
"1": "socket:[21619]",
"10": "/proc/2277/mountinfo",
"11": "anon_inode:inotify",
"12": "/proc/swaps",
"13": "socket:[21669]",
"14": "socket:[21670]",
"2": "socket:[21619]",
"3": "socket:[21635]",
"4": "anon_inode:[eventpoll]",
"5": "anon_inode:[signalfd]",
"6": "/sys/fs/cgroup/systemd/user/abhi/2",
"7": "anon_inode:[timerfd]",
"8": "socket:[21650]",
"9": "anon_inode:[eventpoll]"
}
}
}
We can see the memory usage for the process.
strum 2277 | jq '.Processes[0].Memory'
{
"Swap": {
"Size": 0,
"Unit": "kb"
}
}
NOT IMPLEMENTD
NOT IMPLEMENTED
We can get information about the IO of a process. We can see what files it has open as well as the limits that it has.
strum 2277 | jq '.Processes[0].IO'
{
"Limits": {
"OpenFiles": 1024,
"FileSize": 0,
"CPUTime": -1
},
"FD": {
"0": "/dev/null",
"1": "socket:[21619]",
"10": "/proc/2277/mountinfo",
"11": "anon_inode:inotify",
"12": "/proc/swaps",
"13": "socket:[21669]",
"14": "socket:[21670]",
"2": "socket:[21619]",
"3": "socket:[21635]",
"4": "anon_inode:[eventpoll]",
"5": "anon_inode:[signalfd]",
"6": "/sys/fs/cgroup/systemd/user/abhi/2",
"7": "anon_inode:[timerfd]",
"8": "socket:[21650]",
"9": "anon_inode:[eventpoll]"
}
}
We can see here what the kernel limits are for the process.
strum 2277 | jq '.Processes[0].IO.Limits'
{
"OpenFiles": 1024,
"FileSize": 0,
"CPUTime": -1
}