Hatena::ブログ(Diary)

ablog このページをアンテナに追加 RSSフィード Twitter

2014-12-22

top でプロセスが使っていたCPU番号を表示する

topを実行して、f 押して j 押せばプロセスが最後に使ったCPU番号を表示できる。

  • top を実行して
$ top

f:id:yohei-a:20141222211054p:image:w640

  • f 押して

f:id:yohei-a:20141222211046p:image:w640

  • j 押して、return すると

f:id:yohei-a:20141222211530p:image:w640

  • P列目(右から2つ目)にCPU番号が表示される

f:id:yohei-a:20141222211039p:image:w640

top -H でCPU使用率の高いスレッドを調べる

top でスレッド単位で表示させたい場合は -H オプションを使う。

$ top -H 

top を起動してから、H(shift + h) でもよい。

$ man top
-H : Threads toggle
     Starts top with the last remembered ’H’ state reversed.  When this toggle is On, all individual threads will be displayed.  Otherwise, top
     displays a summation of all threads in a process.

2014-12-19

micbench でノートPCのメモリアクセスレイテンシを計測してみた

f:id:yohei-a:20141219233047p:image:w640

環境

ハードウェア
$ cat /proc/cpuinfo |grep 'model name'|head -1
model name	: Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
$ cd /sys/devices/system/cpu/cpu0/cache
$ echo `cat index0/level` `cat index0/type` `cat index0/size`
1 Data 32K
$ echo `cat index1/level` `cat index1/type` `cat index1/size`
1 Instruction 32K
$ echo `cat index2/level` `cat index2/type` `cat index2/size`
2 Unified 256K
$ echo `cat index3/level` `cat index3/type` `cat index3/size`
3 Unified 3072K
OS

手順

#!/bin/bash

FILE=micbench_mem.log

for i in $(seq 1 10000); do
  echo ${i} $(micbench mem --rand --size ${i}KB --affinity 0:c0 --timeout 1|perl -lane '/clk_per_op/ and print $F[1]') >> $FILE
done
  • グラフ化する
    • 上のはEXCELでグラフ化しました。

gdb でレジスタの値を書き換えてみる

同僚に教えてもらった gdb で実行中のプロセスにアタッチして、writeシステムコール発行直前でレジスタのファイルディスクリプタを書換えるというのを試してみた。

f:id:yohei-a:20141219221907p:image:w640

  • write_loop.c
#include <unistd.h>

int main(void)
{
        while(1) {
                write(1, "foo\n", 4);
        }
}
$ gcc -o write_loop write_loop.c
  • 実行する
$ ./write_loop > foo.log
  • PID を調べて、
$ ps auxw|grep [w]rite_loop
yazekats  5873 97.6  0.0   3968   284 pts/0    R+   22:01   1:18 ./write_loop
$ ls -l /proc/5873/fd 
total 0
lrwx------ 1 yazekats yazekats 64 Dec 19 22:10 0 -> /dev/pts/0
l-wx------ 1 yazekats yazekats 64 Dec 19 22:10 1 -> /home/yazekats/Documents/work/foo.log
lrwx------ 1 yazekats yazekats 64 Dec 19 22:03 2 -> /dev/pts/0
$ gdb -p 5873
(gdb) b write
Breakpoint 1 at 0x3ba66db780
(gdb) n
Single stepping until exit from function write,
which has no line number information.
0x00000000004004dc in main ()
(gdb) n
Single stepping until exit from function main,
which has no line number information.

