Code Monkey home page Code Monkey logo

pcstat's Introduction

pcstat - get page cache statistics for files

A common question when tuning databases and other IO-intensive applications is, "is Linux caching my data or not?" pcstat gets that information for you using the mincore(2) syscall.

The fincore application from linux-ftools does the same thing and I read its source code. I chose not to use it because it appears to be abandoned and has some build problems.

I wrote this is so that Apache Cassandra users can see if ssTables are being cached. If $GOPATH/bin is in your PATH, this will get it installed:

go install github.com/tobert/pcstat@latest
pcstat /var/lib/cassandra/data/*/*/*-Data.db

If you don't want to mess around with building the software, binaries are provided in orphaned branches so you can pull them down from Github with curl/wget.

if [ $(uname -m) == "x86_64" ] ; then
    curl -L -o pcstat https://github.com/tobert/pcstat/raw/2014-05-02-01/pcstat.x86_64
else
    curl -L -o pcstat https://github.com/tobert/pcstat/raw/2014-05-02-01/pcstat.x86_32
fi
chmod 755 pcstat
./pcstat /var/lib/cassandra/data/*/*/*-Data.db

Usage

Command-line arguments are described below. Every argument following the program flags is considered a file for inspection.

pcstat <-json <-pps>|-terse|-default> <-nohdr> <-bname> file file file
 -json output will be JSON
   -pps include the per-page information in the output (can be huge!)
 -terse print terse machine-parseable output
 -histo print a histogram using unicode block characters
 -nohdr don't print the column header in terse or default format
 -bname use basename(file) in the output (use for long paths)
 -plain return data with no box characters
 -unicode return data with unicode box characters

Examples

Default output

The default output is designed to be easy for humans to read at a glance and should look nice in any fixed-width font.

atobey@brak ~ $ pcstat testfile3
|-----------+----------------+------------+-----------+---------|
| Name      | Size           | Pages      | Cached    | Percent |
|-----------+----------------+------------+-----------+---------|
| LICENSE   | 11323          | 3          | 0         | 000.000 |
| README.md | 6768           | 2          | 2         | 100.000 |
| pcstat    | 3065456        | 749        | 749       | 100.000 |
| pcstat.go | 9687           | 3          | 3         | 100.000 |
| testfile3 | 102401024      | 25001      | 60        | 000.240 |
|-----------+----------------+------------+-----------+---------|

Terse output

Meant to be machine readable and easy to process with standard shell tools and scripts. Note: No attempt is made to escape characters for proper CSV at this time.

pcstat -terse -bname *
name,size,timestamp,mtime,pages,cached,percent
LICENSE,11323,1400767725,1400492571,3,0,0
README.md,6185,1400767725,1400767719,2,2,100
pcstat,3065456,1400767725,1400766869,749,749,100
pcstat.go,9687,1400767725,1400766807,3,3,100
testfile3,102401024,1400767725,1400761247,25001,60,0.23999040038398464

JSON output

The 'status' field will always be empty unless you add the -pps flag, which will cause status to be populated with an array of booleans, one per page in the file indicated whether it's cached or not. This can get spammy with big files so it's off by default.

atobey@brak ~ $ pcstat -json testfile3 |json_pp
[
 {
   "filename":  "testfile3",
   "size":      102401024,
   "timestamp": "2014-05-22T13:57:19.971348936Z",
   "mtime":     "2014-05-22T12:20:47.940163295Z",
   "pages":     25001,
   "cached":    60,
   "uncached":  24941,
   "percent":   0.23999040038398464,
   "status":    []
 }
]

Histogram output

Your terminal and font need to support the Block Elements section of Unicode for this to work. Even then, the output is inconsistent in my testing, so YMMV. See http://www.unicode.org/charts/PDF/U2580.pdf

The number after the filename is the number of pages in the file. This might be removed in the future.

atobey@brak ~ $ pcstat -bname -histo *
LICENSE          3 ▁▁▁
README.md        2 ██
pcstat         749 █████████████████████████████████████████████████
pcstat.go        3 ███
testfile      2560 ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
testfile2        3 ▁▁▁
testfile3    25001 ▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

Testing

