JSON output
This commit is contained in:
@@ -75,6 +75,9 @@ garbage collection period in number of refresh. default is 50.
|
|||||||
\fB-P\fP
|
\fB-P\fP
|
||||||
Show only processes with the specified pid(s).
|
Show only processes with the specified pid(s).
|
||||||
.TP
|
.TP
|
||||||
|
\fB-j\fP
|
||||||
|
Output in JSON format.
|
||||||
|
.TP
|
||||||
\fB-f\fP
|
\fB-f\fP
|
||||||
EXPERIMENTAL: specify string pcap filter (like tcpdump). This may be removed or changed in a future version.
|
EXPERIMENTAL: specify string pcap filter (like tcpdump). This may be removed or changed in a future version.
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
71
src/cui.cpp
71
src/cui.cpp
@@ -49,6 +49,8 @@ extern int viewMode;
|
|||||||
extern bool showcommandline;
|
extern bool showcommandline;
|
||||||
extern bool showBasename;
|
extern bool showBasename;
|
||||||
|
|
||||||
|
extern bool output_json;
|
||||||
|
|
||||||
extern unsigned refreshlimit;
|
extern unsigned refreshlimit;
|
||||||
extern unsigned refreshcount;
|
extern unsigned refreshcount;
|
||||||
|
|
||||||
@@ -90,6 +92,7 @@ public:
|
|||||||
|
|
||||||
void show(int row, unsigned int proglen, unsigned int devlen);
|
void show(int row, unsigned int proglen, unsigned int devlen);
|
||||||
void log();
|
void log();
|
||||||
|
void json();
|
||||||
|
|
||||||
double sent_value;
|
double sent_value;
|
||||||
double recv_value;
|
double recv_value;
|
||||||
@@ -232,6 +235,48 @@ void Line::log() {
|
|||||||
<< recv_value << std::endl;
|
<< recv_value << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
std::string escape_json(const std::string &s) {
|
||||||
|
std::ostringstream o;
|
||||||
|
for (auto c = s.cbegin(); c != s.cend(); c++) {
|
||||||
|
switch (*c) {
|
||||||
|
case '"': o << "\\\""; break;
|
||||||
|
case '\\': o << "\\\\"; break;
|
||||||
|
case '\b': o << "\\b"; break;
|
||||||
|
case '\f': o << "\\f"; break;
|
||||||
|
case '\n': o << "\\n"; break;
|
||||||
|
case '\r': o << "\\r"; break;
|
||||||
|
case '\t': o << "\\t"; break;
|
||||||
|
default:
|
||||||
|
if ('\x00' <= *c && *c <= '\x1f') {
|
||||||
|
o << "\\u"
|
||||||
|
<< std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(*c);
|
||||||
|
} else {
|
||||||
|
o << *c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return o.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Line::json() {
|
||||||
|
std::cout << "{";
|
||||||
|
std::cout << "\"name\": \"" << escape_json(m_name) << "\"";
|
||||||
|
std::cout << ", ";
|
||||||
|
std::cout << "\"pid\": \"" << m_pid << "\"";
|
||||||
|
std::cout << ", ";
|
||||||
|
std::cout << "\"uid\": \"" << m_uid << "\"";
|
||||||
|
std::cout << ", ";
|
||||||
|
std::cout << "\"devicename\": \"" << devicename << "\"";
|
||||||
|
std::cout << ", ";
|
||||||
|
std::cout << "\"sent\": " << sent_value;
|
||||||
|
std::cout << ", ";
|
||||||
|
std::cout << "\"recv\": " << recv_value;
|
||||||
|
std::cout << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int get_devlen(Line *lines[], int nproc, int rows) {
|
int get_devlen(Line *lines[], int nproc, int rows) {
|
||||||
int devlen = MIN_COLUMN_WIDTH_DEV;
|
int devlen = MIN_COLUMN_WIDTH_DEV;
|
||||||
int curlen;
|
int curlen;
|
||||||
@@ -343,6 +388,28 @@ void show_trace(Line *lines[], int nproc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* get_iso8601_timestamp() {
|
||||||
|
static char buffer[32];
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm *utc = gmtime(&now);
|
||||||
|
strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", utc);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_json(Line *lines[], int nproc) {
|
||||||
|
/* print them */
|
||||||
|
std::cout << "{\"timestamp\": \""<< get_iso8601_timestamp() << "\", \"processes\": [";
|
||||||
|
for (int i = 0; i < nproc; i++) {
|
||||||
|
if(i>0){
|
||||||
|
std::cout << ",";
|
||||||
|
}
|
||||||
|
lines[i]->json();
|
||||||
|
delete lines[i];
|
||||||
|
}
|
||||||
|
std::cout << "]}"<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void show_ncurses(Line *lines[], int nproc) {
|
void show_ncurses(Line *lines[], int nproc) {
|
||||||
int rows; // number of terminal rows
|
int rows; // number of terminal rows
|
||||||
int cols; // number of terminal columns
|
int cols; // number of terminal columns
|
||||||
@@ -453,7 +520,9 @@ void do_refresh() {
|
|||||||
/* sort the accumulated lines */
|
/* sort the accumulated lines */
|
||||||
qsort(lines, nproc, sizeof(Line *), GreatestFirst);
|
qsort(lines, nproc, sizeof(Line *), GreatestFirst);
|
||||||
|
|
||||||
if (tracemode || DEBUG)
|
if (output_json)
|
||||||
|
show_json(lines, nproc);
|
||||||
|
else if (tracemode || DEBUG)
|
||||||
show_trace(lines, nproc);
|
show_trace(lines, nproc);
|
||||||
else
|
else
|
||||||
show_ncurses(lines, nproc);
|
show_ncurses(lines, nproc);
|
||||||
|
|||||||
14
src/main.cpp
14
src/main.cpp
@@ -69,6 +69,7 @@ static void help(bool iserror) {
|
|||||||
output << " b: display the program basename instead of the fullpath\n";
|
output << " b: display the program basename instead of the fullpath\n";
|
||||||
output << " m: switch between total (kB, bytes, MB) and throughput (kB/s, "
|
output << " m: switch between total (kB, bytes, MB) and throughput (kB/s, "
|
||||||
" MB/s, GB/s) mode\n";
|
" MB/s, GB/s) mode\n";
|
||||||
|
output << " j: json output\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void quit_cb(int /* i */) {
|
void quit_cb(int /* i */) {
|
||||||
@@ -80,7 +81,7 @@ void quit_cb(int /* i */) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void forceExit(bool success, const char *msg, ...) {
|
void forceExit(bool success, const char *msg, ...) {
|
||||||
if ((!tracemode) && (!DEBUG)) {
|
if ((!tracemode) && (!DEBUG) && (!output_json)) {
|
||||||
exit_ui();
|
exit_ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +142,7 @@ void clean_up() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
procclean();
|
procclean();
|
||||||
if ((!tracemode) && (!DEBUG))
|
if ((!tracemode) && (!DEBUG) && (!output_json))
|
||||||
exit_ui();
|
exit_ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +154,7 @@ int main(int argc, char **argv) {
|
|||||||
int garbage_collection_period = 50;
|
int garbage_collection_period = 50;
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "Vhxtpsd:v:c:laf:Cbg:P:")) != -1) {
|
while ((opt = getopt(argc, argv, "Vhxtpsd:v:c:laf:Cbg:P:j")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'V':
|
case 'V':
|
||||||
versiondisplay();
|
versiondisplay();
|
||||||
@@ -204,6 +205,9 @@ int main(int argc, char **argv) {
|
|||||||
case 'P':
|
case 'P':
|
||||||
pidsToWatch.insert((pid_t)atoi(optarg));
|
pidsToWatch.insert((pid_t)atoi(optarg));
|
||||||
break;
|
break;
|
||||||
|
case 'j':
|
||||||
|
output_json = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
help(true);
|
help(true);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@@ -300,7 +304,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
struct dpargs *userdata = (dpargs *)malloc(sizeof(struct dpargs));
|
struct dpargs *userdata = (dpargs *)malloc(sizeof(struct dpargs));
|
||||||
|
|
||||||
if ((!tracemode) && (!DEBUG)) {
|
if ((!tracemode) && (!DEBUG) && (!output_json)) {
|
||||||
init_ui();
|
init_ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +332,7 @@ int main(int argc, char **argv) {
|
|||||||
time_t const now = ::time(NULL);
|
time_t const now = ::time(NULL);
|
||||||
if (last_refresh_time + refreshdelay <= now) {
|
if (last_refresh_time + refreshdelay <= now) {
|
||||||
last_refresh_time = now;
|
last_refresh_time = now;
|
||||||
if ((!DEBUG) && (!tracemode)) {
|
if ((!DEBUG) && (!tracemode) && (!output_json)) {
|
||||||
// handle user input
|
// handle user input
|
||||||
ui_tick();
|
ui_tick();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ bool showcommandline = false;
|
|||||||
bool showBasename = false;
|
bool showBasename = false;
|
||||||
// viewMode: kb/s or total
|
// viewMode: kb/s or total
|
||||||
int viewMode = VIEWMODE_KBPS;
|
int viewMode = VIEWMODE_KBPS;
|
||||||
|
bool output_json = false;
|
||||||
const char version[] = " version " VERSION;
|
const char version[] = " version " VERSION;
|
||||||
timeval curtime;
|
timeval curtime;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user