diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-08-07 16:47:18 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-08-07 16:47:18 -0400 |
commit | 384c5fe974abe35ab11dce4446dc5eed86585a3b (patch) | |
tree | 9bbdc8206d4a9c08866dc2251e40f4f7249696d4 /testsuite/systemtap.examples/network/socktop | |
parent | 9b3f22a9b83c4fd5e66874d78f4d35ad742ff802 (diff) | |
download | systemtap-steved-384c5fe974abe35ab11dce4446dc5eed86585a3b.tar.gz systemtap-steved-384c5fe974abe35ab11dce4446dc5eed86585a3b.tar.xz systemtap-steved-384c5fe974abe35ab11dce4446dc5eed86585a3b.zip |
samples: separate into subdirectories by subsystem
Diffstat (limited to 'testsuite/systemtap.examples/network/socktop')
-rwxr-xr-x | testsuite/systemtap.examples/network/socktop | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/testsuite/systemtap.examples/network/socktop b/testsuite/systemtap.examples/network/socktop new file mode 100755 index 00000000..123e37e9 --- /dev/null +++ b/testsuite/systemtap.examples/network/socktop @@ -0,0 +1,318 @@ +#!/bin/bash + +# Socktop systemtap script +# Copyright (C) 2006 IBM Corp. +# +# This file is part of systemtap, and is free software. You can +# redistribute it and/or modify it under the terms of the GNU General +# Public License (GPL); either version 2, or (at your option) any +# later version. + +### +### socktop - Combination shell/systemtap script to track reads and writes +### on sockets by process. Can be filtered by process IDs and +### names, protocols, protocol families, users and socket type. +### + +# Filter options +F_PROTSTR=""; F_PROT=0 # Filter by protocol +F_FAMSTR=""; F_FAM=0 # Filter by protocol family +F_TYPESTR=""; F_TYPE=0 # Filter by socket type +F_PIDSTR=""; F_PID=0 # Filter by process ID +F_NAMESTR=""; F_NAME=0 # Filter by process name +F_UIDSTR=""; F_UID=0 # Filter by user +FILTER=0 # Any filters specified? + +# Print options +P_INTERVAL=5 # default interval between output +P_DEVICES=0 # default is don't display network device traffic +P_NUMTOP=10 # default number of processes and network devices to print + +DELIM="," + +function usage { + echo "USAGE: socktop [-d] [-i interval] [-N num] [-P protocol]... [-f family]..." + echo " [-t stype]... [-n pname]... [-p pid]... [-u username]... [-h]" + echo " -d # print network device traffic (default: off)" + echo " -i interval # interval in seconds between printing (default: $P_INTERVAL)" + echo " -N num # number of top processes and devices to print (default: $P_NUMTOP)" + echo " -f family # this protocol family only (default: all)" + echo " -P protocol # this protocol only (default: all)" + echo " -t stype # this socket type only (default: all)" + echo " -n pname # this process name only (default: all)" + echo " -p pid # this process ID only (default: all)" + echo " -u username # this user only (default: all)" + echo " -h # print this help text" + echo "" + echo "Protocol Families:" + echo " LOCAL, INET, INET6, IPX, NETLINK, X25, AX25, ATMPVC, APPLETALK, PACKET" + echo "" + echo "Protocols:" + echo " TCP, UDP, SCTP, IP, FC, ... (see /etc/protocols for complete list)" + echo "" + echo "Socket Types:" + echo " STREAM, DGRAM, RAW, RDM, SEQPACKET, DCCP, PACKET" +} + +# Process options +while getopts df:i:n:N:P:p:t:u:h option; do + case $option in + d) P_DEVICES=1 ;; + i) P_INTERVAL=$OPTARG ;; + N) P_NUMTOP=$OPTARG ;; + f) let "F_FAM++" + F_FAMSTR=$OPTARG$DELIM$F_FAMSTR ;; + n) let "F_NAME++" + F_NAMESTR=$OPTARG$DELIM$F_NAMESTR ;; + p) let "F_PID++" + F_PIDSTR=$OPTARG$DELIM$F_PIDSTR ;; + P) let "F_PROT++" + F_PROTSTR=$OPTARG$DELIM$F_PROTSTR ;; + t) let "F_TYPE++" + F_TYPESTR=$OPTARG$DELIM$F_TYPESTR ;; + u) uid=`awk -F: '$1 == name {print $3}' name=$OPTARG /etc/passwd` + if [[ $uid != "" ]]; then + let "F_UID++" + F_UIDSTR=$uid$DELIM$F_UIDSTR + else + echo "ERROR: Unknown user:" $OPTARG + let "ERROR++" + fi ;; + h|?|*) usage + exit 1 ;; + esac +done + +if [[ $ERROR > 0 ]]; then + exit 1 +fi + +if [[ $F_FAM > 0 || $F_NAME > 0 || $F_PID > 0 || + $F_PROT > 0 || $F_TYPE > 0 || $F_UID > 0 ]]; then + FILTER=1 +fi + +# +# Pass a timezone adjustment value to the stap script +# +TZ=`date "+%z"` +TZ_SIGN=`echo $TZ | cut -c1` +TZ_HOURS=`echo $TZ | cut -c2-3` +TZ_MINS=`echo $TZ | cut -c4-5` +TZ_ADJUST=$TZ_SIGN$((10#$TZ_HOURS*60*60+10#$TZ_MINS*60)) + +# +# Start the systemtap script +# +stap -e ' +global execname, user, if_tx, if_rx, if_dev +global sk_tx, sk_rx, sk_pid +global f_name_str, f_pid_str, f_prot_str, f_fam_str, f_type_str, f_uid_str +global f_name, f_pid, f_prot, f_fam, f_type, f_uid + +probe begin +{ + # If no filters specified, skip filter processing + if ('$FILTER' == 0) next + + f_name_str = "'$F_NAMESTR'" + f_pid_str = "'$F_PIDSTR'" + f_prot_str = "'$F_PROTSTR'" + f_fam_str = "'$F_FAMSTR'" + f_type_str = "'$F_TYPESTR'" + f_uid_str = "'$F_UIDSTR'" + + delim = "'$DELIM'" + error = 0 + + # Protocols + if ('$F_PROT') { + prot = tokenize(f_prot_str, delim) + while (prot != "") { + p = sock_prot_str2num(prot) + if (p < 0) { + printf("ERROR: Unknown protocol: %s\n", prot) + error++ + } else + f_prot[p] = 1 + prot = tokenize("", delim) + } + } + + # Protocol families + if ('$F_FAM') { + fam = tokenize(f_fam_str, delim) + while (fam != "") { + f = sock_fam_str2num(fam) + if (f < 0) { + printf("ERROR: Unknown protocol family: %s\n", fam) + error++ + } else + f_fam[f] = 1 + fam = tokenize("", delim) + } + } + + # Process names + if ('$F_NAME') { + pname = tokenize(f_name_str, delim) + while (pname != "") { + f_name[pname] = 1 + pname = tokenize("", delim) + } + } + + # Process IDs + if ('$F_PID') { + pid = tokenize(f_pid_str, delim) + while (pid != "") { + f_pid[strtol(pid, 10)] = 1 + pid = tokenize("", delim) + } + } + + # Socket types + if ('$F_TYPE') { + stype = tokenize(f_type_str, delim) + while (stype != "") { + t = sock_type_str2num(stype) + if (t < 0) { + printf("ERROR: Unknown socket type: %s\n", stype) + error++ + } else + f_type[t] = 1 + stype = tokenize("", delim) + } + } + + # User IDs + if ('$F_UID') { + uid = tokenize(f_uid_str, delim) + while (uid != "") { + f_uid[strtol(uid, 10)] = 1 + uid = tokenize("", delim) + } + } + + if (error) exit() +} + +probe netdev.transmit +{ + if ('$P_DEVICES') { + if_tx[dev_name] <<< length + if_dev[dev_name] ++ + } +} + +probe netdev.receive +{ + if ('$P_DEVICES') { + if_rx[dev_name] <<< length + if_dev[dev_name] ++ + } +} + +probe socket.send +{ + if (!success) next + + pid = pid() + uid = uid() + ename = execname() + + # Check filters + if ('$FILTER') { + if ('$F_PROT' && !(protocol in f_prot)) next + if ('$F_FAM' && !(family in f_fam)) next + if ('$F_PID' && !(pid in f_pid)) next + if ('$F_NAME' && !(ename in f_name)) next + if ('$F_UID' && !(uid in f_uid)) next + if ('$F_TYPE' && !(type in f_type)) next + } + + execname[pid] = ename + user[pid] = uid + sk_tx[pid, protocol, family] <<< size + sk_pid[pid, protocol, family] += size +} + +probe socket.receive +{ + if (!success) next + + pid = pid() + uid = uid() + ename = execname() + + # Check filters + if ('$FILTER') { + if ('$F_PROT' && !(protocol in f_prot)) next + if ('$F_FAM' && !(family in f_fam)) next + if ('$F_PID' && !(pid in f_pid)) next + if ('$F_NAME' && !(ename in f_name)) next + if ('$F_UID' && !(uid in f_uid)) next + if ('$F_TYPE' && !(type in f_type)) next + } + + execname[pid] = ename + user[pid] = uid + sk_rx[pid, protocol, family] <<< size + sk_pid[pid, protocol, family] += size +} + +function print_activity() +{ + # Print top processes + max = '$P_NUMTOP' + time = gettimeofday_s() + '$TZ_ADJUST' + + printf("======================= %s ========================\n", ctime(time)) + printf("------------------------------- PROCESSES -------------------------------\n") + printf("%-5s %-5s %7s %7s %7s %7s %-4s %-8s %-15s\n", + "PID", "UID", "#SEND", "#RECV", "SEND_KB", + "RECV_KB", "PROT", "FAMILY", "COMMAND") + foreach ([pid, prot, fam] in sk_pid- limit max) { + n_sk_tx = @count(sk_tx[pid, prot, fam]) + n_sk_rx = @count(sk_rx[pid, prot, fam]) + printf("%-5d %-5d %7d %7d %7d %7d %-4s %-8s %-15s\n", + pid, user[pid], n_sk_tx, n_sk_rx, + n_sk_tx ? @sum(sk_tx[pid, prot, fam])/1024 : 0, + n_sk_rx ? @sum(sk_rx[pid, prot, fam])/1024 : 0, + sock_prot_num2str(prot), sock_fam_num2str(fam), + execname[pid]) + } + + # Print top network devices + if ('$P_DEVICES') { + max = '$P_NUMTOP' + printf("-------------------------------- DEVICES --------------------------------\n") + printf("%-7s %13s %13s %15s %15s\n", + "DEV", "#XMIT", "#RECV", "XMIT_KB", "RECV_KB") + foreach ([dev] in if_dev- limit max) { + n_if_tx = @count(if_tx[dev]) + n_if_rx = @count(if_rx[dev]) + printf("%-7s %13d %13d %15d %15d\n", dev, n_if_tx, n_if_rx, + n_if_tx ? @sum(if_tx[dev])/1024 : 0, + n_if_rx ? @sum(if_rx[dev])/1024 : 0) + } + } + + printf("=========================================================================\n\n") + + delete execname + delete user + delete sk_tx + delete sk_rx + delete sk_pid + delete if_tx + delete if_rx + delete if_dev +} + + +probe timer.s('$P_INTERVAL') +{ + print_activity() +} +' |