The easiest way to tell if this tool is working is to drop caches and do reads on files to get things into cache.

atobey@brak ~/src/pcstat $ dd if=/dev/urandom of=testfile bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.805698 s, 13.0 MB/s
atobey@brak ~/src/pcstat $ ./pcstat testfile
|--------------------+----------------+------------+-----------+---------|
| Name               | Size           | Pages      | Cached    | Percent |
|--------------------+----------------+------------+-----------+---------|
| testfile           | 10485760       | 2560       | 2560      | 100     |
|--------------------+----------------+------------+-----------+---------|
atobey@brak ~/src/pcstat $ echo 1 |sudo tee /proc/sys/vm/drop_caches
1
atobey@brak ~/src/pcstat $ ./pcstat testfile
|--------------------+----------------+------------+-----------+---------|
| Name               | Size           | Pages      | Cached    | Percent |
|--------------------+----------------+------------+-----------+---------|
| testfile           | 10485760       | 2560       | 0         | 0       |
|--------------------+----------------+------------+-----------+---------|
atobey@brak ~/src/pcstat $ dd if=/dev/urandom of=testfile bs=4096 seek=10 count=1 conv=notrunc
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000468208 s, 8.7 MB/s
atobey@brak ~/src/pcstat $ ./pcstat testfile
|--------------------+----------------+------------+-----------+---------|
| Name               | Size           | Pages      | Cached    | Percent |
|--------------------+----------------+------------+-----------+---------|
| testfile           | 10485760       | 2560       | 1         | 0       |
|--------------------+----------------+------------+-----------+---------|

Building

git clone https://github.com/tobert/pcstat.git
cd pcstat
go build
sudo cp -a pcstat /usr/local/bin
pcstat /usr/local/bin/pcstat

Requirements

Go 1.17 or higher.

From the mincore(2) man page:

  • Available since Linux 2.3.99pre1 and glibc 2.2.
  • mincore() is not specified in POSIX.1-2001, and it is not available on all UNIX implementations.
  • Before kernel 2.6.21, mincore() did not return correct information some mappings.

Author

A. Tobey [email protected] @[email protected]

License

Apache 2.0

pcstat's People

Contributors

aivarasbaranauskas avatar arstercz avatar aybabtme avatar cholcombe973 avatar iwinux avatar jamessanford avatar jessegersensonchess avatar kokes avatar manniwood avatar tobert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pcstat's Issues

Add time information to output

Add -mtime -atime -ctime to include them in the output. With relatime, it's probably useful enough to see how long the file has been untouched. For apps that write into files, mtime is always useful. ctime is included because while I can't think of a use for it right now, it's on the way and completes the trio.

Also add timestamps to all output. Pick a format for JSON that's easy to load in Javascript (probably unix epoch).

needs tests

There aren't any tests right now. Unfortunately the dd test in the README requires root access so that won't do.

The right way is probably to have tests create temp files and use madvise() to cache pages and validate everything is working.

a fmt bug

I think you forgot to add the pid parameter, which also resulted in the inability to enter the container's mnt namespace

