Merge pull request #218 from sgtcortez/feat-process-filter
Add process filter
This commit is contained in:
@@ -21,6 +21,7 @@ nethogs \- Net top tool grouping bandwidth per process
|
||||
.RB [ "\-C" ]
|
||||
.RB [ "\-b" ]
|
||||
.RB [ "\-g period" ]
|
||||
.RB [ "\-P pid" ]
|
||||
.RI [device(s)]
|
||||
.SH DESCRIPTION
|
||||
NetHogs is a small 'net top' tool. Instead of breaking the traffic down per protocol or per subnet, like most such tools do, it groups bandwidth by process - and does not rely on a special kernel module to be loaded. So if there's suddenly a lot of network traffic, you can fire up NetHogs and immediately see which PID is causing this, and if it's some kind of spinning process, kill it.
|
||||
@@ -69,6 +70,9 @@ Display the program basename.
|
||||
\fB-g\fP
|
||||
garbage collection period in number of refresh. default is 50.
|
||||
.TP
|
||||
\fB-P\fP
|
||||
Show only processes with the specified pid(s).
|
||||
.TP
|
||||
\fB-f\fP
|
||||
EXPERIMENTAL: specify string pcap filter (like tcpdump). This may be removed or changed in a future version.
|
||||
.TP
|
||||
@@ -113,7 +117,9 @@ command, as follows:
|
||||
sudo setcap "cap_net_admin,cap_net_raw+pe" /usr/local/sbin/nethogs
|
||||
.EE
|
||||
.in
|
||||
|
||||
.SH "Notes"
|
||||
1. When using the -P <pid> option, in a case where a process exited (normally or abruptly), Nethogs does not track that it exited. So, the operating system might create
|
||||
a new process (for another program) with the same pid. In this case, this new process will be shown by Nethogs.
|
||||
.SH "SEE ALSO"
|
||||
.I netstat(8) tcpdump(1) pcap(3)
|
||||
.SH AUTHOR
|
||||
|
||||
12
src/main.cpp
12
src/main.cpp
@@ -1,5 +1,6 @@
|
||||
#include "nethogs.cpp"
|
||||
#include <fcntl.h>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -14,6 +15,8 @@
|
||||
static std::pair<int, int> self_pipe = std::make_pair(-1, -1);
|
||||
static time_t last_refresh_time = 0;
|
||||
|
||||
std::set<pid_t> pidsToWatch;
|
||||
|
||||
// selectable file descriptors for the main loop
|
||||
static fd_set pc_loop_fd_set;
|
||||
static std::vector<int> pc_loop_fd_list;
|
||||
@@ -27,7 +30,7 @@ static void help(bool iserror) {
|
||||
// output << "usage: nethogs [-V] [-b] [-d seconds] [-t] [-p] [-f (eth|ppp))]
|
||||
// [device [device [device ...]]]\n";
|
||||
output << "usage: nethogs [-V] [-h] [-x] [-d seconds] [-v mode] [-c count] "
|
||||
"[-t] [-p] [-s] [-a] [-l] [-f filter] [-C] [-b]"
|
||||
"[-t] [-p] [-s] [-a] [-l] [-f filter] [-C] [-b] [-P pid] "
|
||||
"[device [device [device ...]]]\n";
|
||||
output << " -V : prints version.\n";
|
||||
output << " -h : prints this help.\n";
|
||||
@@ -54,6 +57,7 @@ static void help(bool iserror) {
|
||||
" This may be removed or changed in a future version.\n";
|
||||
output << " device : device(s) to monitor. default is all "
|
||||
"interfaces up and running excluding loopback\n";
|
||||
output << " -P : Show only processes.\n";
|
||||
output << std::endl;
|
||||
output << "When nethogs is running, press:\n";
|
||||
output << " q: quit\n";
|
||||
@@ -146,8 +150,9 @@ int main(int argc, char **argv) {
|
||||
char *filter = NULL;
|
||||
int garbage_collection_period = 50;
|
||||
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "Vhxtpsd:v:c:laf:Cbg:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "Vhxtpsd:v:c:laf:Cbg:P:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'V':
|
||||
versiondisplay();
|
||||
@@ -195,6 +200,9 @@ int main(int argc, char **argv) {
|
||||
case 'g':
|
||||
garbage_collection_period = (time_t)atoi(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
pidsToWatch.insert((pid_t) atoi(optarg));
|
||||
break;
|
||||
default:
|
||||
help(true);
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <ncurses.h>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <strings.h>
|
||||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||||
@@ -34,6 +35,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "conninode.h"
|
||||
#include "inode2prog.h"
|
||||
@@ -66,6 +68,8 @@ Process *unknownudp;
|
||||
Process *unknownip;
|
||||
ProcList *processes;
|
||||
|
||||
extern std::set<pid_t> pidsToWatch;
|
||||
|
||||
#define KB (1UL << 10)
|
||||
#define MB (1UL << 20)
|
||||
#define GB (1UL << 30)
|
||||
@@ -77,6 +81,7 @@ float tokbps(u_int64_t bytes) { return (((double)bytes) / PERIOD) / KB; }
|
||||
float tombps(u_int64_t bytes) { return (((double)bytes) / PERIOD) / MB; }
|
||||
float togbps(u_int64_t bytes) { return (((double)bytes) / PERIOD) / GB; }
|
||||
|
||||
|
||||
void process_init() {
|
||||
unknowntcp = new Process(0, "", "unknown TCP");
|
||||
processes = new ProcList(unknowntcp, NULL);
|
||||
@@ -87,6 +92,7 @@ void process_init() {
|
||||
// unknownip = new Process (0, "", "unknown IP");
|
||||
// processes = new ProcList (unknownip, processes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int Process::getLastPacket() {
|
||||
@@ -262,6 +268,10 @@ Process *getProcess(unsigned long inode, const char *devicename) {
|
||||
if (proc != NULL)
|
||||
return proc;
|
||||
|
||||
if ( !(pidsToWatch.empty()) && pidsToWatch.find(node->pid) == pidsToWatch.end() ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// extract program name and command line from data read from cmdline file
|
||||
const char *prgname = node->cmdline.c_str();
|
||||
const char *cmdline = prgname + strlen(prgname) + 1;
|
||||
@@ -384,6 +394,10 @@ Process *getProcess(Connection *connection, const char *devicename,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(pidsToWatch.empty()) && proc == NULL) {
|
||||
proc = (packettype == IPPROTO_TCP) ? unknowntcp : unknownudp;
|
||||
}
|
||||
|
||||
if (proc == NULL) {
|
||||
proc = new Process(inode, "", connection->refpacket->gethashstring());
|
||||
processes = new ProcList(proc, processes);
|
||||
@@ -426,3 +440,4 @@ void remove_timed_out_processes() {
|
||||
}
|
||||
|
||||
void garbage_collect_processes() { garbage_collect_inodeproc(); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user