blob: c456526fdb9a63127da016a1d9efd2eab0e1e627 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GARNET_DRIVERS_BLUETOOTH_LIB_COMMON_LOG_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_COMMON_LOG_H_
#include <cstddef>
// Logging utilities for the host library. This provides a common abstraction
// over Zircon DDK debug utilities (used when btlib runs in a driver) and
// printf.
//
// USAGE:
//
// Functions have been provided to check if logging has been enabled at a
// certain severity and to log a message using a tag, file name, and line
// number:
//
// if (IsLogLevelEnabled(LogSeverity::TRACE)) {
// LogMessage(__FILE__, __LINE__, LogSeverity::TRACE, "bt-host", "oops:
// %d", foo);
// }
//
// or using the bt_log convenience macro:
//
// bt_log(TRACE, "bt-host", "oops: %d", foo);
//
// DRIVER MODE:
//
// By default, the log messages use <ddk/debug.h> as its backend. In this mode
// the ERROR, WARN, INFO, TRACE, and SPEW severity levels directly correspond to
// the DDK severity levels. Log levels are supplied to the kernel commandline,
// e.g. to disable INFO level and enable TRACE level messages in the bt-host
// driver use the following:
//
// driver.bthost.log=-info,+trace
//
// In driver mode, the "tag" argument to bt_log is informational and gets
// included in the log message.
//
// (refer to
// https://fuchsia.googlesource.com/zircon/+/master/docs/kernel_cmdline.md#driver_name_log_flags
// for all supported DDK debug log flags).
//
// PRINTF MODE:
//
// When btlib code is run outside a driver (e.g. bt-host-unittests) log messages
// can be routed to stdout via printf instead of driver_printf. To enable this
// mode, call the UsePrintf() function at process start-up:
//
// int main() {
// ::btlib::common::UsePrintf(::btlib::common::LogSeverity::ERROR);
//
// ...do stuff...
//
// return 0;
// }
//
// The |min_severity| parameter determines the smallest severity level that will
// be allowed. For example, passing LogSeverity::INFO will enable INFO, WARN,
// and ERROR severity levels.
//
// The UsePrintf() function is NOT thread-safe. This should be called EARLY
// and ONLY ONCE during initialization. Once the printf mode is enabled it
// cannot be toggled back to driver mode.
//
// CAVEATS:
//
// Since the logging mode is determined at run-time and not compile-time (due
// to build dependency reasons) users of these utilities will need to link a
// symbol for |__zircon_driver_rec__|. While this symbol will remain unused in
// printf-mode it is needed to pass compilation if the target is not a driver.
// Use the BT_DECLARE_FAKE_DRIVER macro for this purpose:
//
// BT_DECLARE_FAKE_DRIVER();
//
// int main() {
// ::btlib::common::UsePrintf(::btlib::common::LogSeverity::TRACE);
// }
namespace btlib {
namespace common {
// Log severity levels used by the host library, following the convention of
// <ddk/debug.h>
enum class LogSeverity {
// Indicates unexpected failures.
ERROR = 0,
// Indicates a situation that is not an error but may be indicative of an
// impending problem.
WARN = 1,
// Terse information messages for startup, shutdown, or other infrequent state
// changes.
INFO = 2,
// Verbose messages for transactions and state changes
TRACE = 3,
// Very verbose messages.
SPEW = 4,
// Reserved for highly verbose messages (corresponds to the "debug1" driver
// log flag).
DEBUG = 5,
};
constexpr size_t kNumLogSeverities = 6;
bool IsLogLevelEnabled(LogSeverity severity);
void LogMessage(const char* file, int line, LogSeverity severity,
const char* tag, const char* fmt, ...);
void UsePrintf(LogSeverity min_severity);
} // namespace common
} // namespace btlib
#define bt_log(flag, tag, fmt...) \
do { \
if (::btlib::common::IsLogLevelEnabled( \
::btlib::common::LogSeverity::flag)) { \
::btlib::common::LogMessage( \
__FILE__, __LINE__, ::btlib::common::LogSeverity::flag, tag, fmt); \
} \
} while (0)
#define BT_DECLARE_FAKE_DRIVER() zx_driver_rec_t __zircon_driver_rec__ = {};
#endif // GARNET_DRIVERS_BLUETOOTH_LIB_COMMON_LOG_H_