[CONTRIB] halog: support searching by response time
Also support inverting search criteria when specified uppercase
diff --git a/contrib/halog/halog.c b/contrib/halog/halog.c
index 32b4a7f..27e0961 100644
--- a/contrib/halog/halog.c
+++ b/contrib/halog/halog.c
@@ -58,6 +58,10 @@
#define FILT_ACC_COUNT 0x20
#define FILT_GRAPH_TIMERS 0x40
#define FILT_PERCENTILE 0x80
+#define FILT_TIME_RESP 0x100
+
+#define FILT_INVERT_ERRORS 0x200
+#define FILT_INVERT_TIME_RESP 0x400
unsigned int filter = 0;
unsigned int filter_invert = 0;
@@ -69,7 +73,7 @@
{
fprintf(stderr,
"%s"
- "Usage: halog [-c] [-v] [-gt] [-pct] [-s <skip>] [-e] [-ad <delay>] [-ac <count>] < file.log\n"
+ "Usage: halog [-c] [-v] [-gt] [-pct] [-s <skip>] [-e|-E] [-rt|-RT <time>] [-ad <delay>] [-ac <count>] < file.log\n"
"\n",
msg ? msg : ""
);
@@ -353,6 +357,7 @@
int val, test;
int array[5];
int filter_acc_delay = 0, filter_acc_count = 0;
+ int filter_time_resp = 0;
int skip_fields = 1;
argc--; argv++;
@@ -372,6 +377,18 @@
filter |= FILT_ACC_COUNT;
filter_acc_count = atol(*argv);
}
+ else if (strcmp(argv[0], "-rt") == 0) {
+ if (argc < 2) die("missing option for -rt");
+ argc--; argv++;
+ filter |= FILT_TIME_RESP;
+ filter_time_resp = atol(*argv);
+ }
+ else if (strcmp(argv[0], "-RT") == 0) {
+ if (argc < 2) die("missing option for -RT");
+ argc--; argv++;
+ filter |= FILT_TIME_RESP | FILT_INVERT_TIME_RESP;
+ filter_time_resp = atol(*argv);
+ }
else if (strcmp(argv[0], "-s") == 0) {
if (argc < 2) die("missing option for -s");
argc--; argv++;
@@ -379,6 +396,8 @@
}
else if (strcmp(argv[0], "-e") == 0)
filter |= FILT_ERRORS_ONLY;
+ else if (strcmp(argv[0], "-E") == 0)
+ filter |= FILT_ERRORS_ONLY | FILT_INVERT_ERRORS;
else if (strcmp(argv[0], "-c") == 0)
filter |= FILT_COUNT_ONLY;
else if (strcmp(argv[0], "-q") == 0)
@@ -416,6 +435,40 @@
while ((line = fgets2(stdin)) != NULL) {
linenum++;
+ test = 1;
+ if (filter & FILT_TIME_RESP) {
+ int tps;
+
+ /* only report lines with response times larger than filter_time_resp */
+ b = field_start(line, TIME_FIELD + skip_fields);
+ if (!*b) {
+ truncated_line(linenum, line);
+ continue;
+ }
+
+ e = field_stop(b + 1);
+ /* we have field TIME_FIELD in [b]..[e-1] */
+
+ p = b;
+ err = 0;
+ for (f = 0; f < 4 && *p; f++) {
+ tps = str2ic(p);
+ if (tps < 0) {
+ tps = -1;
+ err = 1;
+ }
+
+ SKIP_CHAR(p, '/');
+ }
+
+ if (f < 4) {
+ parse_err++;
+ continue;
+ }
+
+ test &= (tps >= filter_time_resp) ^ !!(filter & FILT_INVERT_TIME_RESP);
+ }
+
if (filter & FILT_ERRORS_ONLY) {
/* only report erroneous status codes */
b = field_start(line, STATUS_FIELD + skip_fields);
@@ -424,18 +477,11 @@
continue;
}
if (*b == '-') {
- test = 1;
+ test &= !!(filter & FILT_INVERT_ERRORS);
} else {
val = strl2ui(b, 3);
- test = (val >= 500 && val <= 599);
+ test &= (val >= 500 && val <= 599) ^ !!(filter & FILT_INVERT_ERRORS);
}
- test ^= filter_invert;
- if (test) {
- tot++;
- if (!(filter & FILT_COUNT_ONLY))
- puts(line);
- }
- continue;
}
if (filter & (FILT_ACC_COUNT|FILT_ACC_DELAY)) {
@@ -539,8 +585,14 @@
continue;
}
+ test ^= filter_invert;
+ if (!test)
+ continue;
+
/* all other cases mean we just want to count lines */
tot++;
+ if (!(filter & FILT_COUNT_ONLY))
+ puts(line);
}
if (t)