2010-09-19
Your on the fly control system should not use toggles
Here's a request to programmers: if you are building a system with
some form of dynamic control and adjustment commands, like Bind 9 and
its rndc
program for controlling the daemon's behavior on the fly,
your interface should not include 'toggles', commands or options that
invert the current state of a setting. In rndc
, an example is 'rndc
querylog
'; this turns DNS query logging on if it is off, and turns it
off if it is on.
(In fact this extends to startup options too.)
A toggle is a terrible interface because it is a mechanism, not an outcome, and people don't care about the former and do care about the latter. There are basically no situations in which sysadmins want to change the state of query logging without caring what the previous and new states are; instead, sysadmins either want to turn it on or to turn it off. By providing only a mechanism, you force people to either assume what the current state is or to explicitly check it before (and perhaps after) they use your interface.
So please don't do that. Don't build interfaces like 'rndc querylog
';
make interfaces that are 'rndc querylog on
' and 'rndc querylog off
'.
Your users will thank you for it.
(Toggles work in GUIs because you can see their state as well as change them, and you see their state before you change them.)
A related sin is interfaces that increase or decrease a setting (such as verbosity or debug level), instead of setting it directly. While there are some uses for these, they should be the secondary way that you change the setting in question, not the primary way; you should always provide a way to directly set the setting's value, and expect it to be used most of the time. Again, usually people know the value that they want. It is rare that increasing or decreasing the level is the actual outcome people want, instead of just the mechanism for getting it.
(The exception is when you are not certain what debug level will start producing the messages you want without also producing too much detail. There it makes sense to increase the debug level step by step until you hit the right point. But frankly, with modern shells with command line editing you can do this almost as well with a 'set to level X' interface.)
Also, a personal note: sysadmins will kill you if the only way to
disable debugging is to repeatedly run 'cmd decrease-debugging
' until
it stops entirely. Well, really we'll kill your program and restart it,
but we'll sure wish that we could say very grumpy things to you.
Some notes on (dynamic) Bind 9 logging
Bind 9's rndc
has tasty looking options to change and increase logging
on the fly, which is just what you want if you're trying to track down
an erratic behavior in a caching nameserver (where restarting the server
might well make the whole thing go away so you can't troubleshoot what's
going on). However, it turns out that you need some Bind configuration
options already configured in order to make it work. Since I just went
through figuring this out (and I may need to do it again), here's what's
needed:
- you need one or more logging channels configured with '
severity dynamic
'. Without this, you can issue all the 'rndc trace 99
' commands you want to and nothing extra will get logged.(Note that '
severity debug
' does not do what you want.)Doing this only to a file-based channel is good, unless you really want to flood your syslog for some reason. If your Bind is running chroot'd (as is the default on, eg, OpenBSD) the file path for this is relative to the chroot.
- you must also add whatever logging categories you're interested in and
configure them to use the channel you've set up with dynamic
severity.
Note that some categories will log additional things even at '
rndc notrace
' level; this may make you want to comment them out when not running in a debug setup. Sadly there seems to be no way to enable and disable logging categories throughrndc
. - '
rndc reconfig
' may be helpful in getting a running Bind instance to notice your changed or added logging configuration without too many changes in its behavior. This really depends on what you're trying to debug, though.(It was successful for me, in that it didn't suddenly make the Bind instance start properly answering the query it had previously been failing on.)
Once you have done all of this, 'rndc querylog; rndc trace 99
' should
turn on more or less maximum logging, and then 'rndc querylog; rndc
notrace
' will turn it off. You may want to verify the current running
setup with 'rndc status
'.
Sadly, I cannot (yet) say what categories it is necessary to enable in order to get Bind to log enough information to reconstruct where a particular query answer comes from. Maybe I'll figure that out Monday, assuming I don't decide that the server has just started to malfunction and needs be restarted.