If you’ve ever used Heroku, you’re probably familiars with its logs. Logs a great when debugging a test app as they are readable enough while providing useful information. However, once the application is recieving a lot of traffic, it become quite difficult to make sense of all the logs!

There’s a solution for that, using angle-grinder. Here are some sample commands to use. They can easily be tweaked.

Status Aggregate by Second #

Command #

heroku logs -t | agrind \
  '*
    | parse "T*." as time
    | logfmt
    | count(status < 400) as successful,
      count(status >= 400) as failure,
      p95(service) as service,
      p95(connect) as connect
      by time
    | sort by time desc'
Sample
time            successful        failure        service        connect
-------------------------------------------------------------------------------
09:24:18        9                 0              150            0
09:24:17        11                0              29             0
09:24:16        33                0              106            0

All Paths #

Command #

heroku logs -t | agrind \
  'path | logfmt' \
  --format '{dyno:<6} {connect:6} {service:7} {status:4} {method:5}  {path}'
Sample
web.1     0ms     5ms  304   GET  /foo?bar=baz
web.2     0ms    32ms  200   GET  /hello/word?user=1337
web.3     1ms   120ms  400  POST  /auth/attempt

All status >= 400 #

Command #

heroku logs -t | agrind \
  'path | logfmt | where status >= 400'  \
  --format '{dyno:<6} {connect:6} {service:7} {status:4} {method:5}  {path}'
Sample
web.3     0ms     8ms  404   GET  /not/found
web.2     1ms    25ms  500   GET  /server?error
web.1     0ms   221ms  403  POST  /forbidden/path

First paths stats #

Command #

heroku logs -t | agrind \
  ' path
    | parse regex "path=\"(?P<canonical>/[^/?\"]+)(?P<rest>[^\"]*)?\"" nodrop
    | logfmt
    | count(status < 400) as successful,
      count(status >= 400) as failure,
      p50(service) as mean,
      p95(service) as p95,
      p99(service) as p99
      by canonical
    | sort by mean desc'
Sample
canonical                  successful        failure        mean        p95        p99
----------------------------------------------------------------------------------------------
/base-path                 123               1              61          93         61
/topLevel                  15                0              39          83         103
/api.                      17                0              33          67         70