1

I need to analyze the output of apache server-status. I need to match every entry which has high delays in "Sending Reply" parsing the stastic page. The content looks like this:

11-1 24986 7/9/7288 K 0.08 3 1 77.5 0.08 23.17 IP-CLIENT
hostname:80 GET /static/img/securoty.png HTTP/1.1
12-1 23648 65/108/8176 K 5.74 2 51 90.6 0.16 24.50 IP-CLIENT
hostname:80 POST /php/toolbar_ajax.php HTTP/1.1
13-1 22887 95/118/7672 K 5.38 2 47 140.5 0.17 18.65 IP-CLIENT
hostname:80 POST /php/toolbar_ajax.php HTTP/1.1
14-1 24987 4/6/8016 K 0.09 4 379 288.5 0.28 22.42 IP-CLIENT
hostname:80 GET /static/img/bg_dealers.jpg HTTP/1.1
15-1 24518 7/43/8425 K 2.36 4 53 10.2 0.18 23.24 IP-CLIENT
hostname:80 POST /php/toolbar_ajax.php HTTP/1.1
40-3 12970 14/27/5335 W 10.37 0 0 26.7 0.05 18.44 IP-CLIENT
hostname:80 GET /php/r_fin_new3_std.php HTTP/1.1

Every odd line has this legend:

 __________________________________________________________________

Srv  Child Server number - generation
PID  OS process ID
Acc  Number of accesses this connection / this child / this slot
 M   Mode of operation
CPU  CPU usage, number of seconds
SS   Seconds since beginning of most recent request
Req  Milliseconds required to process most recent request
Conn  Kilobytes transferred this connection
Child Megabytes transferred this child
Slot  Total megabytes transferred this slot
 __________________________________________________________________

Every even line contains the asked URL by the client. I need to match every line containing "Mode of operation" in "W" (Sending Reply) and the "SS" (Seconds since beginning of most recent request) greather then 10. After matching these lines I need to print out the line and the line after. In this case I would need to print:

40-3 12970 14/27/5335 W 10.37 0 0 26.7 0.05 18.44 IP-CLIENT
hostname:80 GET /php/r_fin_new3_std.php HTTP/1.1
  • First line, column 4 (Mode of operation) is "W" = TRUE
  • First line, column 5 (Seconds since beginning of most recent request) is 10.37 > 10 = TRUE

Then print the first line and the next one, which gives me the asked URL.

I've the server-status saved (append) every 5 minutes in a logfile. If I use this command I get all "Sending Reply" and the line after, but cannot filter by those greater than 10:

grep " W " -A 1 /var/log/server-status.log

Any idea?

fedorqui
  • 275,237
  • 103
  • 548
  • 598
Simon
  • 337
  • 2
  • 10

2 Answers2

2

hek2gml works fine and let's have a +1 for him : )

I would go for something a bit different, without getline:

awk 'line {print line; print; line=""} NF==11 && $4=="W" && $5 > 10 {line=$0}' file

Which returns:

40-3 12970 14/27/5335 W 10.37 0 0 26.7 0.05 18.44 IP-CLIENT
hostname:80 GET /php/r_fin_new3_std.php HTTP/1.1

That is, keep checking if the line matches the requirement. If so, store it in the line variable, so that when reading the next line we print it together with the next one.

More idiomatically, you can use what 123 suggests:

awk 'NF==11 && $4=="W" && $5 > 10 {x=2} x && x--' file

That is, set a counter when this condition matches. From that moment on, keep evaluating if the value and value-- is True. Whenever this happens, awk will print the current line. Ultimately it will print the current and next line because we start with counter=2.

Find more of these in printing with sed or awk a line following a matching pattern.

Community
  • 1
  • 1
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Hi and thanks for the credits! Your answer would print the previous line, but it should print the line following the pattern. – hek2mgl Nov 30 '15 at 10:52
  • 2
    Without getline the normal way to print lines after a match is to set a counter i.e `awk 'NF==11 && $4=="W" && $5 > 10{x=2}x&&x--'` – 123 Nov 30 '15 at 11:13
  • @123 oh nice one! Updating with this one also, if you don't mind. – fedorqui Nov 30 '15 at 11:18
1

You can use awk:

awk 'NF==11 && $4=="W" && $5 > 10 {getline line; printf "%s\n%s\n", $0, line}'

I'm checking for lines where the field count is 11, the 4th field is set to W and the numeric value of the 5th column is greater than 10. If the condition is true, I'm getting another line and print the current line and that line.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266