func getMountNs(pid int) int {
	fname := fmt.Sprintf("/proc/%d/ns/mnt") //here

pcstat syscall mincore failed with bad address if file is larger than 512MB on arm64 4K_PAGES machines

System: Ubuntu 16.04 LTS on Cavium 48core ARMv8 ThunderX1
Linux thunderx1 4.4.0-36-generic #55-Ubuntu SMP Thu Aug 11 18:05:42 UTC 2016 aarch64 aarch64 aarch64 GNU/Linux

pcstat failed if file is larger than 512MB. Our page size was 4096, however pcstat used 65536. pcstat also calculated the wrong page count on arm64 system.

Test 1:
pcstat /var/lib/cassandra/data/keyspace1/standard1-19ce2110716e11e7843f219b546b9b42/test
+-----------------------------------------------------------------------------------+----------------+------------+-----------+---------+
| Name | Size (bytes) | Pages | Cached | Percent |
|-----------------------------------------------------------------------------------+----------------+------------+-----------+---------|
| /var/lib/cassandra/data/keyspace1/standard1-19ce2110716e11e7843f219b546b9b42/test | 525107053 | 8013 | 8013 | 100.000 |
+-----------------------------------------------------------------------------------+----------------+------------+-----------+---------+

Test 2:
cat mc-69-big-Data.db >> test

pcstat /var/lib/cassandra/data/keyspace1/standard1-19ce2110716e11e7843f219b546b9b42/test
2017/08/08 13:08:14 skipping "/var/lib/cassandra/data/keyspace1/standard1-19ce2110716e11e7843f219b546b9b42/test": syscall SYS_MINCORE failed: bad address
+-------+----------------+------------+-----------+---------+
| Name | Size (bytes) | Pages | Cached | Percent |
|-------+----------------+------------+-----------+---------|
+-------+----------------+------------+-----------+---------+

ls -l /var/lib/cassandra/data/keyspace1/standard1-19ce2110716e11e7843f219b546b9b42
-rw-r--r-- 1 root root 599909718 Aug 8 13:08 test

getconf PAGE_SIZE
4096

cat /proc/meminfo
MemTotal: 32929196 kB
MemFree: 184936 kB
MemAvailable: 19768376 kB
Buffers: 87476 kB
Cached: 19477888 kB
SwapCached: 0 kB
Active: 5676236 kB
Inactive: 15960632 kB
Active(anon): 2092140 kB
Inactive(anon): 8664 kB
Active(file): 3584096 kB
Inactive(file): 15951968 kB
Unevictable: 9921816 kB
Mlocked: 9921816 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 4 kB
Writeback: 0 kB
AnonPages: 11993340 kB
Mapped: 11821268 kB
Shmem: 9284 kB
Slab: 423280 kB
SReclaimable: 340060 kB
SUnreclaim: 83220 kB
KernelStack: 18416 kB
PageTables: 279516 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 16464596 kB
Committed_AS: 15227224 kB
VmallocTotal: 133142937536 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
AnonHugePages: 9535488 kB
CmaTotal: 0 kB
CmaFree: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB

% calculation uses integer math

╭─mstump@work  ~/src/pcstat ‹› ‹master› 
╰─$ ./pcstat ~/Downloads/2014-01-07-wheezy-raspbian.img 
|--------------------------------------------------------+----------------+------------+-----------+---------|
| Name                                                   | Size           | Pages      | Cached    | Percent |
|--------------------------------------------------------+----------------+------------+-----------+---------|
| /Users/mstump/Downloads/2014-01-07-wheezy-raspbian.img | 2962227200     | 723200     | 0         | 0       |
|--------------------------------------------------------+----------------+------------+-----------+---------|
╭─mstump@work  ~/src/pcstat ‹› ‹master› 
╰─$ cat /Users/mstump/Downloads/2014-01-07-wheezy-raspbian.img > /dev/null    
╭─mstump@work  ~/src/pcstat ‹› ‹master› 
╰─$ ./pcstat ~/Downloads/2014-01-07-wheezy-raspbian.img                   
|--------------------------------------------------------+----------------+------------+-----------+---------|
| Name                                                   | Size           | Pages      | Cached    | Percent |
|--------------------------------------------------------+----------------+------------+-----------+---------|
| /Users/mstump/Downloads/2014-01-07-wheezy-raspbian.img | 2962227200     | 723200     | 650407    | 0       |
|--------------------------------------------------------+----------------+------------+-----------+---------|
╭─mstump@work  ~/src/pcstat ‹› ‹master› 
╰─$ cat /Users/mstump/Downloads/2014-01-07-wheezy-raspbian.img > /dev/null
╭─mstump@work  ~/src/pcstat ‹› ‹master› 
╰─$ ./pcstat ~/Downloads/2014-01-07-wheezy-raspbian.img                   
|--------------------------------------------------------+----------------+------------+-----------+---------|
| Name                                                   | Size           | Pages      | Cached    | Percent |
|--------------------------------------------------------+----------------+------------+-----------+---------|
| /Users/mstump/Downloads/2014-01-07-wheezy-raspbian.img | 2962227200     | 723200     | 723200    | 100     |
|--------------------------------------------------------+----------------+------------+-----------+---------|

Use syscall numbers from x/sys/unix

As noted in #25, pcstat does not build for linux/arm64 and it's due to SYS_SETNS being hardcoded for linux/{amd64,386} and nothing else. I looked around and saw SYS_SETNS being specified in x/sys/unix, it was added a few months after you started this project (and later added for arm64 as well).

If I understand it correctly, we can safely remove the two files specifying SYS_SETNS and use unix.SYS_SETNS? I'm not super fluent in this area, so let me know if I'm totally off here.

In any case, I've commited the (trivial) change here, let me know if you want me to open a PR. kokes@da613da

problems while installing

go build
warning: GOPATH set to GOROOT (/usr/lib/golang) has no effect
mincore.go:24:2: cannot find package "golang.org/x/sys/unix" in any of:
/usr/lib/golang/src/golang.org/x/sys/unix (from $GOROOT)
($GOPATH not set)

already install go,but the file '/usr/lib/golang/src/golang.org/x/sys/unix' does not exist.
i found a file : /usr/lib/golang/src/internal/syscall/unix

pcstat no longer builds after latest merge

I'm trying to install / build pcstat on an AWS instance running Ubuntu Linux, but am getting multiple failures.

root@node0:~# go get golang.org/x/sys/unix
# golang.org/x/sys/unix
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:31: clen redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:784
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:44: ParseDirent redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:797
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:70: Pipe redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux_amd64.go:108
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:82: (*SockaddrInet4).sockaddr redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:291
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:96: (*SockaddrInet6).sockaddr redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:305
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:111: (*SockaddrUnix).sockaddr redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:320
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:135: Getsockname redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:492
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:147: ImplementsGetwd redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:164
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:149: Getwd redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:168
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:158: Getgroups redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:181
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:158: too many errors
root@node0:~# go get github.com/tobert/pcstat/pcstat
# golang.org/x/sys/unix
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:31: clen redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:784
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:44: ParseDirent redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:797
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:70: Pipe redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux_amd64.go:108
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:82: (*SockaddrInet4).sockaddr redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:291
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:96: (*SockaddrInet6).sockaddr redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:305
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:111: (*SockaddrUnix).sockaddr redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:320
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:135: Getsockname redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:492
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:147: ImplementsGetwd redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:164
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:149: Getwd redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:168
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:158: Getgroups redeclared in this block
    previous declaration at /usr/src/golang.org/x/sys/unix/syscall_linux.go:181
/usr/src/golang.org/x/sys/unix/syscall_solaris.go:158: too many errors

Hopefully the following provides the information needed about the environment:

root@node0:~# uname -a
Linux node0 3.13.0-36-generic #63-Ubuntu SMP Wed Sep 3 21:30:07 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

root@node0:~# go version
go version go1.2.1 linux/amd64

If anything else is needed, please let me know.

At this point in writing the issue, I am guessing that the problem may exist from a dependency of pcstat (golang.org/x/sys/unix)? If that's the case, well... just raising awareness of this for now.

add sleep loop option

Add a -interval / -n option to make pcstat display results every N seconds (or fractions of a second). Do not bother with \r or other terminal interactions to keep it simple. Just print a new dataset on every iteration. Should work with all output modes.

e.g.

pcstat -interval 1 -json > pcstats.json
pcstat -n 1
pcstat -terse -n 1

Ideally a hook can be added inside the getMincore() function to accept a function that it will call in a loop to avoid the open/mmap on every iteration. This is fairly complicated when multiple files are in play, so I need to think about how to do it some more.

aarch64

pcstat not supported aarch64 version to invoke command,prompt cannot execute binary file error

Name and year in LICENSE

Noticed the license is kept as the original template, without your name and year range. Not sure if it changes anything in terms of legal implications, but it probably wouldn't hurt to include these things in the LICENSE file.

some file appears to be 0 bytes in length

once a file is 0 bytes, pcstat is stop. and do not deal with other files.

$ ./pcstat /lib/x86_64-linux-gnu/libnsl-2.27.so
|--------------------------------------+----------------+------------+-----------+---------|
| Name | Size | Pages | Cached | Percent |
|--------------------------------------+----------------+------------+-----------+---------|
| /lib/x86_64-linux-gnu/libnsl-2.27.so | 97176 | 24 | 24 | 100.000 |
|--------------------------------------+----------------+------------+-----------+---------|

$ ./pcstat /lib/x86_64-linux-gnu/libnsl-2.27.so /lib/x86_64-linux-gnu/liblzma.so.5.2.2
|----------------------------------------+----------------+------------+-----------+---------|
| Name | Size | Pages | Cached | Percent |
|----------------------------------------+----------------+------------+-----------+---------|
| /lib/x86_64-linux-gnu/libnsl-2.27.so | 97176 | 24 | 24 | 100.000 |
| /lib/x86_64-linux-gnu/liblzma.so.5.2.2 | 153984 | 38 | 38 | 100.000 |
|----------------------------------------+----------------+------------+-----------+---------|

$ ./pcstat /home/gpu2/data1/rook/osd2/current/omap/LOCK
2019/11/21 08:07:04 /home/gpu2/data1/rook/osd2/current/omap/LOCK appears to be 0 bytes in length

$ ./pcstat /lib/x86_64-linux-gnu/libnsl-2.27.so /lib/x86_64-linux-gnu/liblzma.so.5.2.2 /home/gpu2/data1/rook/osd2/current/omap/LOCK
2019/11/21 08:08:30 /home/gpu2/data1/rook/osd2/current/omap/LOCK appears to be 0 bytes in length

check page cache in docker

i tried pcstat on my debian8 vm. it worked fine.
image

but when i tried it on a docker instance, no matter which file i checked, it always show 100% cached.
image

i wonder if anyone know about this issue ?

Having trouble compiling on ubuntu

I get the following error when running "go get github.com/tobert/pcstat/pcstat"

/home/ubuntu/go/src/golang.org/x/sys/unix/zsyscall_linux_amd64.go:29: error: undefined reference to 'golang.org_x_sys_unix.use'
/home/ubuntu/go/src/golang.org/x/sys/unix/zsyscall_linux_amd64.go:30: error: undefined reference to 'golang.org_x_sys_unix.use'
/home/ubuntu/go/src/golang.org/x/sys/unix/zsyscall_linux_amd64.go:46: error: undefined reference to 'golang.org_x_sys_unix.use'
/home/ubuntu/go/src/golang.org/x/sys/unix/zsyscall_linux_amd64.go:69: error: undefined reference to 'golang.org_x_sys_unix.use'
collect2: error: ld returned 1 exit status

My go version is:
go version xgcc (Ubuntu 4.9.1-0ubuntu1) 4.9.1 linux/amd64

My OS is:

uname -a
Linux ip-10-0-2-186 3.13.0-48-generic #80-Ubuntu SMP Thu Mar 12 11:16:15 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

Ubuntu 14.04.3 LTS

Note that command "go get golang.org/x/sys/unix" runs successfully.

Any help greatly appreciated.

Provide binary artifacts through Releases?

Perhaps Releases could be used to distribute pcstat artifacts. It would be a more obvious place to look, a more credible place than "an old branch", and, last but not least, would allow for new os/architecture combos - notably arm64 has gained prominence in the recent years, so that would be helpful.

My dummy Makefile could build at least some of these targets - though not linux/amd64, but that's due to the older x/sys and the hardcoded SYS_SETNS, which is now included for many arches in x/sys natively)... but that's all for a separate ticket.

.PHONY: dist

BUILD_OS ?= linux darwin
BUILD_ARCH ?= amd64 386 arm64

dist:
	mkdir -p dist
	@for os in $(BUILD_OS) ; do \
		for arch in $(BUILD_ARCH); do \
			echo "Buidling" $$arch $$os; \
			binpath="dist/pcstat-$$os-$$arch"; \
			CGO_ENABLED=0 GOARCH=$$arch GOOS=$$os go build -o $$binpath ./pcstat; \
		done \
	done
	(cd dist; shasum -a 256 * > sha256sums.txt)

(perhaps gzipping would be nice as well)

Have trouble installing pcstat

when I install pcstat according to official instruction, I get following hits:
go get: module github.com/tobert/pcstat@upgrade found (v0.0.1), but does not contain package github.com/tobert/pcstat/pcstat

Anyone know why, thanks!

pcstat to show the top [number] cached file in the linux os globally

Does anyone need this feature? Use pcstat to show the top [number] cached file in the linux os globally.

For example, I know that the os caches a lot of memories, but I donnot know which big files are being cached by the os.

$ free -h
              total        used        free      shared  buff/cache   available
Mem:            15G        6.4G        2.3G        1.1G        6.9G        7.7G
Swap:          975M        268K        975M

I add a new param --top to pcstat, it reads the /proc/[pid]/stat files, and finds those processes who's rss is not 0, then collects all the files opened by those processes, gets stats and sort them by cached pages.

Here is an example:

$ sudo pcstat --top 3  --bname  
+-------------+----------------+------------+-----------+---------+
| Name        | Size (bytes)   | Pages      | Cached    | Percent |
|-------------+----------------+------------+-----------+---------|
| chrome      | 114911208      | 28055      | 25476     | 090.807 |
| pycharm.jar | 95177431       | 23237      | 11479     | 049.400 |
| atom        | 62641344       | 15294      | 10578     | 069.164 |
+-------------+----------------+------------+-----------+---------+

interpreting histogram format

Thanks for creating such a tool, and I find it very useful when troubleshooting IO issues during development (under both Linux and macOS).

Could you please add some documentation explaining how to interpret the histogram format output? Initially I assume it represents a visualization of -json -pps but since histogram is 2D, I have some difficulty interpreting it.

Formatting percentages without leading zeroes

First and foremost thanks for the wonderful tool, it works great. Here's just one readability nitpick:

The output is kinda hard to read for small percentages due to the leading zeroes:

+------------------------+----------------+------------+-----------+---------+
| Name                   | Size (bytes)   | Pages      | Cached    | Percent |
|------------------------+----------------+------------+-----------+---------|
| LICENSE                | 11323          | 3          | 0         | 000.000 |
| README.md              | 7114           | 2          | 0         | 000.000 |
| go.mod                 | 102            | 1          | 1         | 100.000 |
| go.sum                 | 207            | 1          | 0         | 000.000 |
| mincore.go             | 2449           | 1          | 0         | 000.000 |
| mnt_ns_linux.go        | 1779           | 1          | 0         | 000.000 |
| mnt_ns_unix.go         | 741            | 1          | 0         | 000.000 |
| pc                     | 2535856        | 620        | 267       | 043.065 |
| pcstatus.go            | 2735           | 1          | 0         | 000.000 |
| syscall_linux_386.go   | 746            | 1          | 0         | 000.000 |
| syscall_linux_amd64.go | 752            | 1          | 0         | 000.000 |
+------------------------+----------------+------------+-----------+---------+

I think it would be more scannable if the leading zeroes weren't there

+------------------------+----------------+------------+-----------+---------+
| Name                   | Size (bytes)   | Pages      | Cached    | Percent |
|------------------------+----------------+------------+-----------+---------|
| LICENSE                | 11323          | 3          | 0         |   0.000 |
| README.md              | 7114           | 2          | 0         |   0.000 |
| go.mod                 | 102            | 1          | 1         | 100.000 |
| go.sum                 | 207            | 1          | 0         |   0.000 |
| mincore.go             | 2449           | 1          | 0         |   0.000 |
| mnt_ns_linux.go        | 1779           | 1          | 0         |   0.000 |
| mnt_ns_unix.go         | 741            | 1          | 0         |   0.000 |
| pc                     | 2535856        | 620        | 460       |  74.194 |
| pcstatus.go            | 2735           | 1          | 0         |   0.000 |
| syscall_linux_386.go   | 746            | 1          | 0         |   0.000 |
| syscall_linux_amd64.go | 752            | 1          | 0         |   0.000 |
+------------------------+----------------+------------+-----------+---------+

I just changed all the %07.3f to %7.3f, so that a space would be used to fill it from the left.

I did see the comment

		// %07.3f was chosen to make it easy to scan the percentages vertically
		// I tried a few different formats only this one kept the decimals aligned

So I don't know if this suggested implementation solves your issue or not - I certainly find it more scannable vertically, but that's just me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.