Breakpoint 1, 0x0000003ba66db780 in write () from /lib64/libc.so.6
(gdb) info reg
rax            0x4	4
rbx            0x0	0
rcx            0xffffffffffffffff	-1
rdx            0x4	4
rsi            0x4005d8	4195800
rdi            0x1	1 ★FDは1の標準出力
rbp            0x7fff77c9b5a0	0x7fff77c9b5a0
rsp            0x7fff77c9b598	0x7fff77c9b598
r8             0x3ba698f300	256198112000
r9             0x3ba620e9f0	256190245360
r10            0x7fff77c9b320	140735203095328
r11            0x246	582
r12            0x4003e0	4195296
r13            0x7fff77c9b680	140735203096192
r14            0x0	0
r15            0x0	0
rip            0x3ba66db790	0x3ba66db790 <__write_nocancel+7>
eflags         0x246	[ PF ZF IF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) set $rdi=2
(gdb) info reg
rax            0x4	4
rbx            0x0	0
rcx            0xffffffffffffffff	-1
rdx            0x4	4
rsi            0x4005d8	4195800
rdi            0x2	2 ★FDが2の標準エラーに変わっている
rbp            0x7fff77c9b5a0	0x7fff77c9b5a0
rsp            0x7fff77c9b598	0x7fff77c9b598
r8             0x3ba698f300	256198112000
r9             0x3ba620e9f0	256190245360
r10            0x7fff77c9b320	140735203095328
r11            0x246	582
r12            0x4003e0	4195296
r13            0x7fff77c9b680	140735203096192
r14            0x0	0
r15            0x0	0
rip            0x3ba66db790	0x3ba66db790 <__write_nocancel+7>
eflags         0x246	[ PF ZF IF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) n

お、標準エラーに出力された!

$ ./write_loop > foo.log
foo ← これが出力される

2014-12-13

Huge Page の解放について

ちょっと検証してみたメモ。


検証結果

  • vm.nr_hugepages を設定する
[root@yazekats-linux ~]# grep -i hugepage /proc/meminfo
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
[root@yazekats-linux ~]# sysctl -w vm.nr_hugepages=200
vm.nr_hugepages = 200
[root@yazekats-linux ~]# grep -i hugepage /proc/meminfo
AnonHugePages:         0 kB
HugePages_Total:     200
HugePages_Free:      200
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
  • Huge Page を System V 共有メモリとして使うプログラムを実行する
[root@yazekats-linux hugepage_test]# gdb ./hugepage-shm
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/yazekats/Documents/github/yoheia/misc/hugepage_test/hugepage-shm...done.
(gdb) b 68
Breakpoint 1 at 0x40076c: file hugepage-shm.c, line 68.
(gdb) r
Starting program: /home/yazekats/Documents/github/yoheia/misc/hugepage_test/hugepage-shm 
shmid: 0x25002c

