rbbcc 0.11.6 → 0.11.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/lib/rbbcc/table.rb +8 -7
  4. data/lib/rbbcc/version.rb +1 -1
  5. data/rbbcc.gemspec +5 -2
  6. metadata +2 -62
  7. data/docs/README.md +0 -7
  8. data/docs/answers/01-hello-world.rb +0 -16
  9. data/docs/answers/02-sys_sync.rb +0 -18
  10. data/docs/answers/03-hello_fields.rb +0 -33
  11. data/docs/answers/04-sync_timing.rb +0 -46
  12. data/docs/answers/05-sync_count.rb +0 -54
  13. data/docs/answers/06-disksnoop.rb +0 -71
  14. data/docs/answers/07-hello_perf_output.rb +0 -59
  15. data/docs/answers/08-sync_perf_output.rb +0 -60
  16. data/docs/answers/09-bitehist.rb +0 -32
  17. data/docs/answers/10-disklatency.rb +0 -51
  18. data/docs/answers/11-vfsreadlat.c +0 -46
  19. data/docs/answers/11-vfsreadlat.rb +0 -66
  20. data/docs/answers/12-urandomread.rb +0 -38
  21. data/docs/answers/13-disksnoop_fixed.rb +0 -108
  22. data/docs/answers/14-strlen_count.rb +0 -46
  23. data/docs/answers/15-nodejs_http_server.rb +0 -44
  24. data/docs/answers/16-task_switch.c +0 -23
  25. data/docs/answers/16-task_switch.rb +0 -17
  26. data/docs/answers/node-server.js +0 -11
  27. data/docs/getting_started.md +0 -154
  28. data/docs/projects_using_rbbcc.md +0 -43
  29. data/docs/tutorial_bcc_ruby_developer.md +0 -774
  30. data/docs/tutorial_bcc_ruby_developer_japanese.md +0 -770
  31. data/examples/bitehist.rb +0 -46
  32. data/examples/charty/Gemfile +0 -11
  33. data/examples/charty/Gemfile.lock +0 -48
  34. data/examples/charty/bitehist-unicode.rb +0 -87
  35. data/examples/collectsyscall.rb +0 -182
  36. data/examples/dddos.rb +0 -112
  37. data/examples/disksnoop.rb +0 -73
  38. data/examples/dns_blocker.rb +0 -134
  39. data/examples/example.gif +0 -0
  40. data/examples/extract_arg.rb +0 -26
  41. data/examples/hello_fields.rb +0 -32
  42. data/examples/hello_perf_output.rb +0 -64
  43. data/examples/hello_ring_buffer.rb +0 -64
  44. data/examples/hello_world.rb +0 -6
  45. data/examples/kvm_hypercall.rb +0 -69
  46. data/examples/lsm_sockblock.rb +0 -141
  47. data/examples/mallocstack.rb +0 -63
  48. data/examples/networking/http_filter/http-parse-simple.c +0 -114
  49. data/examples/networking/http_filter/http-parse-simple.rb +0 -85
  50. data/examples/pin_maps_a.rb +0 -88
  51. data/examples/pin_maps_b.rb +0 -71
  52. data/examples/py-orig/sockblock.py +0 -119
  53. data/examples/ringbuf_pin_a.rb +0 -51
  54. data/examples/ringbuf_pin_b.rb +0 -29
  55. data/examples/ruby_usdt.rb +0 -105
  56. data/examples/sbrk_trace.rb +0 -204
  57. data/examples/ssl_http_trace.rb +0 -274
  58. data/examples/syscalluname.rb +0 -39
  59. data/examples/table.rb +0 -15
  60. data/examples/tools/bashreadline.rb +0 -83
  61. data/examples/tools/execsnoop.rb +0 -229
  62. data/examples/tools/runqlat.rb +0 -148
  63. data/examples/urandomread-explicit.rb +0 -58
  64. data/examples/urandomread.rb +0 -39
  65. data/examples/usdt-test.rb +0 -6
  66. data/examples/usdt.rb +0 -26
