Fair question. Some explanation is needed.
So, what does NSLog do? It does two things. First it sends your log message to the Apple System Logger. This is essentially a daemon process that takes log entries and writes them to a system database. You can browse this database via Console.app on Mac OS X. But, this doesn't actually display anything on screen. So then NSLog does the usual writing to stderr. And it's this step that causes it to be written to screen.
With Lumberjack, things are a bit more flexible and transparent. Try disabling the TTY logger in your setup. You'll notice you still see your log statements in Console.app. Or, if iOS, in the device log via Xcode (in organizer). But you won't see anything in Xcode's console while debugging. Now try the reverse. Enable TTY, but disable ASL. Now you'll see output while debugging in Xcode. But your logs will be absent from system log in organizer.
You can capitalize on this for performance. For example, see no need for ASL? Don't enable it. Prefer dedicated log files on iOS where you don't have to worry about truncation due to the super short history the OS seems to keep/display. No problem. A few lines of code and you're done.
Now concerning stderr. This is just a file descriptor within your application. Think of it like a socket or pipe. The other end goes somewhere, but you don't really need to worry about where. If you launch your app on the command line, the pipe gets printed out to the terminal. If launched via Xcode, the pipe goes to the Xcode console. If launched normally (e.g. Double-click in finder, or tap on app to launch on iOS.), then the pipe may go to /dev/null (meaning you can write to it, but the bytes simply go nowhere). Some people will even remap stderr to a log file. It's a crude form of logging, but it works in a pinch.
Under most circumstances, one can ask the system if stderr is going someplace. This is what I've done with the isaTTY variable. It was, in theory, a nice little optimization. All the work required to format and print the log statement gets skipped. However, as you've noticed, it's not always reliable. So I will likely remove the isaTTY variable. As you know, logging to /dev/null doesn't hurt anything, and happens all the time. However, one can still optimize. Just don't enable TTY logger when compiling in release mode.
-Robbie Hanson
Sent from my iPhone