Breakpoint 1, main () at hugepage-shm.c:68
68		if (shmaddr == (char *)-1) {
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64
(gdb) 
  • Huge Page が割り当てられている
[yazekats@yazekats-linux ~]$ grep -i hugepage /proc/meminfo 
AnonHugePages:         0 kB
HugePages_Total:     200
HugePages_Free:      200
HugePages_Rsvd:      128 ★
HugePages_Surp:        0
Hugepagesize:       2048 kB
HugePages_Total is the size of the pool of huge pages.
HugePages_Free  is the number of huge pages in the pool that are not yet
                allocated.
HugePages_Rsvd★  is short for "reserved," and is the number of huge pages for
                which a commitment to allocate from the pool has been made,
                but no allocation has yet been made.  Reserved huge pages
                guarantee that an application will be able to allocate a
                huge page from the pool of huge pages at fault time.
HugePages_Surp  is short for "surplus," and is the number of huge pages in
                the pool above the value in /proc/sys/vm/nr_hugepages. The
                maximum number of surplus huge pages is controlled by
                /proc/sys/vm/nr_overcommit_hugepages.
[yazekats@yazekats-linux ~]$ ps auxw|grep [h]ugepage-shm
root      2509  0.0  0.0 187884 12928 pts/0    S+   12:09   0:00 gdb ./hugepage-shm
root      2524★  0.0  0.0   3972   284 pts/0    t    12:10   0:00 /home/yazekats/Documents/github/yoheia/misc/hugepage_test/hugepage-shm
  • PID:2524 が作成した共有メモリセグメントの shmid を調べる。
[root@yazekats-linux ~]# ipcs -p|grep 2524
2424876★    root       2524       2524      
  • shmid:2424876 の共有メモリセグメントを確認する。
[root@yazekats-linux ~]# ipcs -m |grep 2424876
0x00000002 2424876    root       600        268435456★  1 

268435456 bytes = 256MB使っている

(gdb) quit
A debugging session is active.

	Inferior 1 [process 2524] will be killed.

Quit anyway? (y or n) y
[yazekats@yazekats-linux ~]$ ps auxw|grep [h]ugepage-shm
[yazekats@yazekats-linux ~]$
  • Huge Page は解放されていない。
[yazekats@yazekats-linux ~]$ grep -i hugepage /proc/meminfo 
AnonHugePages:         0 kB
HugePages_Total:     200
HugePages_Free:      200
HugePages_Rsvd:      128
HugePages_Surp:        0
Hugepagesize:       2048 kB
  • 共有メモリも解放されない。
[root@yazekats-linux ~]# ipcs -p|grep 2524
2424876    root       2524       2524      
[root@yazekats-linux ~]# ipcs -m |grep 2424876
0x00000002 2424876    root       600        268435456  0     
  • ipcrm コマンドで共有メモリを解放する
[root@yazekats-linux ~]# ipcrm -m 2424876
  • Huge Page も共有メモリも解放されている
[root@yazekats-linux ~]# grep -i hugepage /proc/meminfo 
AnonHugePages:         0 kB
HugePages_Total:     200
HugePages_Free:      200
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
[root@yazekats-linux ~]# ipcs -p|grep 2524
[root@yazekats-linux ~]# ipcs -m |grep 2424876

参考

hugepage-shm.c のソースコード
/*
 * hugepage-shm:
 *
 * Example of using huge page memory in a user application using Sys V shared
 * memory system calls.  In this example the app is requesting 256MB of
 * memory that is backed by huge pages.  The application uses the flag
 * SHM_HUGETLB in the shmget system call to inform the kernel that it is
 * requesting huge pages.
 *
 * For the ia64 architecture, the Linux kernel reserves Region number 4 for
 * huge pages.  That means that if one requires a fixed address, a huge page
 * aligned address starting with 0x800000... will be required.  If a fixed
 * address is not required, the kernel will select an address in the proper
 * range.
 * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
 *
 * Note: The default shared memory limit is quite low on many kernels,
 * you may need to increase it via:
 *
 * echo 268435456 > /proc/sys/kernel/shmmax
 *
 * This will increase the maximum size per shared memory segment to 256MB.
 * The other limit that you will hit eventually is shmall which is the
 * total amount of shared memory in pages. To set it to 16GB on a system
 * with a 4kB pagesize do:
 *
 * echo 4194304 > /proc/sys/kernel/shmall
 */

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>

#ifndef SHM_HUGETLB
#define SHM_HUGETLB 04000
#endif

#define LENGTH (256UL*1024*1024)

#define dprintf(x)  printf(x)

/* Only ia64 requires this */
#ifdef __ia64__
#define ADDR (void *)(0x8000000000000000UL)
#define SHMAT_FLAGS (SHM_RND)
#else
#define ADDR (void *)(0x0UL)
#define SHMAT_FLAGS (0)
#endif

int main(void)
{
	int shmid;
	unsigned long i;
	char *shmaddr;

	shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
	if (shmid < 0) {
		perror("shmget");
		exit(1);
	}
	printf("shmid: 0x%x\n", shmid);

	shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
	if (shmaddr == (char *)-1) {
		perror("Shared memory attach failure");
		shmctl(shmid, IPC_RMID, NULL);
		exit(2);
	}
	printf("shmaddr: %p\n", shmaddr);

	dprintf("Starting the writes:\n");
	for (i = 0; i < LENGTH; i++) {
		shmaddr[i] = (char)(i);
		if (!(i % (1024 * 1024)))
			dprintf(".");
	}
	dprintf("\n");

	dprintf("Starting the Check...");
	for (i = 0; i < LENGTH; i++)
		if (shmaddr[i] != (char)i) {
			printf("\nIndex %lu mismatched\n", i);
			exit(3);
		}
	dprintf("Done.\n");

	if (shmdt((const void *)shmaddr) != 0) {
		perror("Detach failure");
		shmctl(shmid, IPC_RMID, NULL);
		exit(4);
	}

	shmctl(shmid, IPC_RMID, NULL);

	return 0;
}
hugepage-shm.c のコンパイル手順
[yazekats@yazekats-linux hugepage_test]$  gcc -g -o hugepage-shm hugepage-shm.c
[yazekats@yazekats-linux hugepage_test]$  ls -1
hugepage-shm ★←実行可能ファイルができる
hugepage-shm.c
hugepage-shm.c の実行手順
[root@yazekats-linux hugepage_test]# ./hugepage-shm 
shmid: 0x22802c
shmaddr: 0x7f8aa5600000
Starting the writes:
................................................................................................................................................................................................................................................................
Starting the Check...Done.

環境

[root@yazekats-linux ~]# cat /etc/issue
Oracle Linux Server release 6.4
Kernel \r on an \m

[root@yazekats-linux ~]# uname -r
2.6.39-400.17.1.el6uek.x86_64

補足(2014/12/14):

vm.nr_hugepages を 0 にしても解放されません。

[root@yazekats-linux ~]# sysctl -w vm.nr_hugepages=0
vm.nr_hugepages = 0
[root@yazekats-linux ~]# grep -i hugepage /proc/meminfo
AnonHugePages:         0 kB
HugePages_Total:     128
HugePages_Free:      128
HugePages_Rsvd:      128
HugePages_Surp:      128
Hugepagesize:       2048 kB
[root@yazekats-linux ~]# tail /etc/sysctl.conf
kernel.msgmax = 65536

# Controls the maximum shared segment size, in bytes
kernel.shmmax = 68719476736

# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 4294967296

vm.nr_hugepages=0

[root@yazekats-linux ~]# sysctl -p
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
vm.nr_hugepages = 0
[root@yazekats-linux ~]# grep -i hugepage /proc/meminfo
AnonHugePages:         0 kB
HugePages_Total:     128
HugePages_Free:      128
HugePages_Rsvd:      128
HugePages_Surp:      128
Hugepagesize:       2048 kB 

micbench をインストールしてみた

インストール

$ sudo yum install numactl
$ sudo yum install numactl-devel
$ git clone git://github.com/hayamiz/micbench.git
$ cd micbench/
$ ./autogen.sh 
$ ./configure 
$ sudo make install

使ってみる

  • とりあえず実行
$ micbench mem -m 1 -t 10 -R -a 0:c0 -s 16K -v
shuffle time: 0.000022
loop end: t=10.000213
access_pattern	random
multiplicity	1
local	false
page_size	4096
size	16384
use_hugepages	false
total_ops	7601389568
total_clk	25939357289
exec_time	10.000213
ops_per_sec	7.601228e+08
clk_per_op	3.412449e+00 ★3クロック
total_exec_time	10.716373
[yazekats@yazekats-linux ~]$ cat /proc/cpuinfo |grep 'model name'|head -1
model name	: Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
[yazekats@yazekats-linux ~]$ cd /sys/devices/system/cpu/cpu0/cache
[yazekats@yazekats-linux cache]$ echo `cat index0/level` `cat index0/type` `cat index0/size`
1 Data 32K
[yazekats@yazekats-linux cache]$ echo `cat index1/level` `cat index1/type` `cat index1/size`
1 Instruction 32K
[yazekats@yazekats-linux cache]$ echo `cat index2/level` `cat index2/type` `cat index2/size`
2 Unified 256K
[yazekats@yazekats-linux cache]$ echo `cat index3/level` `cat index3/type` `cat index3/size`
3 Unified 3072K
[yazekats@yazekats-linux cache]$ micbench mem --rand --size 16K --affinity 0:c0 --timeout 10
loop end: t=10.000334
access_pattern	random
multiplicity	1
local	false
page_size	4096
size	16384
use_hugepages	false
total_ops	7698382848
total_clk	25931027932
exec_time	10.000334
ops_per_sec	7.698126e+08
clk_per_op	3.368373e+00 ★3クロック
total_exec_time	10.388622
[yazekats@yazekats-linux cache]$ micbench mem --rand --size 128K --affinity 0:c0 --timeout 10
loop end: t=10.000659
access_pattern	random
multiplicity	1
local	false
page_size	4096
size	131072
use_hugepages	false
total_ops	2115764224
total_clk	25939831721
exec_time	10.000659
ops_per_sec	2.115625e+08
clk_per_op	1.226027e+01 ★12クロック
total_exec_time	11.275838
[yazekats@yazekats-linux cache]$ micbench mem --rand --size 2MB --affinity 0:c0 --timeout 10
loop end: t=10.002390
access_pattern	random
multiplicity	1
local	false
page_size	4096
size	2097152
use_hugepages	false
total_ops	486014976
total_clk	25945385592
exec_time	10.002390
ops_per_sec	4.858988e+07
clk_per_op	5.338392e+01 ★53クロック
total_exec_time	10.857365
[yazekats@yazekats-linux cache]$ micbench mem --rand --size 256MB --affinity 0:c0 --timeout 10
loop end: t=10.004887
access_pattern	random
multiplicity	1
local	false
page_size	4096
size	268435456
use_hugepages	false
total_ops	113770496
total_clk	25952470523
exec_time	10.004887
ops_per_sec	1.137149e+07
clk_per_op	2.281125e+02 ★228クロック
total_exec_time	13.071042

参考


追記(2014/12/14):

  • micbench_mem.sh
#!/bin/bash

FILE=micbench_mem.log

for i in $(seq 1 1000); do
  memsize=$((${i}*${i}))
  echo ${memsize} $(micbench mem --rand --size ${memsize}KB --affinity 0:c0 --timeout 1|perl -lane '/clk_per_op/ and print $F[1]') >> $FILE
done

Perfmonger をインストールしてみた

インストール

$ git clone git://github.com/hayamiz/perfmonger.git
$ cd perfmonger/
$ ./autogen.sh
$ ./configure 
$ sudo make install

使ってみる

$ perfmonger record -i 0.1                                                             
{"time": 1418432543.6794, "cpuinfo": {"nr_cpu": 4, "all": {"usr": 0.00, "nice": 0.00, "sys": 0.00, "iowait": 0.00, "irq": 0.00, "soft": 0.00, "steal": 0.00, "guest": 0.00, "idle": 0.00}, "cpus": [{"usr": 0.00, "nice": 0.00, "sys": 0.00, "iowait": 0.00, "irq": 0.00, "soft": 0.00, "steal": 0.00, "guest": 0.00, "idle": 100.00}, {"usr": 0.00, "nice": 0.00, "sys": 0.00, "iowait": 0.00, "irq": 0.00, "soft": 0.00, "steal": 0.00, "guest": 0.00, "idle": 100.00}, {"usr": 0.00, "nice": 0.00, "sys": 0.00, "iowait": 0.00, "irq": 0.00, "soft": 0.00, "steal": 0.00, "guest": 0.00, "idle": 100.00}, {"usr": 0.00, "nice": 0.00, "sys": 0.00, "iowait": 0.00, "irq": 0.00, "soft": 0.00, "steal": 0.00, "guest": 0.00, "idle": 100.00}]}, "ioinfo": {"devices": ["sda", "dm-0", "dm-1", "dm-2", "dm-3"], "sda": {"riops": 0.0000, "wiops": 0.0000, "rsecps": 0.0000, "wsecps": 0.0000, "r_await": 0.0000, "w_await": 0.0000, "avgrq-sz": 0.0000, "avgqu-sz": 0.0000}, "dm-0": {"riops": 0.0000, "wiops": 0.0000, "rsecps": 0.0000, "wsecps": 0.0000, "r_await": 0.0000, "w_await": 0.0000, "avgrq-sz": 0.0000, "avgqu-sz": 0.0000}, "dm-1": {"riops": 0.0000, "wiops": 0.0000, "rsecps": 0.0000, "wsecps": 0.0000, "r_await": 0.0000, "w_await": 0.0000, "avgrq-sz": 0.0000, "avgqu-sz": 0.0000}, "dm-2": {"riops": 0.0000, "wiops": 0.0000, "rsecps": 0.0000, "wsecps": 0.0000, "r_await": 0.0000, "w_await": 0.0000, "avgrq-sz": 0.0000, "avgqu-sz": 0.0000}, "dm-3": {"riops": 0.0000, "wiops": 0.0000, "rsecps": 0.0000, "wsecps": 0.0000, "r_await": 0.0000, "w_await": 0.0000, "avgrq-sz": 0.0000, "avgqu-sz": 0.0000}, "total": {"riops": 0.0000, "wiops": 0.0000, "rsecps": 0.0000, "wsecps": 0.0000, "r_await": 0.0000, "w_await": 0.0000}}}

参考

2014-12-09

prociostat.pl と visualize_prociostat.R で Linux のプロセスのボトルネックを分析する

今日もモツ鍋を堪能されていた模様の @ さんが Linuxプロセスのアクティビティを追跡してグラフ化するツールPerl + R で作られたということで早速使ってみました。

プロセスユーザーモードCPUを使えているのか、I/O待ちになっているのかといった傾向を分析することができます。Oracle Database はCPUを使えているのか、どんな理由で待機している(CPUを使えていない)か見ることができるよう実装されていますが、そんなものはないプログラムでも /proc ファイルシステムを参照してプログラムの外側からボトルネック分析が可能になります。素晴らしい!

こんな感じのグラフができます。

f:id:yohei-a:20141209235041j:image:w640


ツール

prociostat.pl
$ perl prociostat.pl -C -p 13674 # PID:13674 の情報を取得
# perl prociostat.pl -C # 全てのプロセスの情報を取得
visualize_prociostat.R
# yum install R
  • 使用例)