@@ -1,66 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Original: from vfsreadlat.py
4
- # Copyright (c) 2015 Brendan Gregg.
5
- # Licensed under the Apache License, Version 2.0 (the "License")
6
- # Ruby version follows.
7
- #
8
- # vfsreadlat.rb VFS read latency distribution.
9
- # For Linux, uses BCC, eBPF. See .c file.
10
- #
11
- # Written as a basic example of a function latency distribution histogram.
12
- #
13
- # USAGE: vfsreadlat.rb [interval [count]]
14
- #
15
- # The default interval is 5 seconds. A Ctrl-C will print the partially
16
- # gathered histogram then exit.
17
-
18
- require "rbbcc"
19
- include RbBCC
20
-
21
- def usage
22
- puts("USAGE: %s [interval [count]]" % $0)
23
- exit
24
- end
25
-
26
- # arguments
27
- interval = 5
28
- count = -1
29
- if ARGV.size > 0
30
- begin
31
- interval = ARGV[0].to_i
32
- raise if interval == 0
33
- count = ARGV[1].to_i if ARGV[1]
34
- rescue => e # also catches -h, --help
35
- usage()
36
- end
37
- end
38
-
39
- # load BPF program
40
- b = BCC.new(src_file: "11-vfsreadlat.c")
41
- b.attach_kprobe(event: "vfs_read", fn_name: "do_entry")
42
- b.attach_kretprobe(event: "vfs_read", fn_name: "do_return")
43
-
44
- # header
45
- print("Tracing... Hit Ctrl-C to end.")
46
-
47
- # output
48
- cycle = 0
49
- do_exit = false
50
- loop do
51
- if count > 0
52
- cycle += 1
53
- exit if cycle > count
54
- end
55
-
56
- begin
57
- sleep(interval)
58
- rescue Interrupt
59
- do_exit = true
60
- end
61
-
62
- puts
63
- b["dist"].print_log2_hist("usecs")
64
- b["dist"].clear
65
- exit if do_exit
66
- end
@@ -1,38 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # urandomread.rb Example of instrumenting a kernel tracepoint.
4
- # For Linux, uses BCC, BPF. Embedded C.
5
- #
6
- # REQUIRES: Linux 4.7+ (BPF_PROG_TYPE_TRACEPOINT support).
7
- #
8
- # Test by running this, then in another shell, run:
9
- # dd if=/dev/urandom of=/dev/null bs=1k count=5
10
- #
11
- # Original urandomread.py Copyright 2016 Netflix, Inc.
12
- # Licensed under the Apache License, Version 2.0 (the "License")
13
- # Ruby version follows.
14
-
15
- require 'rbbcc'
16
- include RbBCC
17
-
18
- b = BCC.new(text: <<BPF)
19
- TRACEPOINT_PROBE(random, urandom_read) {
20
- // args is from /sys/kernel/debug/tracing/events/random/urandom_read/format
21
- bpf_trace_printk("%d\\n", args->got_bits);
22
- return 0;
23
- }
24
- BPF
25
-
26
- # header
27
- puts("%-18s %-16s %-6s %s" % ["TIME(s)", "COMM", "PID", "GOTBITS"])
28
-
29
- # format output
30
- loop do
31
- begin
32
- b.trace_fields do |task, pid, cpu, flags, ts, msg|
33
- puts("%-18.9f %-16s %-6d %s" % [ts, task, pid, msg])
34
- end
35
- rescue Interrupt
36
- exit
37
- end
38
- end
@@ -1,108 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # disksnoop_fixed.rb Trace block device I/O: basic version of iosnoop.
4
- # For Linux, uses BCC, eBPF. Embedded C.
5
- # This is ported from original disksnoop.py
6
- #
7
- # Written as a basic example of tracing latency.
8
- #
9
- # Licensed under the Apache License, Version 2.0 (the "License")
10
- #
11
- # 11-Aug-2015 Brendan Gregg Created disksnoop.py
12
-
13
- =begin
14
- name: block_rq_issue
15
- ID: 1093
16
- format:
17
- field:unsigned short common_type; offset:0; size:2; signed:0;
18
- field:unsigned char common_flags; offset:2; size:1; signed:0;
19
- field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
20
- field:int common_pid; offset:4; size:4; signed:1;
21
-
22
- field:dev_t dev; offset:8; size:4; signed:0;
23
- field:sector_t sector; offset:16; size:8; signed:0;
24
- field:unsigned int nr_sector; offset:24; size:4; signed:0;
25
- field:unsigned int bytes; offset:28; size:4; signed:0;
26
- field:char rwbs[8]; offset:32; size:8; signed:1;
27
- field:char comm[16]; offset:40; size:16; signed:1;
28
- field:__data_loc char[] cmd; offset:56; size:4; signed:1;
29
-
30
- print fmt: "%d,%d %s %u (%s) %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, REC->bytes, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->comm
31
-
32
- name: block_rq_complete
33
- ID: 1095
34
- format:
35
- field:unsigned short common_type; offset:0; size:2; signed:0;
36
- field:unsigned char common_flags; offset:2; size:1; signed:0;
37
- field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
38
- field:int common_pid; offset:4; size:4; signed:1;
39
-
40
- field:dev_t dev; offset:8; size:4; signed:0;
41
- field:sector_t sector; offset:16; size:8; signed:0;
42
- field:unsigned int nr_sector; offset:24; size:4; signed:0;
43
- field:int error; offset:28; size:4; signed:1;
44
- field:char rwbs[8]; offset:32; size:8; signed:1;
45
- field:__data_loc char[] cmd; offset:40; size:4; signed:1;
46
-
47
- print fmt: "%d,%d %s (%s) %llu + %u [%d]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->error
48
-
49
- in kernel 5.0.
50
- This implementation shows the count of sector.
51
- =end
52
-
53
- require 'rbbcc'
54
- include RbBCC
55
-
56
- # load BPF program
57
- b = BCC.new(text: <<CLANG)
58
- #include <uapi/linux/ptrace.h>
59
- #include <linux/blkdev.h>
60
-
61
- BPF_HASH(start, u32);
62
-
63
- TRACEPOINT_PROBE(block, block_rq_issue) {
64
- // stash start timestamp by request ptr
65
- u64 ts = bpf_ktime_get_ns();
66
- u32 tid = bpf_get_current_pid_tgid();
67
-
68
- start.update(&tid, &ts);
69
- return 0;
70
- }
71
-
72
- TRACEPOINT_PROBE(block, block_rq_complete) {
73
- u64 *tsp, delta;
74
- u32 tid = bpf_get_current_pid_tgid();
75
-
76
- tsp = start.lookup(&tid);
77
- if (tsp != 0) {
78
- char dst[8];
79
- int i;
80
- delta = bpf_ktime_get_ns() - *tsp;
81
- if (bpf_probe_read_str(dst, sizeof(dst), args->rwbs) < 0) {
82
- dst[0] = '?';
83
- for(i = 1; i < sizeof(dst); ++i)
84
- dst[i] = 0;
85
- }
86
- bpf_trace_printk("%d %s %d\\n", args->nr_sector,
87
- dst, delta / 1000);
88
- start.delete(&tid);
89
- }
90
- return 0;
91
- }
92
- CLANG
93
-
94
- # header
95
- puts("%-18s %-8s %-7s %8s" % ["TIME(s)", "RWBS", "SECTORS", "LAT(ms)"])
96
-
97
- # format output
98
- loop do
99
- begin
100
- task, pid, cpu, flags, ts, msg = b.trace_fields
101
- sector_s, rwbs, us_s = msg.split
102
- ms = us_s.to_i.to_f / 1000
103
-
104
- puts("%-18.9f %-8s %-7s %8.2f" % [ts, rwbs, sector_s, ms])
105
- rescue Interrupt
106
- exit
107
- end
108
- end
@@ -1,46 +0,0 @@
1
- require 'rbbcc'
2
- include RbBCC
3
-
4
- # load BPF program
5
- b = BCC.new(text: <<BPF)
6
- #include <uapi/linux/ptrace.h>
7
-
8
- struct key_t {
9
- char c[80];
10
- };
11
- BPF_HASH(counts, struct key_t);
12
-
13
- int count(struct pt_regs *ctx) {
14
- if (!PT_REGS_PARM1(ctx))
15
- return 0;
16
-
17
- struct key_t key = {};
18
- u64 zero = 0, *val;
19
-
20
- bpf_probe_read(&key.c, sizeof(key.c), (void *)PT_REGS_PARM1(ctx));
21
- // could also use `counts.increment(key)`
22
- val = counts.lookup_or_try_init(&key, &zero);
23
- if (val) {
24
- (*val)++;
25
- }
26
- return 0;
27
- };
28
- BPF
29
- b.attach_uprobe(name: "c", sym: "strlen", fn_name: "count")
30
-
31
- # header
32
- print("Tracing strlen()... Hit Ctrl-C to end.")
33
-
34
- # sleep until Ctrl-C
35
- begin
36
- sleep(99999999)
37
- rescue Interrupt
38
- puts
39
- end
40
-
41
- # print output
42
- puts("%10s %s" % ["COUNT", "STRING"])
43
- counts = b.get_table("counts")
44
- counts.items.sort_by{|k, v| v.to_bcc_value }.each do |k, v|
45
- puts("%10d %s" % [v.to_bcc_value, k.to_bcc_value.c])
46
- end
@@ -1,44 +0,0 @@
1
- require 'rbbcc'
2
- include RbBCC
3
-
4
- if ARGV.size != 1
5
- print("USAGE: #{$0} PID")
6
- exit()
7
- end
8
- pid = ARGV[0]
9
- debug = !!ENV['DEBUG']
10
-
11
- # load BPF program
12
- bpf_text = <<BPF
13
- #include <uapi/linux/ptrace.h>
14
- int do_trace(struct pt_regs *ctx) {
15
- uint64_t addr;
16
- char path[128]={0};
17
- bpf_usdt_readarg(6, ctx, &addr);
18
- bpf_probe_read(&path, sizeof(path), (void *)addr);
19
- bpf_trace_printk("path:%s\\n", path);
20
- return 0;
21
- };
22
- BPF
23
-
24
- # enable USDT probe from given PID
25
- u = USDT.new(pid: pid.to_i)
26
- u.enable_probe(probe: "http__server__request", fn_name: "do_trace")
27
- if debug
28
- puts(u.get_text)
29
- puts(bpf_text)
30
- end
31
-
32
- # initialize BPF
33
- b = BCC.new(text: bpf_text, usdt_contexts: [u])
34
-
35
- puts("%-18s %-16s %-6s %s" % ["TIME(s)", "COMM", "PID", "ARGS"])
36
- loop do
37
- begin
38
- b.trace_fields do |task, pid, cpu, flags, ts, msg|
39
- puts("%-18.9f %-16s %-6d %s" % [ts, task, pid, msg])
40
- end
41
- rescue Interrupt
42
- exit
43
- end
44
- end
@@ -1,23 +0,0 @@
1
- #include <uapi/linux/ptrace.h>
2
- #include <linux/sched.h>
3
-
4
- struct key_t {
5
- u32 prev_pid;
6
- u32 curr_pid;
7
- };
8
-
9
- BPF_HASH(stats, struct key_t, u64, 1024);
10
- int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
11
- struct key_t key = {};
12
- u64 zero = 0, *val;
13
-
14
- key.curr_pid = bpf_get_current_pid_tgid();
15
- key.prev_pid = prev->pid;
16
-
17
- // could also use `stats.increment(key);`
18
- val = stats.lookup_or_try_init(&key, &zero);
19
- if (val) {
20
- (*val)++;
21
- }
22
- return 0;
23
- }
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # Original task_switch.rb Copyright (c) PLUMgrid, Inc.
3
- # Licensed under the Apache License, Version 2.0 (the "License")
4
-
5
- require 'rbbcc'
6
- include RbBCC
7
-
8
- b = BCC.new(src_file: "16-task_switch.c")
9
- b.attach_kprobe(event: "finish_task_switch", fn_name: "count_sched")
10
-
11
- # generate many schedule events
12
- 100.times { sleep 0.01 }
13
-
14
- b["stats"].each do |_k, v|
15
- k = _k[0, 8].unpack("i! i!") # Handling pointer without type!!
16
- puts("task_switch[%5d->%5d]=%u" % [k[0], k[1], v.to_bcc_value])
17
- end
@@ -1,11 +0,0 @@
1
- var http = require("http");
2
-
3
- var server = http.createServer(function (req, res) {
4
- res.writeHead(200, {"Content-Type": "text/plain"});
5
- res.end("Sample node.js server, returns contents in any path.\n");
6
- });
7
-
8
- var port = process.env.PORT || 8081;
9
- server.listen(port, function() {
10
- console.log("Do curl http://localhost:" + port);
11
- });
@@ -1,154 +0,0 @@
1
- # Getting Started
2
-
3
- RbBCC is a project to utilize the power of eBPF/BCC from Ruby.
4
-
5
- ## Setup
6
-
7
- RbBCC requires `libbcc.so` version **0.11.0 or 0.10.0**(we plan to support newer version of libbcc, such as 0.12.0; but it may be done after rbbcc 1.0...).
8
-
9
- BTW we do not need to install header files, becuase current version of RbBCC uses the functionality of libbcc via ffi(We use MRI's standard library **fiddle**, not external gems).
10
-
11
- We can install this shared library via package `libbcc` from official iovisor project repo:
12
-
13
- ```console
14
- # e.g. In Ubuntu:
15
- $ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD
16
- $ echo "deb https://repo.iovisor.org/apt/$(lsb_release -cs) $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/iovisor.list
17
- $ sudo apt-get update
18
- $ sudo apt-get install libbcc
19
- ```
20
-
21
- For more imformation, see [bcc's official doc](https://github.com/iovisor/bcc/blob/master/INSTALL.md).
22
-
23
- After installed libbcc, you can create project hierarchy like:
24
-
25
- ```
26
- .
27
- ├── Gemfile
28
- └── tools
29
- └── hello_world.rb
30
- ```
31
-
32
- with `Gemfile` below:
33
-
34
- ```ruby
35
- source "https://rubygems.org"
36
-
37
- gem "rbbcc"
38
- ```
39
-
40
- Then run `bundle install`.
41
-
42
- ### With docker
43
-
44
- _TBD_
45
-
46
- ## Hello world from Linux kernel!
47
-
48
- Creating `tools/hello_world.rb` as:
49
-
50
- ```ruby
51
- #!/usr/bin/env ruby
52
-
53
- require 'rbbcc'
54
- include RbBCC
55
-
56
- text = <<CLANG
57
- int kprobe__sys_clone(void *ctx)
58
- {
59
- bpf_trace_printk("Hello, World!\\n");
60
- return 0;
61
- }
62
- CLANG
63
-
64
- b = BCC.new(text: text)
65
- printf("%-18s %-16s %-6s %s\n", "TIME(s)", "COMM", "PID", "value")
66
-
67
- b.trace_fields do |task, pid, cpu, flags, ts, msg|
68
- printf("%-18.9f %-16s %-6d %s", ts, task, pid, msg)
69
- end
70
- ```
71
-
72
- Then invoke this Ruby script. BCC requires to run as a priveleged user.
73
-
74
- ```console
75
- $ sudo bundle exec ruby tools/hello_world.rb
76
- Found fnc: kprobe__sys_clone
77
- Attach: p___x64_sys_clone
78
- TIME(s) COMM PID value
79
- ```
80
-
81
- Open another terminal and hit commands, like `curl https://www.ruby-lang.org/`.
82
-
83
- Then RbBCC process displays what kind of program invokes another program with message `Hello, World`.
84
-
85
- ```console
86
- TIME(s) COMM PID value
87
- 109979.625639000 bash 7591 Hello, World!
88
- 109979.632267000 curl 29098 Hello, World!
89
- 109981.467914000 bash 7591 Hello, World!
90
- 109981.474290000 curl 29100 Hello, World!
91
- 109984.913358000 bash 7591 Hello, World!
92
- 109984.921165000 curl 29102 Hello, World!
93
- ...
94
- ```
95
-
96
- These lines are displayed by a kernel hook of `clone(2)(internally: sys_clone)` call. The bash command like `curl, grep, ping...` internally call `sys_clone` to fork new processes, and RbBCC traces these kernel calls with a very small cost.
97
-
98
- Then, change the Ruby(and internal C) codes into this like:
99
-
100
- ```ruby
101
- #!/usr/bin/env ruby
102
-
103
- require 'rbbcc'
104
- include RbBCC
105
-
106
- text = <<CLANG
107
- #include <uapi/linux/ptrace.h>
108
-
109
- int printret(struct pt_regs *ctx) {
110
- char str[80] = {};
111
- u32 pid;
112
- if (!PT_REGS_RC(ctx))
113
- return 0;
114
- pid = bpf_get_current_pid_tgid();
115
- bpf_probe_read(&str, sizeof(str), (void *)PT_REGS_RC(ctx));
116
- bpf_trace_printk("[%d]input: %s\\n", pid, str);
117
-
118
- return 0;
119
- };
120
- CLANG
121
-
122
- b = BCC.new(text: text)
123
- b.attach_uretprobe(name: "/bin/bash", sym: "readline", fn_name: "printret")
124
-
125
- printf("%-18s %-16s %s\n", "TIME(s)", "COMM", "value")
126
- b.trace_fields do |task, pid, cpu, flags, ts, msg|
127
- printf("%-18.9f %-16s %s", ts, task, msg)
128
- end
129
- ```
130
-
131
- Run again:
132
-
133
- ```console
134
- $ sudo bundle exec ruby tools/hello_world.rb
135
- Found fnc: printret
136
- Attach: p__bin_bash_0xad900
137
- TIME(s) COMM value
138
- ```
139
-
140
- And open another "bash" terminal again. When you hit a command to this bash in any session, any input strings are snooped and shown in the tracing process. This is all of the trace result of return in `readline()` function from user program "bash". RbBCC can detect where and how it occurs.
141
-
142
- ```console
143
- TIME(s) COMM value
144
- 1554.284390000 bash [5457]input: curl localhost
145
- 1559.425699000 bash [5457]input: ping 8.8.8.8
146
- 1565.805870000 bash [5457]input: sudo cat /etc/passwd
147
- ...
148
- ```
149
-
150
- ----
151
-
152
- For more use case and information. Please see [`examples`](../examples/) directory and (especially for C API) BCC's official document.
153
-
154
- * [bcc Reference Guide](https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md)
@@ -1,43 +0,0 @@
1
- # Projects Using RbBCC
2
-
3
- ## bpfql
4
-
5
- [bpfql](https://github.com/udzura/bpfql) is a tool to run an eBPF tracing query, using YAML or Ruby DSL.
6
-
7
- ```ruby
8
- BPFQL do
9
- select "*"
10
- from "tracepoint:random:urandom_read"
11
- where "comm", is: "ruby"
12
- end
13
- ```
14
-
15
- ```console
16
- $ sudo bundle exec bpfql examples/random.rb
17
- Found fnc: tracepoint__random__urandom_read
18
- Attach: random:urandom_read
19
- TS COMM PID GOT_BITS POOL_LEFT INPUT_LEFT
20
- 0.000000000 ruby 32485 128 0 2451
21
- 0.002465663 ruby 32485 128 0 2451
22
- ^CExiting bpfql...
23
- ```
24
-
25
- See [its repo](https://github.com/udzura/bpfql) for more details.
26
-
27
- ## rack-ebpf and rack application tracing
28
-
29
- [rack-ebpf](https://github.com/udzura/rack-ebpf) is a rack middleware that invoke USDT probes every time start/end the requests.
30
-
31
- Combine this rack middleware and `rack-ebpf-run` command, we can trace and analyze system stats per request.
32
-
33
- e.g.
34
-
35
- * Count of syscall invocations(like read, write) per request
36
- * Consumed time for syscall ops(like read, write) per request
37
- * Created Ruby objects per request, using Ruby itself's USDT (this requires ruby itself as `--enable-dtrace` build)
38
-
39
- For detailed usage, see [rack-ebpf's repo](https://github.com/udzura/rack-ebpf)
40
-
41
- ----
42
-
43
- Also we're going to prepare some BCC tools made with Ruby. TBA!