Take a look at blktrace on Linux. It logs all block I/O layer activity from when an I/O request is sent to the disk to when it's serviced. It also outputs which sectors on the disk were written to service the request. People have written a few tools to read these logs and show meaningful numbers/pretty graphs -- btt is the official one, and here's another one that I like: http://oss.oracle.com/~mason/seekwatcher/.
Among other things, you can distinguish random from sequential I/O using blktrace and its accompanying set of tools by looking at the distance between subsequent I/O requests sent to the disk.