星期六, 4月 29, 2017

20170429 openSUSE eBPF/BCC workshop 小記

openSUSE eBPF/BCC workshop 小記

Notes:
  • Kernel config 可以參考 /boot/ 下 config-開頭對應自己目前的核心, 看相關參數有沒有開
例如
# grep   BPF   /boot/config-4.4.46-11-default
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NETFILTER_XT_MATCH_BPF=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_ACT_BPF=m
CONFIG_BPF_JIT=y
CONFIG_HAVE_BPF_JIT=y
CONFIG_BPF_EVENTS=y
# CONFIG_TEST_BPF is not set

安裝相關套件
# zypper   in   python-bcc
# zypper  in  bcc-examples

相關 examples 存放地方
# pwd
/usr/share/bcc/examples

觀察 hello world
# cat   /usr/share/bcc/examples/hello_world.py  
#!/usr/bin/env python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

# run in project examples directory with:
# sudo ./hello_world.py"
# see trace_fields.py for a longer example

from bcc import BPF

BPF(text='void kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); }').trace_print()

安裝 ( 更新 ) 目前的 kernel-default
# zypper  in  kernel-default

重新開機
# reboot
執行相關測試

# cd   /usr/share/bcc/examples/

執行 hello_world.py
# python   /usr/share/bcc/examples/hello_world.py

接下來可以嘗試在另外一個視窗 ssh 機器

就可以觀察到相關輸出

template:/usr/share/bcc/examples # python  /usr/share/bcc/examples/hello_world.py
           sshd-2314  [001] d..2   479.045754: : Hello, World!
           sshd-2864  [000] d..2   479.072225: : Hello, World!
           sshd-2864  [000] d..2   479.172032: : Hello, World!
           sshd-2864  [000] d..2   485.447949: : Hello, World!

另外一個測試

# cat  /usr/share/bcc/examples/tracing/trace_fields.py
#!/usr/bin/env python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

# This is an example of tracing an event and printing custom fields.
# run in project examples directory with:
# sudo ./trace_fields.py"

from bcc import BPF

prog = """
int hello(void *ctx) {
 bpf_trace_printk("Hello, World!\\n");
 return 0;
}
"""
b = BPF(text=prog)
b.attach_kprobe(event="sys_clone", fn_name="hello")
print "PID MESSAGE"
b.trace_print(fmt="{1} {5}")

進行測試
# python    /usr/share/bcc/examples/tracing/trace_fields.py
PID MESSAGE
2954 Hello, World!
2473 Hello, World!
3042 Hello, World!


其他的 examples 檔案可以在 https://github.com/iovisor/bcc/tree/master/examples 找到

# cd   /usr/share/bcc/examples/tracing/

# wget   https://raw.githubusercontent.com/iovisor/bcc/master/examples/tracing/sync_timing.py

# cat   sync_timing.py
#!/usr/bin/python
#
# sync_timing.py    Trace time between syncs.
#                   For Linux, uses BCC, eBPF. Embedded C.
#
# Written as a basic example of tracing time between events.
#
# Copyright 2016 Netflix, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

from __future__ import print_function
from bcc import BPF

# load BPF program
b = BPF(text="""
#include <uapi/linux/ptrace.h>
#include <linux/blkdev.h>

BPF_HASH(last);

void do_trace(struct pt_regs *ctx) {
   u64 ts, *tsp, delta, key = 0;

   // attempt to read stored timestamp
   tsp = last.lookup(&key);
   if (tsp != 0) {
       delta = bpf_ktime_get_ns() - *tsp;
       if (delta < 1000000000) {
           // output if time is less than 1 second
           bpf_trace_printk("%d\\n", delta / 1000000);
       }
       last.delete(&key);
   }

   // update stored timestamp
   ts = bpf_ktime_get_ns();
   last.update(&key, &ts);
}
""")

b.attach_kprobe(event="sys_sync", fn_name="do_trace")
print("Tracing for quick sync's... Ctrl-C to end")

# format output
start = 0
while 1:
   (task, pid, cpu, flags, ts, ms) = b.trace_fields()
   if start == 0:
       start = ts
   ts = ts - start
   print("At time %.2f s: multiple syncs detected, last %s ms ago" % (ts, ms))

執行 sync_timing.py ( 另外在新視窗執行 #sync;sync;sync )
# python   /usr/share/bcc/examples/tracing/sync_timing.py
Tracing for quick sync's... Ctrl-C to end
At time 0.00 s: multiple syncs detected, last 177 ms ago
At time 0.16 s: multiple syncs detected, last 161 ms ago
At time 15.44 s: multiple syncs detected, last 1 ms ago
At time 15.44 s: multiple syncs detected, last 1 ms ago
At time 15.44 s: multiple syncs detected, last 1 ms ago


執行另外一個測試
# python   /usr/share/bcc/examples/tracing/disksnoop.py
TIME(s)            T  BYTES    LAT(ms)
4578.806008000     R  8           0.06
4580.853965000     R  8           0.06
4581.622036000     W  6144        0.12


執行另外一個測試
個人覺得這個測試很好用, 可以統計較常用的 block 大小 :)

# python    /usr/share/bcc/examples/tracing/bitehist.py
Tracing... Hit Ctrl-C to end.
^C
    kbytes              : count     distribution
        0 -> 1          : 8        |****************************************|
        2 -> 3          : 1        |*****                                   |
        4 -> 7          : 0        |                                        |
        8 -> 15         : 0        |                                        |
       16 -> 31         : 1        |*****                                   |


# cat   /usr/share/bcc/examples/tracing/bitehist.py

#!/usr/bin/python
#
# bitehist.py Block I/O size histogram.
# For Linux, uses BCC, eBPF. See .c file.
#
# Written as a basic example of using a histogram to show a distribution.
#
# The default interval is 5 seconds. A Ctrl-C will print the partially
# gathered histogram then exit.
#
# Copyright (c) 2015 Brendan Gregg.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 15-Aug-2015 Brendan Gregg Created this.

from bcc import BPF
from time import sleep

# load BPF program
b = BPF(src_file = "bitehist.c")

# header
print("Tracing... Hit Ctrl-C to end.")

# trace until Ctrl-C
try:
sleep(99999999)
except KeyboardInterrupt:
print

# output
b["dist"].print_log2_hist("kbytes")


感謝今天 AL 分享

~ enjoy it

沒有留言: