Commit b03d9eb2 authored by Brendan Gregg's avatar Brendan Gregg Committed by Brenden Blanco

funccount: add -d for duration

parent 75e2f379
...@@ -27,6 +27,9 @@ Trace this process ID only. ...@@ -27,6 +27,9 @@ Trace this process ID only.
\-i INTERVAL \-i INTERVAL
Print output every interval seconds. Print output every interval seconds.
.TP .TP
\-d DURATION
Total duration of trace in seconds.
.TP
\-T \-T
Include timestamps on output. Include timestamps on output.
.TP .TP
...@@ -49,6 +52,10 @@ Print kernel functions beginning with "vfs_", every second: ...@@ -49,6 +52,10 @@ Print kernel functions beginning with "vfs_", every second:
# #
.B funccount \-i 1 'vfs_*' .B funccount \-i 1 'vfs_*'
.TP .TP
Print kernel functions beginning with "vfs_", for ten seconds only:
#
.B funccount \-d 10 'vfs_*'
.TP
Match kernel functions beginning with "vfs_", using regular expressions: Match kernel functions beginning with "vfs_", using regular expressions:
# #
.B funccount \-r '^vfs_.*' .B funccount \-r '^vfs_.*'
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# funccount Count functions, tracepoints, and USDT probes. # funccount Count functions, tracepoints, and USDT probes.
# For Linux, uses BCC, eBPF. # For Linux, uses BCC, eBPF.
# #
# USAGE: funccount [-h] [-p PID] [-i INTERVAL] [-T] [-r] pattern # USAGE: funccount [-h] [-p PID] [-i INTERVAL] [-d DURATION] [-T] [-r] pattern
# #
# The pattern is a string with optional '*' wildcards, similar to file # The pattern is a string with optional '*' wildcards, similar to file
# globbing. If you'd prefer to use regular expressions, use the -r option. # globbing. If you'd prefer to use regular expressions, use the -r option.
...@@ -218,6 +218,7 @@ class Tool(object): ...@@ -218,6 +218,7 @@ class Tool(object):
./funccount 'vfs_*' # count kernel fns starting with "vfs" ./funccount 'vfs_*' # count kernel fns starting with "vfs"
./funccount -r '^vfs.*' # same as above, using regular expressions ./funccount -r '^vfs.*' # same as above, using regular expressions
./funccount -Ti 5 'vfs_*' # output every 5 seconds, with timestamps ./funccount -Ti 5 'vfs_*' # output every 5 seconds, with timestamps
./funccount -d 10 'vfs_*' # trace for 10 seconds only
./funccount -p 185 'vfs_*' # count vfs calls for PID 181 only ./funccount -p 185 'vfs_*' # count vfs calls for PID 181 only
./funccount t:sched:sched_fork # count calls to the sched_fork tracepoint ./funccount t:sched:sched_fork # count calls to the sched_fork tracepoint
./funccount -p 185 u:node:gc* # count all GC USDT probes in node, PID 185 ./funccount -p 185 u:node:gc* # count all GC USDT probes in node, PID 185
...@@ -232,13 +233,15 @@ class Tool(object): ...@@ -232,13 +233,15 @@ class Tool(object):
epilog=examples) epilog=examples)
parser.add_argument("-p", "--pid", type=int, parser.add_argument("-p", "--pid", type=int,
help="trace this PID only") help="trace this PID only")
parser.add_argument("-i", "--interval", default=99999999, parser.add_argument("-i", "--interval",
help="summary interval, seconds") help="summary interval, seconds")
parser.add_argument("-d", "--duration",
help="total duration of trace, seconds")
parser.add_argument("-T", "--timestamp", action="store_true", parser.add_argument("-T", "--timestamp", action="store_true",
help="include timestamp on output") help="include timestamp on output")
parser.add_argument("-r", "--regexp", action="store_true", parser.add_argument("-r", "--regexp", action="store_true",
help="use regular expressions. Default is \"*\" wildcards only.") help="use regular expressions. Default is \"*\" wildcards only.")
parser.add_argument("-d", "--debug", action="store_true", parser.add_argument("-D", "--debug", action="store_true",
help="print BPF program before starting (for debugging purposes)") help="print BPF program before starting (for debugging purposes)")
parser.add_argument("pattern", parser.add_argument("pattern",
help="search expression for events") help="search expression for events")
...@@ -246,6 +249,10 @@ class Tool(object): ...@@ -246,6 +249,10 @@ class Tool(object):
global debug global debug
debug = self.args.debug debug = self.args.debug
self.probe = Probe(self.args.pattern, self.args.regexp, self.args.pid) self.probe = Probe(self.args.pattern, self.args.regexp, self.args.pid)
if self.args.duration and not self.args.interval:
self.args.interval = self.args.duration
if not self.args.interval:
self.args.interval = 99999999
@staticmethod @staticmethod
def _signal_ignore(signal, frame): def _signal_ignore(signal, frame):
...@@ -257,13 +264,17 @@ class Tool(object): ...@@ -257,13 +264,17 @@ class Tool(object):
print("Tracing %d functions for \"%s\"... Hit Ctrl-C to end." % print("Tracing %d functions for \"%s\"... Hit Ctrl-C to end." %
(self.probe.matched, self.args.pattern)) (self.probe.matched, self.args.pattern))
exiting = 0 if self.args.interval else 1 exiting = 0 if self.args.interval else 1
seconds = 0
while True: while True:
try: try:
sleep(int(self.args.interval)) sleep(int(self.args.interval))
seconds += int(self.args.interval)
except KeyboardInterrupt: except KeyboardInterrupt:
exiting = 1 exiting = 1
# as cleanup can take many seconds, trap Ctrl-C: # as cleanup can take many seconds, trap Ctrl-C:
signal.signal(signal.SIGINT, Tool._signal_ignore) signal.signal(signal.SIGINT, Tool._signal_ignore)
if self.args.duration and seconds >= int(self.args.duration):
exiting = 1
print() print()
if self.args.timestamp: if self.args.timestamp:
......
...@@ -266,6 +266,41 @@ kernel activity that aren't visible in other metrics. ...@@ -266,6 +266,41 @@ kernel activity that aren't visible in other metrics.
Include -T to print timestamps on output. Include -T to print timestamps on output.
A maximum duration can be set. For example, to print 5 x 1 second summaries
of vfs_read() calls:
# ./funccount -i 1 -d 5 vfs_read
Tracing 1 functions for "vfs_read"... Hit Ctrl-C to end.
FUNC COUNT
vfs_read 30
FUNC COUNT
vfs_read 26
FUNC COUNT
vfs_read 54
FUNC COUNT
vfs_read 25
FUNC COUNT
vfs_read 31
Detaching...
By leaving off the "-i 1", this will print a single 5 second summary:
# funccount.py -d 5 vfs_read
Tracing 1 functions for "vfs_read"... Hit Ctrl-C to end.
FUNC COUNT
vfs_read 167
Detaching...
This can be useful for finding out rates: trace all functions for ten seconds
and then divide by ten for the per-second rate.
The "*" wildcard can be used multiple times. Eg, matching functions that contain The "*" wildcard can be used multiple times. Eg, matching functions that contain
the word "readdir": the word "readdir":
...@@ -293,8 +328,9 @@ Detaching... ...@@ -293,8 +328,9 @@ Detaching...
Full USAGE: Full USAGE:
# ./funccount -h # ./funccount -h
usage: funccount.py [-h] [-p PID] [-i INTERVAL] [-T] [-r] [-d] pattern usage: funccount [-h] [-p PID] [-i INTERVAL] [-d DURATION] [-T] [-r] [-D]
pattern
Count functions, tracepoints, and USDT probes Count functions, tracepoints, and USDT probes
...@@ -306,16 +342,19 @@ optional arguments: ...@@ -306,16 +342,19 @@ optional arguments:
-p PID, --pid PID trace this PID only -p PID, --pid PID trace this PID only
-i INTERVAL, --interval INTERVAL -i INTERVAL, --interval INTERVAL
summary interval, seconds summary interval, seconds
-d DURATION, --duration DURATION
total duration of trace, seconds
-T, --timestamp include timestamp on output -T, --timestamp include timestamp on output
-r, --regexp use regular expressions. Default is "*" wildcards -r, --regexp use regular expressions. Default is "*" wildcards
only. only.
-d, --debug print BPF program before starting (for debugging -D, --debug print BPF program before starting (for debugging
purposes) purposes)
examples: examples:
./funccount 'vfs_*' # count kernel fns starting with "vfs" ./funccount 'vfs_*' # count kernel fns starting with "vfs"
./funccount -r '^vfs.*' # same as above, using regular expressions ./funccount -r '^vfs.*' # same as above, using regular expressions
./funccount -Ti 5 'vfs_*' # output every 5 seconds, with timestamps ./funccount -Ti 5 'vfs_*' # output every 5 seconds, with timestamps
./funccount -d 10 'vfs_*' # trace for 10 seconds only
./funccount -p 185 'vfs_*' # count vfs calls for PID 181 only ./funccount -p 185 'vfs_*' # count vfs calls for PID 181 only
./funccount t:sched:sched_fork # count calls to the sched_fork tracepoint ./funccount t:sched:sched_fork # count calls to the sched_fork tracepoint
./funccount -p 185 u:node:gc* # count all GC USDT probes in node, PID 185 ./funccount -p 185 u:node:gc* # count all GC USDT probes in node, PID 185
......
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