Greetings,
I've been running screen for a while now - I use it day to day operations just fine, and occasionally when I'm in a pinch I use it for a serial terminal.
The way you scroll up in screen ( or atleast the way that I've found that seems to be standard ) is to use ctrl + a then [. This puts you into "copy mode", and there are some nice features in there. My issue was thus:
I have a production service that prints some debug to stdout. I could make it print to stderr, but it really doesn't matter in this case. I want to have some hope of if something goes wrong figuring out what did. Log files aren't really an option so I ran it in screen. Yes yes I could have made it network log to somewhere else, but again, not really an viable option in this case. Works great as the program dies and the output stops, leaving the last debug messages in the buffer of screen.
Enter problem: Disconnecting from the screen ( ctrl+a ) d, leaving it in copy mode. Turns out that screen _blocks_stdout_ while it is in copy mode. Depending on what kind of program you're running in screen this could be bad.
In my case it was pretty annoying because _monitoring_didn't_catch_it_ as the program was still responding to tcp connections. It was block writing to stdout. Because the blocking stdout command was in its own function and I am using an async javascript program without waiting for a callback, other parts of the system still worked.
Thought I'd share. Make sure you hit esc+esc on production screen stuff.. it blocks stdout!
Rob
On 2012-10-10 09:50, Robert Keizer wrote:
I have a production service that prints some debug to stdout. I could make it print to stderr, but it really doesn't matter in this case.
Are you sure it doesn't matter? Read on...
I want to have some hope of if something goes wrong figuring out what did. Log files aren't really an option so I ran it in screen. Yes yes I could have made it network log to somewhere else, but again, not really an viable option in this case. Works great as the program dies and the output stops, leaving the last debug messages in the buffer of screen.
One of the classic C/UNIX lessons about stdout vs stderr is that the C library buffers stdout by default but not stderr, exactly for the reason that you want error messages to be flushed out right away, leaving nothing in the buffer. This is particularly important if the program dies in a way that prevents the usual exit processing, such as flushing buffers and closing file I/O.
So, issues with "screen" aside, you probably should either send your debug output to stderr, or set your stdout to unbuffered mode while debugging (or both).
On 12-10-10 10:33 AM, Gilbert E. Detillieux wrote:
On 2012-10-10 09:50, Robert Keizer wrote:
I have a production service that prints some debug to stdout. I could make it print to stderr, but it really doesn't matter in this case.
Are you sure it doesn't matter? Read on...
I want to have some hope of if something goes wrong figuring out what did. Log files aren't really an option so I ran it in screen. Yes yes I could have made it network log to somewhere else, but again, not really an viable option in this case. Works great as the program dies and the output stops, leaving the last debug messages in the buffer of screen.
One of the classic C/UNIX lessons about stdout vs stderr is that the C library buffers stdout by default but not stderr, exactly for the reason that you want error messages to be flushed out right away, leaving nothing in the buffer. This is particularly important if the program dies in a way that prevents the usual exit processing, such as flushing buffers and closing file I/O.
So, issues with "screen" aside, you probably should either send your debug output to stderr, or set your stdout to unbuffered mode while debugging (or both).
Interesting!
Thought I'd test out stdout vs stderr just to see if this was in fact the case. It's not - stderr and stdout have the same effect in this case.
Below is a script the listens for incoming data on a given port ( example is 1337 ). When data is received it writes to either stdout or stderr and then sends data on to another port ( in this case 1338 ). This script also fills up the screen buffer by a simple loop ( tested filling with both stderr and stdout ).
Using telnet to feed the script data, and nc ( nc -lk 1338 ) to listen on port 1338 for the output, one can test to confirm.
net = require "net" server = net.createServer ( c ) -> c.setEncoding "utf8" c.on "data", ( data ) -> _c = net.createConnection 1338, ( ) -> process.stderr.write "Data: " + data + "\n" _c.write data _c.end( )
server.listen 1337, "127.0.0.1" loops = ( ) -> process.stderr.write "Loopies: " + Date( ) + "\n" setTimeout loops, 100 loops( )
Screenshot is attached - it shows this script in the top left running in screen, with copy mode enabled. Right of it is the telnet session feeding it, and on the bottom left is the nc or "output". Note that the last two inputs did not make it to the output. Ergo, unless I'm totally an idiot in my implementation: This is blocking on stderr as well.
Thoughts? Because now I'm officially annoyed that this blocks on stderr as well!
Rob
It's also worth noting that as soon as copy mode is disabled ( esc+esc ) the messages pop up in the output nc.
I'm assuming the output has a buffer limit because I ran into the issue where some, but not all buffered output from the program made it to the output nc listener (not this example, but how I got into this mess ).
Or perhaps what makes more sense is that the program I'm using has a limit on how many functions it will handle at once - given that it is a single thread just async, with >1000 of these it could simply hit a limit of saying "no" and waiting for the process.stdout / process.stderr to complete before moving on.
Rob
People may be getting things out of order due to myself adding an attachment - I replied to Gilbert before the "Its also worth noting" email. Apologies for yet another email, but it may make a little more sense to people following the discussion.
Rob