Hi,
I'm currently polishing the public API to prepare for a first release. Please don't ask for a date, because I won't be able to give one. Anyway, since some of these changes requires breaking backwards compatibility, I want to take this opportunity to reconsider a few other items as well. And one of these things is the logging support.
Currently, the libdivecomputer API exposes the message() and message_set_logfile() functions. The first one is a simple printf() style logging function sending its output to stderr, and the second one allows to duplicate the output to a logfile. The main purpose of these functions is to allow non-technical people to easily email the output of the test applications, without having to redirect the output manually to a file. Running a command line application is already difficult enough.
Originally, these functions were intended for internal use only. They where never supposed to be part of the public api. Applications are supposed to rely on the status code that are returned. The logfile should be used at most for troubleshooting and diagnostics purposes. The only reason why they are included in the public api today, is because of the test applications. To make the output easier to interpret, the test applications write some additional info (e.g. the name of the functions being called). Since the test applications are no different from other applications, these functions had to be public.
But there are a number of potential problems:
1. Thread-safety. The logging functions use a number of global variables without any locking, and are therefore not thread-safe. This is not ideal considered the remainder of the library was designed to be used safely in a multi-threaded application (under a number of conditions).
In practice it's not that bad because the global variables used for the logging or not that critical (e.g. timestamps), and most C stdio libraries implementations are thread-safe by default (thus the actual file writing should be fine, and in case two threads want to log at the same time, the output might be interleaved.).
I believe the only real solution is either to implement proper locking (which is a heavyweight solution considered we don't require any explicit locking elsewhere in the code) or disable all logging by default. Disabling the logging could be done at build time (e.g. logging in debug builds only) or at runtime (see next item). Note that disabling at runtime wouldn't be truly thread-safe either.
2. Verbosity. By default only errors are logged. However, for troubleshooting this minimal info is almost useless and a much more verbose logfile is required. For this reason, the test applications are using a special patched version of the library, which is not ideal.
This could be solved by adding a new function to let the application specify the loglevel (e.g. None, Errors, Warnings, Debug), with a default setting of "None".
If anyone has ideas to improve this situation, you're welcome to share them!
My personal preference is to allow to disable the logging at build time (e.g. the easiest solution), to avoid the entire thread-safety issues, and build with logging when necessary (e.g. in the single threaded test applications). But on the other hand, it would be great if those verbose diagnostics logs could be generated directly from within the applications, so users are not forced to use the very user unfriendly commandline based test applications.
Jef