I haven't found a logging solution that blows me away, rlog looks like the easiest for me to integrate. I propose to integrated it under a single-macro QPID_LOG API the following one-macro logging API which is type safe (ostream based), and should be efficiently implementable over any logging infrastructure that is capable of not evaluating the log message if no log will be generated.
rlog will let us retrieve logs by level, by component (arbirary collection of source files), by individual source file or combinations thereof. It has stderr and syslog backends built in and can be extended. It can be configured to include source file/line, thread ID, function name in logs. If it lets us down long term, we should be able to replace easily since only QPID_LOG macros will be widely distributed. (rlog actually offers hierarchical channels beyond simple log levels, deliberately ignored to increase portability to future log infrastructures.) Comments welcome but I'm implementing right away so speak up! Cheers, Alan.
#ifndef _log_h #define _log_h /* * * Copyright (c) 2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include <rlog/rlog.h> #include <sstream> /** @file Qpid logging macro. * Use only the QPID_LOG macros in this file for logging, as the logging * infrastructure used may change in the future. */ * namespace qpid { namespace log { using namespace boost::format; /** * Example of use: * @code * QPID_LOG(debug, "There are " << foocount << " foos in the bar."); * QPID_LOG(error, boost::format("Dohickey %s exploded") % dohicky.name()); * @endcode * * Logging levels are: debug, info, warning, error * * All code with logging statements should be built with * -DQPID_COMPONENT=<component name> * You can subscribe to log messages by level, component or both. */ #define QPID_LOG(::qpid::log::LEVEL, MESSAGE) \ _rMessage( LOGID, LEVEL, static_cast<std::ostringstream&>(std::ostringstream() << MESSAGE).str().c_str() ) /** @internal log levels map to rlog channels */ typedef const rlog::RLogChannel* Level; extern Level debug, info, warning, error; #ifndef QPID_COMPONENT # error "QPID_COMPONENT undefined. Use -DQPID_COMPONENT=<component name>" #endif #define RLOG_COMPONENT QPID_COMPONENT }} // namespace qpid::log #endif /*!_log_h*/
