The biggest problem I have experienced is that logging the activity changes the timing of the threads. So if I had to do it today, I night make a really simple set of codes for certain events. I would then write those codes to a circular buffer, to be consumed by a monitor thread. The monitor thread would then write to a log file, or send over a socket to a monitoring program or something. Another program, maybe on another processor, would translate the codes into readable strings, in parallel vertical columns, one for each thread, with consistent timing across any horizontal rows.