$ Rscript visualize_prociostat.R process.13674.txt

使用例

$ grep -R foo . > /dev/null 2>&1 & 
[1] 14520
$ perl prociostat.pl -C -p 14520
pid 14520 uid   501 user  20.16 sys   8.16 r  11112370176 w            0 cmd grep-Rfoo.
^CBye! ←Ctrl+Cで停止
$ ls -1
process.14520.txt ★出力された CSV ファイル
prociostat.pl
visualize_prociostat.R
$ head process.14520.txt 
↓CSVの中身はこんな感じ
time,delta_utime,delta_stime,delta_delayacct_blkio_ticks,delta_read_bytes,delta_write_bytes
1418136011,4,4,9,23072768,0
1418136012,1,3,3,1216512,0
1418136013,1,2,1,315392,0
1418136014,2,4,1,237568,0
1418136015,6,5,13,22831104,0
1418136016,1,6,2,552960,0
1418136017,2,4,3,2043904,0
1418136018,0,2,2,573440,0
1418136019,1,2,1,1232896,0
  • visualize_prociostat.R でグラフ化(png)する
$ export LANG=C
$ Rscript visualize_prociostat.R process.14520.txt
$ ls -1
process.14520.txt
process.14520.txt.png ★生成されたグラフ(png)
prociostat.pl
visualize_prociostat.R
  • process.14520.txt.png を開いてみる

