Commit 9162be45 authored by Marko Myllynen's avatar Marko Myllynen Committed by yonghong-song

Add Perl support for ucalls / uflow / ustat (#1959)

Sort language entries while at it.
parent fe26ca97
.TH ucalls 8 "2016-11-07" "USER COMMANDS"
.SH NAME
ucalls, javacalls, pythoncalls, rubycalls, phpcalls \- Summarize method calls
ucalls, javacalls, perlcalls, phpcalls, pythoncalls, rubycalls \- Summarize method calls
from high-level languages and Linux syscalls.
.SH SYNOPSIS
.B javacalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.br
.B perlcalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.br
.B phpcalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.br
.B pythoncalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.br
.B rubycalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.br
.B phpcalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.br
.B ucalls [-l {java,python,ruby,php}] [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.B ucalls [-l {java,perl,php,python,ruby}] [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.SH DESCRIPTION
This tool summarizes method calls from high-level languages such as Python,
Java, Ruby, and PHP. It can also trace Linux system calls. Whenever a method is
invoked, ucalls records the call count and optionally the method's execution
This tool summarizes method calls from high-level languages such as Java, Perl,
PHP, Python, and Ruby. It can also trace Linux system calls. Whenever a method
is invoked, ucalls records the call count and optionally the method's execution
time (latency) and displays a summary.
This uses in-kernel eBPF maps to store per process summaries for efficiency.
This tool relies on USDT probes embedded in many high-level languages, such as
Java, Python, Ruby, and PHP. It requires a runtime instrumented with these
Java, Perl, PHP, Python, and Ruby. It requires a runtime instrumented with these
probes, which in some cases requires building from source with a USDT-specific
flag, such as "--enable-dtrace" or "--with-dtrace". For Java, method probes are
not enabled by default, and can be turned on by running the Java process with
......@@ -33,7 +35,7 @@ Since this uses BPF, only the root user can use this tool.
CONFIG_BPF and bcc.
.SH OPTIONS
.TP
\-l {java,python,ruby,php}
\-l {java,perl,php,python,ruby}
The language to trace. If not provided, only syscalls are traced (when the \-S
option is used).
.TP
......@@ -73,9 +75,9 @@ Trace only syscalls and print a summary after 10 seconds:
.B ucalls -S 788 10
.SH OVERHEAD
Tracing individual method calls will produce a considerable overhead in all
high-level languages. For languages with just-in-time compilation, such as
Java, the overhead can be more considerable than for interpreted languages.
On the other hand, syscall tracing will typically be tolerable for most
high-level languages. For languages with just-in-time compilation, such as
Java, the overhead can be more considerable than for interpreted languages.
On the other hand, syscall tracing will typically be tolerable for most
processes, unless they have a very unusual rate of system calls.
.SH SOURCE
This is from bcc.
......
.TH uflow 8 "2016-11-07" "USER COMMANDS"
.SH NAME
uflow, javaflow, pythonflow, rubyflow, phpflow \- Print a flow graph of method
uflow, javaflow, perlflow, phpflow, pythonflow, rubyflow \- Print a flow graph of method
calls in high-level languages.
.SH SYNOPSIS
.B javaflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
.br
.B perlflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
.br
.B phpflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
.br
.B pythonflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
.br
.B rubyflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
.br
.B phpflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
.br
.B uflow [-h] [-M METHOD] [-C CLAZZ] [-v] [-l {java,python,ruby,php}] pid
.B uflow [-h] [-M METHOD] [-C CLAZZ] [-v] [-l {java,perl,php,python,ruby}] pid
.SH DESCRIPTION
uflow traces method calls and prints them in a flow graph that can facilitate
debugging and diagnostics by following the program's execution (method flow).
This tool relies on USDT probes embedded in many high-level languages, such as
Java, Python, Ruby, and PHP. It requires a runtime instrumented with these
Java, Perl, PHP, Python, and Ruby. It requires a runtime instrumented with these
probes, which in some cases requires building from source with a USDT-specific
flag, such as "--enable-dtrace" or "--with-dtrace". For Java processes, the
startup flag "-XX:+ExtendedDTraceProbes" is required. For PHP processes, the
......@@ -39,7 +41,7 @@ name interpretation strongly depends on the language. For example, in Java use
\-v
Print the resulting BPF program, for debugging purposes.
.TP
{java,python,ruby,php}
{java,perl,php,python,ruby}
The language to trace.
.TP
pid
......
.TH ustat 8 "2016-11-07" "USER COMMANDS"
.SH NAME
ustat, javastat, pythonstat, rubystat, nodestat, phpstat \- Activity stats from
ustat, javastat, nodestat, perlstat, phpstat, pythonstat, rubystat \- Activity stats from
high-level languages.
.SH SYNOPSIS
.B javastat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.br
.B pythonstat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.br
.B rubystat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.br
.B nodestat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.br
.B perlstat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.br
.B phpstat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.br
.B ustat [-l {java,python,ruby,node,php}] [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.B pythonstat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.br
.B rubystat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.br
.B ustat [-l {java,perl,python,ruby,node,php}] [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.SH DESCRIPTION
This is "top" for high-level language events, such as garbage collections,
exceptions, thread creations, object allocations, method calls, and more. The
events are aggregated for each process and printed in a top-like table, which
can be sorted by various fields.
can be sorted by various fields. Not all language runtimes provide the same
set of details.
This uses in-kernel eBPF maps to store per process summaries for efficiency.
This tool relies on USDT probes embedded in many high-level languages, such as
Node, Java, Python, Ruby, and PHP. It requires a runtime instrumented with these
probes, which in some cases requires building from source with a USDT-specific
flag, such as "--enable-dtrace" or "--with-dtrace". For Java, some probes are
not enabled by default, and can be turned on by running the Java process with
the "-XX:+ExtendedDTraceProbes" flag. For PHP processes, the environment
variable USE_ZEND_DTRACE must be set to 1.
Java, Node, Perl, PHP, Python, and Ruby. It requires a runtime instrumented with
these probes, which in some cases requires building from source with a
USDT-specific flag, such as "--enable-dtrace" or "--with-dtrace". For Java,
some probes are not enabled by default, and can be turned on by running the Java
process with the "-XX:+ExtendedDTraceProbes" flag. For PHP processes, the
environment variable USE_ZEND_DTRACE must be set to 1.
Newly-created processes will only be traced at the next interval. If you run
this tool with a short interval (say, 1-5 seconds), this should be virtually
......@@ -40,7 +43,7 @@ Since this uses BPF, only the root user can use this tool.
CONFIG_BPF and bcc.
.SH OPTIONS
.TP
\-l {java,python,ruby,node,php}
\-l {java,node,perl,php,python,ruby}
The language to trace. By default, all languages are traced.
.TP
\-C
......
......@@ -180,6 +180,15 @@ apps:
opensnoop:
command: wrapper opensnoop
aliases: [opensnoop]
perlcalls:
command: wrapper perlcalls
aliases: [perlcalls]
perlflow:
command: wrapper perlflow
aliases: [perlflow]
perlstat:
command: wrapper perlstat
aliases: [perlstat]
phpcalls:
command: wrapper phpcalls
aliases: [phpcalls]
......
......@@ -406,9 +406,9 @@ void bcc_procutils_free(const char *ptr) {
}
/* Detects the following languages + C. */
const char *languages[] = {"java", "python", "ruby", "php", "node"};
const char *languages[] = {"java", "node", "perl", "php", "python", "ruby"};
const char *language_c = "c";
const int nb_languages = 5;
const int nb_languages = 6;
const char *bcc_procutils_language(int pid) {
char procfilename[24], line[4096], pathname[32], *str;
......
......@@ -15,7 +15,7 @@ class TestUtils(unittest.TestCase):
self.assertEqual(len(online_cpus), num_cores)
def test_detect_language(self):
candidates = ["java", "ruby", "php", "node", "c", "python"]
candidates = ["c", "java", "perl", "php", "node", "ruby", "python"]
language = detect_language(candidates, os.getpid())
self.assertEqual(language, "python")
......
......@@ -4,7 +4,7 @@
# ucalls Summarize method calls in high-level languages and/or system calls.
# For Linux, uses BCC, eBPF.
#
# USAGE: ucalls [-l {java,python,ruby,php}] [-h] [-T TOP] [-L] [-S] [-v] [-m]
# USAGE: ucalls [-l {java,perl,php,python,ruby}] [-h] [-T TOP] [-L] [-S] [-v] [-m]
# pid [interval]
#
# Copyright 2016 Sasha Goldshtein
......@@ -18,7 +18,7 @@ from bcc import BPF, USDT, utils
from time import sleep
import os
languages = ["java", "python", "ruby", "php"]
languages = ["java", "perl", "php", "python", "ruby"]
examples = """examples:
./ucalls -l java 185 # trace Java calls and print statistics on ^C
......@@ -69,6 +69,18 @@ if language == "java":
read_method = "bpf_usdt_readarg(4, ctx, &method);"
extra_message = ("If you do not see any results, make sure you ran java"
" with option -XX:+ExtendedDTraceProbes")
elif language == "perl":
entry_probe = "sub__entry"
return_probe = "sub__return"
read_class = "bpf_usdt_readarg(2, ctx, &clazz);" # filename really
read_method = "bpf_usdt_readarg(1, ctx, &method);"
elif language == "php":
entry_probe = "function__entry"
return_probe = "function__return"
read_class = "bpf_usdt_readarg(4, ctx, &clazz);"
read_method = "bpf_usdt_readarg(1, ctx, &method);"
extra_message = ("If you do not see any results, make sure the environment"
" variable USE_ZEND_DTRACE is set to 1")
elif language == "python":
entry_probe = "function__entry"
return_probe = "function__return"
......@@ -80,13 +92,6 @@ elif language == "ruby":
return_probe = "method__return"
read_class = "bpf_usdt_readarg(1, ctx, &clazz);"
read_method = "bpf_usdt_readarg(2, ctx, &method);"
elif language == "php":
entry_probe = "function__entry"
return_probe = "function__return"
read_class = "bpf_usdt_readarg(4, ctx, &clazz);"
read_method = "bpf_usdt_readarg(1, ctx, &method);"
extra_message = ("If you do not see any results, make sure the environment"
" variable USE_ZEND_DTRACE is set to 1")
elif not language or language == "none":
if not args.syscalls:
print("Nothing to do; use -S to trace syscalls.")
......
......@@ -2,8 +2,9 @@ Demonstrations of ucalls.
ucalls summarizes method calls in various high-level languages, including Java,
Python, Ruby, PHP, and Linux system calls. It displays statistics on the most
frequently called methods, as well as the latency (duration) of these methods.
Perl, PHP, Python, Ruby, and Linux system calls. It displays statistics on the
most frequently called methods, as well as the latency (duration) of these
methods.
Through the syscalls support, ucalls can provide basic information on a
process' interaction with the system including syscall counts and latencies.
......@@ -60,7 +61,7 @@ METHOD # CALLS
USAGE message:
# ./ucalls.py -h
usage: ucalls.py [-h] [-l {java,python,ruby,php,none}] [-T TOP] [-L] [-S] [-v]
usage: ucalls.py [-h] [-l {java,perl,php,python,ruby,none}] [-T TOP] [-L] [-S] [-v]
[-m]
pid [interval]
......@@ -72,7 +73,7 @@ positional arguments:
optional arguments:
-h, --help show this help message and exit
-l {java,python,ruby,php,none}, --language {java,python,ruby,php,none}
-l {java,perl,php,python,ruby,none}, --language {java,perl,php,python,ruby,none}
language to trace (if none, trace syscalls only)
-T TOP, --top TOP number of most frequent/slow calls to print
-L, --latency record method latency from enter to exit (except
......
......@@ -4,7 +4,7 @@
# uflow Trace method execution flow in high-level languages.
# For Linux, uses BCC, eBPF.
#
# USAGE: uflow [-C CLASS] [-M METHOD] [-v] {java,python,ruby,php} pid
# USAGE: uflow [-C CLASS] [-M METHOD] [-v] {java,perl,php,python,ruby} pid
#
# Copyright 2016 Sasha Goldshtein
# Licensed under the Apache License, Version 2.0 (the "License")
......@@ -18,7 +18,7 @@ import ctypes as ct
import time
import os
languages = ["java", "python", "ruby", "php"]
languages = ["java", "perl", "php", "python", "ruby"]
examples = """examples:
./uflow -l java 185 # trace Java method calls in process 185
......@@ -127,6 +127,20 @@ if language == "java":
enable_probe("method__return", "java_return",
"bpf_usdt_readarg(2, ctx, &clazz);",
"bpf_usdt_readarg(4, ctx, &method);", is_return=True)
elif language == "perl":
enable_probe("sub__entry", "perl_entry",
"bpf_usdt_readarg(2, ctx, &clazz);",
"bpf_usdt_readarg(1, ctx, &method);", is_return=False)
enable_probe("sub__return", "perl_return",
"bpf_usdt_readarg(2, ctx, &clazz);",
"bpf_usdt_readarg(1, ctx, &method);", is_return=True)
elif language == "php":
enable_probe("function__entry", "php_entry",
"bpf_usdt_readarg(4, ctx, &clazz);",
"bpf_usdt_readarg(1, ctx, &method);", is_return=False)
enable_probe("function__return", "php_return",
"bpf_usdt_readarg(4, ctx, &clazz);",
"bpf_usdt_readarg(1, ctx, &method);", is_return=True)
elif language == "python":
enable_probe("function__entry", "python_entry",
"bpf_usdt_readarg(1, ctx, &clazz);", # filename really
......@@ -147,13 +161,6 @@ elif language == "ruby":
enable_probe("cmethod__return", "ruby_creturn",
"bpf_usdt_readarg(1, ctx, &clazz);",
"bpf_usdt_readarg(2, ctx, &method);", is_return=True)
elif language == "php":
enable_probe("function__entry", "php_entry",
"bpf_usdt_readarg(4, ctx, &clazz);",
"bpf_usdt_readarg(1, ctx, &method);", is_return=False)
enable_probe("function__return", "php_return",
"bpf_usdt_readarg(4, ctx, &clazz);",
"bpf_usdt_readarg(1, ctx, &method);", is_return=True)
else:
print("No language detected; use -l to trace a language.")
exit(1)
......
......@@ -4,8 +4,8 @@ Demonstrations of uflow.
uflow traces method entry and exit events and prints a visual flow graph that
shows how methods are entered and exited, similar to a tracing debugger with
breakpoints. This can be useful for understanding program flow in high-level
languages such as Java, Python, Ruby, and PHP, which provide USDT probes for
method invocations.
languages such as Java, Perl, PHP, Python, and Ruby, which provide USDT
probes for method invocations.
For example, trace all Ruby method calls in a specific process:
......@@ -88,7 +88,7 @@ thread running on the same CPU.
USAGE message:
# ./uflow -h
usage: uflow.py [-h] [-l {java,python,ruby,php}] [-M METHOD] [-C CLAZZ] [-v]
usage: uflow.py [-h] [-l {java,perl,php,python,ruby}] [-M METHOD] [-C CLAZZ] [-v]
pid
Trace method execution flow in high-level languages.
......@@ -98,7 +98,7 @@ positional arguments:
optional arguments:
-h, --help show this help message and exit
-l {java,python,ruby,php}, --language {java,python,ruby,php}
-l {java,perl,php,python,ruby}, --language {java,perl,php,python,ruby}
language to trace
-M METHOD, --method METHOD
trace only calls to methods starting with this prefix
......
......@@ -5,7 +5,7 @@
# method calls, class loads, garbage collections, and more.
# For Linux, uses BCC, eBPF.
#
# USAGE: ustat [-l {java,python,ruby,node,php}] [-C]
# USAGE: ustat [-l {java,node,perl,php,python,ruby}] [-C]
# [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d]
# [interval [count]]
#
......@@ -132,7 +132,7 @@ class Tool(object):
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=examples)
parser.add_argument("-l", "--language",
choices=["java", "python", "ruby", "node", "php"],
choices=["java", "node", "perl", "php", "python", "ruby"],
help="language to trace (default: all languages)")
parser.add_argument("-C", "--noclear", action="store_true",
help="don't clear the screen")
......@@ -151,18 +151,30 @@ class Tool(object):
def _create_probes(self):
probes_by_lang = {
"java": Probe("java", ["java"], {
"gc__begin": Category.GC,
"mem__pool__gc__begin": Category.GC,
"thread__start": Category.THREAD,
"class__loaded": Category.CLOAD,
"object__alloc": Category.OBJNEW,
"method__entry": Category.METHOD,
"ExceptionOccurred__entry": Category.EXCP
}),
"node": Probe("node", ["node"], {
"gc__start": Category.GC
}),
"python": Probe("python", ["python"], {
"function__entry": Category.METHOD,
"gc__start": Category.GC
"perl": Probe("perl", ["perl"], {
"sub__entry": Category.METHOD
}),
"php": Probe("php", ["php"], {
"function__entry": Category.METHOD,
"compile__file__entry": Category.CLOAD,
"exception__thrown": Category.EXCP
}),
"python": Probe("python", ["python"], {
"function__entry": Category.METHOD,
"gc__start": Category.GC
}),
"ruby": Probe("ruby", ["ruby", "irb"], {
"method__entry": Category.METHOD,
"cmethod__entry": Category.METHOD,
......@@ -176,15 +188,6 @@ class Tool(object):
"load__entry": Category.CLOAD,
"raise": Category.EXCP
}),
"java": Probe("java", ["java"], {
"gc__begin": Category.GC,
"mem__pool__gc__begin": Category.GC,
"thread__start": Category.THREAD,
"class__loaded": Category.CLOAD,
"object__alloc": Category.OBJNEW,
"method__entry": Category.METHOD,
"ExceptionOccurred__entry": Category.EXCP
})
}
if self.args.language:
......
......@@ -4,7 +4,7 @@ Demonstrations of ustat.
ustat is a "top"-like tool for monitoring events in high-level languages. It
prints statistics about garbage collections, method calls, object allocations,
and various other events for every process that it recognizes with a Java,
Python, Ruby, Node, or PHP runtime.
Node, Perl, PHP, Python, and Ruby runtime.
For example:
......@@ -48,7 +48,7 @@ PID CMDLINE METHOD/s GC/s OBJNEW/s CLOAD/s EXC/s THR/s
USAGE message:
# ./ustat.py -h
usage: ustat.py [-h] [-l {java,python,ruby,node,php}] [-C]
usage: ustat.py [-h] [-l {java,node,perl,php,python,ruby}] [-C]
[-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d]
[interval] [count]
......@@ -60,7 +60,7 @@ positional arguments:
optional arguments:
-h, --help show this help message and exit
-l {java,python,ruby,node,php}, --language {java,python,ruby,node,php}
-l {{java,node,perl,php,python,ruby}}, --language {java,node,perl,php,python,ruby}
language to trace (default: all languages)
-C, --noclear don't clear the screen
-S {cload,excp,gc,method,objnew,thread}, --sort {cload,excp,gc,method,objnew,thread}
......
#!/bin/bash
lib=$(dirname $0)/lib
$lib/ucalls.py -l perl "$@"
lib/ucalls_example.txt
\ No newline at end of file
#!/bin/bash
lib=$(dirname $0)/lib
$lib/uflow.py -l perl "$@"
lib/uflow_example.txt
\ No newline at end of file
#!/bin/bash
lib=$(dirname $0)/lib
$lib/ustat.py -l perl "$@"
lib/ustat_example.txt
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment