The java.util.logging classes are taking over the homebrewn solutions at the moment. It's a very flexible framework which can send the output to wherever you like. By default, logging to stdout and a flat file are possible.
Personally, I think it's an excellent solution to send logging to a file and then grep and tail the file. Configuring the logging also works best using an editor on the logging.properties file. This works fine on development, however, when code is moved to a production environment, UNIX administrators would rather have people looking at exceptions through standard maintenance screens and not give developers shell accounts on servers. Since your standard maintenance screens work on database tables, it's only logical to log to that database.
I've created some code which can be downloaded below. It consists of two parts. The first part is simply a logging handler which sends the log messages to the database. The second part consists of a thread which will read the logging configuration (that you would normally put in your logging.properties file) from a database table. This thread has two advantages. First of all, just like with logging you don't need remote access to the server where your application is running. Also, it rereads the configuration periodically so you don't have to restart your application when you change something in the logging. These are big plusses for an application administrator.
Note that the code can be improved in many ways. The logging handler could be improved for instance by properly using PreparedStatements and also, it could be using the batch updates feature that JDBC 2.0 offers. The code is in the public domain, so feel free to hack!