f:id:yohei-a:20141209235356p:image:w640

*1I/OブロッキングによりプロセスCPUをできなかった tick 数

*2CSVに出力されるので、EXCELなどでグラフ化することもできます

*3:/proc/<pid>/* を参照しているのでアクセス権がないと情報取得できない

2014-12-08

dstat + fluentd + Elasticsearch + kibana でノートPCをモニタリングする

id:kazeburo さんの dstat + fluentd + Elasticsearch + kibana でサーバモニタリングする - blog.nomadscafe.jp を参考に自分のノートPCを dstat + fluentd + Elasticsearch + kibana でモニタリングできるようにした。

Kibana の設定が一番難しかった。GUIでポチポチ設定するだけだが、思うようなグラフにならず苦労した。もう少し使いこなせるようになったら、kibana の設定方法を書きたい。


使用感

dstat で取得したCPU使用率をグラフにしたものです。

f:id:yohei-a:20141208111615p:image:w640


環境

  • Oracle Linux 6.4 (2.6.39-400.17.1.el6uek.x86_64)
  • httpd-2.2.15-26.0.1.el6.x86_64
  • Elasticsearch 1.4.1
  • Ruby 1.9.3
  • kibana 3.1.2

インストール&設定

  • コマンドは"$"で始まるものは一般ユーザー、"#"で始まるものは root で実行しています
Elasticsearch
$ curl -L -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.1.noarch.rpm
# rpm -ivh elasticsearch-1.4.1.noarch.rpm
# service elasticsearch start
$ curl -XPUT localhost:9200/_template/template_1 -d '
{
   "template" : "logstash-*",
   "mappings" : {
       "dstat": {
           "properties": {
                "host" : { "type" : "string", "index" : "not_analyzed" },
                "value" : {"type" : "double"}
           }
       }
   }
}
'
Kibana
$ curl -L -O https://download.elasticsearch.org/kibana/kibana/kibana-3.1.2.tar.gz
$ tar xfz kibana-3.1.2.tar.gz
# mv kibana-3.1.2/* /var/www/html/
fluentd
# yum install libyaml-0.1.3-1.4.el6.x86_64
# yum install libyaml-devel-0.1.3-1.4.el6.x86_64
# yum update libcom_err-1.42.8-1.0.2.el6.x86_64
# yum install libtool-2.2.6-15.5.el6.x86_64
# yum install bison-2.4.1-5.el6.x86_64
# yum install libcom_err-devel-1.42.8-1.0.2.el6.x86_64
# yum install libss-1.42.8-1.0.2.el6.x86_64
# yum install keyutils-libs-devel-1.4-5.el6.x86_64
# yum install krb5-devel-1.10.3-33.el6.x86_64
# yum install krb5-libs-1.10.3-33.el6.i686
# yum install libffi-devel-3.0.5-3.2.el6.x86_64
# yum install openssl-devel-1.0.1e-30.el6_6.4.x86_64
# yum install krb5-libs-1.10.3-33.el6.x86_64
# yum -y install curl-devel
# gpg2 --keyserver hkp://keys.gnupg.net --recv-keys ...
# curl -L https://get.rvm.io | bash -s stable
# rvm install 1.9.3
  • /etc/bashrc に以下を追記する。
source /etc/profile.d/rvm.sh
# gem install fluentd --no-ri --no-rdoc
# gem install fluent-plugin-dstat
# gem install fluent-plugin-map
# gem install fluent-plugin-elasticsearch
  • fluent.conf を作成する
# fluentd --setup /etc/fluent
  • /etc/fluent/fluent.conf に以下を記述する
<source>
  type dstat
  tag dstat
  option -lcn
  delay 5
</source>

<match dstat>
  type copy
  <store>
    type map
    tag  "map.dstat.loadavg-short"
    time time
    record {"value" => record["dstat"]["load avg"]["1m"], "stat" => "loadavg-short", "host" => record["hostname"]}
  </store>
  <store>
    type map
    tag  "map.dstat.cpu-usr"
    time time
    record {"value" => record["dstat"]["total cpu usage"]["usr"], "stat" => "cpu-usr", "host" => record["hostname"]}
  </store>
  <store>
    type map
    tag  "map.dstat.cpu-sys"
    time time
    record {"value" => record["dstat"]["total cpu usage"]["sys"], "stat" => "cpu-sys", "host" => record["hostname"]}
  </store>
  <store>
    type map
    tag  "map.dstat.cpu-hiq"
    time time
    record {"value" => record["dstat"]["total cpu usage"]["hiq"], "stat" => "cpu-hiq", "host" => record["hostname"]}
  </store>
  <store>
    type map
    tag  "map.dstat.cpu-siq"
    time time
    record {"value" => record["dstat"]["total cpu usage"]["siq"], "stat" => "cpu-siq", "host" => record["hostname"]}
  </store>
  <store>
    type map
    tag  "map.dstat.net-recv"
    time time
    record {"value" => record["dstat"]["net/total"]["recv"], "stat" => "net-recv", "host" => record["hostname"]}
  </store>  
  <store>
    type map
    tag  "map.dstat.net-send"
    time time
    record {"value" => record["dstat"]["net/total"]["send"], "stat" => "net-send", "host" => record["hostname"]}
  </store>  
</match>

<match map.dstat.*>
  type elasticsearch
  type_name       dstat
  host            localhost
  port            9200
  logstash_format true
  logstash_prefix logstash
  flush_interval  5s
</match>
# fluentd -c ./fluent/fluent.conf -vv &
# service httpd start

使ってみる

  • Blank Dashboard からダッシュボードを作成して保存する。