Kian-Tat Lim Regarding adding a Log object, your solution on the u/ktlim/getLogger branch is more complete than mine, so I will try using it for the rest of my testing. These comments are with respect to that version of lsst.log:
lsst.log.Log has static Log::setLevel(Log logger, int level) but would it not be simpler to have non-static Log::setLevel(int level)? Similar for getting a level. In essence Log pretends as if it does not know its own name, but in reality is it possible to get that name. Similarly I'd like to see a Log::getContextName() method.
I find it confusing that lsst.log uses "level" instead of "threshold" when describing the threshold at which a logged message will be seen. I feel it conflates two different (though closely related) concepts.
I am not yet convinced that hierarchical contexts are useful. Is there an example showing why they are handier then simply specifying the full name or offering a Log::getSubLogger(subName) method?
pipe_base and pipe_tasks are done and pushed on tickets/
DM-3532 but untested (since I can't yet build log on my Mac and haven't tried the code on lsst-dev). On to C++ code next.
One issue with C++ code is how to handle trace levels used by pex_logging Trace, TTrace and Debug. In pex_logging these were integers 1-9 that mapped were negated to produce log levels. Thus smaller trace levels were more important, ranging from almost as important as INFO to not quite as unimportant as DEBUG. We could simply replace them with huge integers, e.g. 1->19000 to 9->11000, but that's clearly ugly. On a HipChat discussion Tim Jenness proposed adding constants TRACE1-TRACE9 to C++ and Python (and for use on the command line). That sounds best to me since it allows us to exactly replicate the old behavior in a simple way, while avoiding use of the huge integer values for logging levels. I also propose to eliminate the TRACE constant (existing code can use TRACE5 instead).
Note that to use Log objects with these new levels we will also want new LOGLF_level macros for the new named levels. As K-T said on the HipChat discussion: The difference between fixed levels and variable levels was benchmarked at 164 nanosec per call, so fixed is nicer. This probably explains why there is no log macro that accepts a Log object and allows the user to specify an arbitrary log level.
lsst.log Log.h has too many macros, including a pair for each level that logs to the default log (with no name) and can probably be eliminated.
The difference in names between the sprintf macros and boost formatting macros is too subtle, in my opinion. I recommend we adopt one as the default standard, use short names for that version (e.g. LOG_WARN if we ditch the default log) and a longer and very clear name for the deprecated version (e.g. LOG_SPRINTF_WARN or LOG_BOOST_WARN, depending which is deprecated). Or maybe just use the long names for both. The code will be easier to read!