blob: 5a2e23777fb1650fa3828bcc5b8ad22f7f2d88c7 [file] [log] [blame]
btolsch9d6900c2018-05-30 18:22:53 -07001// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef PLATFORM_API_LOGGING_H_
6#define PLATFORM_API_LOGGING_H_
7
8#include <sstream>
9
Jordan Baylesd08f8d22019-01-17 15:06:02 -080010#include "third_party/abseil/src/absl/strings/string_view.h"
11
btolsch9d6900c2018-05-30 18:22:53 -070012namespace openscreen {
13namespace platform {
14
15enum class LogLevel {
16 kVerbose = 0,
17 kInfo,
18 kWarning,
19 kError,
20 kFatal,
21};
22
23std::string LogLevelToString(LogLevel level);
24
25//
26// PLATFORM IMPLEMENTATION
btolsch6d3d0bc2018-12-10 18:59:28 -080027// The following functions must be implemented by the platform.
28void LogInit(const char* filename);
btolsch9d6900c2018-05-30 18:22:53 -070029void SetLogLevel(LogLevel level, int verbose_level = 0);
30void LogWithLevel(LogLevel level,
31 int verbose_level,
Jordan Baylesd08f8d22019-01-17 15:06:02 -080032 absl::string_view file,
btolsch9d6900c2018-05-30 18:22:53 -070033 int line,
Jordan Baylesd08f8d22019-01-17 15:06:02 -080034 absl::string_view msg);
btolsch9d6900c2018-05-30 18:22:53 -070035void Break();
36//
37// END PLATFORM IMPLEMENTATION
38//
39
40// The stream-based logging macros below are adapted from Chromium's
41// base/logging.h.
42class LogMessage {
43 public:
Jordan Baylesd08f8d22019-01-17 15:06:02 -080044 LogMessage(LogLevel level,
45 int verbose_level,
46 absl::string_view file,
47 int line);
btolsch9d6900c2018-05-30 18:22:53 -070048 ~LogMessage();
49
50 std::ostream& stream() { return stream_; }
51
52 private:
53 const LogLevel level_;
54 const int verbose_level_;
Jordan Baylesd08f8d22019-01-17 15:06:02 -080055
56 // The file here comes from the __FILE__ macro, which should persist while
57 // we are doing the logging. Hence, keeping it unmanaged here and not
58 // creating a copy should be safe.
59 absl::string_view const file_;
btolsch9d6900c2018-05-30 18:22:53 -070060 const int line_;
61 std::ostringstream stream_;
62};
63
btolschfc647682018-11-13 23:43:33 -080064#define OSP_VLOG(l) \
btolsch9d6900c2018-05-30 18:22:53 -070065 ::openscreen::platform::LogMessage( \
66 ::openscreen::platform::LogLevel::kVerbose, l, __FILE__, __LINE__) \
67 .stream()
btolschfc647682018-11-13 23:43:33 -080068#define OSP_LOG_INFO \
btolsch9d6900c2018-05-30 18:22:53 -070069 ::openscreen::platform::LogMessage(::openscreen::platform::LogLevel::kInfo, \
70 0, __FILE__, __LINE__) \
71 .stream()
btolschfc647682018-11-13 23:43:33 -080072#define OSP_LOG_WARN \
btolsch9d6900c2018-05-30 18:22:53 -070073 ::openscreen::platform::LogMessage( \
74 ::openscreen::platform::LogLevel::kWarning, 0, __FILE__, __LINE__) \
75 .stream()
btolschfc647682018-11-13 23:43:33 -080076#define OSP_LOG_ERROR \
btolsch9d6900c2018-05-30 18:22:53 -070077 ::openscreen::platform::LogMessage(::openscreen::platform::LogLevel::kError, \
78 0, __FILE__, __LINE__) \
79 .stream()
btolschfc647682018-11-13 23:43:33 -080080#define OSP_LOG_FATAL \
btolsch9d6900c2018-05-30 18:22:53 -070081 ::openscreen::platform::LogMessage(::openscreen::platform::LogLevel::kFatal, \
82 0, __FILE__, __LINE__) \
83 .stream()
84
85namespace detail {
86
87class Voidify {
88 public:
89 Voidify() = default;
90 void operator&(std::ostream&) {}
91};
92
93} // namespace detail
94
btolschfc647682018-11-13 23:43:33 -080095#define OSP_LAZY_STREAM(stream, condition) \
btolsch9d6900c2018-05-30 18:22:53 -070096 !(condition) ? (void)0 : ::openscreen::platform::detail::Voidify() & (stream)
btolschfc647682018-11-13 23:43:33 -080097#define OSP_EAT_STREAM OSP_LAZY_STREAM(OSP_LOG_INFO, false)
98#define OSP_LOG_IF(level, condition) \
99 OSP_LAZY_STREAM(OSP_LOG_##level, (condition))
100#define OSP_VLOG_IF(level, condition) \
101 OSP_LAZY_STREAM(OSP_VLOG(level), (condition))
btolsch9d6900c2018-05-30 18:22:53 -0700102
btolschfc647682018-11-13 23:43:33 -0800103// TODO(btolsch): Add tests for (D)OSP_CHECK and possibly logging.
104#define OSP_CHECK(condition) \
105 OSP_LAZY_STREAM(OSP_LOG_FATAL, !(condition)) \
106 << "OSP_CHECK(" << #condition << ") failed: "
btolsch9d6900c2018-05-30 18:22:53 -0700107
btolschfc647682018-11-13 23:43:33 -0800108#define OSP_CHECK_EQ(a, b) OSP_CHECK((a) == (b)) << a << " vs. " << b << ": "
109#define OSP_CHECK_NE(a, b) OSP_CHECK((a) != (b)) << a << " vs. " << b << ": "
110#define OSP_CHECK_LT(a, b) OSP_CHECK((a) < (b)) << a << " vs. " << b << ": "
111#define OSP_CHECK_LE(a, b) OSP_CHECK((a) <= (b)) << a << " vs. " << b << ": "
112#define OSP_CHECK_GT(a, b) OSP_CHECK((a) > (b)) << a << " vs. " << b << ": "
113#define OSP_CHECK_GE(a, b) OSP_CHECK((a) >= (b)) << a << " vs. " << b << ": "
btolsch834accf2018-06-13 23:10:28 -0700114
btolschfc647682018-11-13 23:43:33 -0800115#if defined(_DEBUG) || defined(OSP_DCHECK_ALWAYS_ON)
116#define OSP_DCHECK_IS_ON() 1
117#define OSP_DCHECK(condition) OSP_CHECK(condition)
118#define OSP_DCHECK_EQ(a, b) OSP_CHECK_EQ(a, b)
119#define OSP_DCHECK_NE(a, b) OSP_CHECK_NE(a, b)
120#define OSP_DCHECK_LT(a, b) OSP_CHECK_LT(a, b)
121#define OSP_DCHECK_LE(a, b) OSP_CHECK_LE(a, b)
122#define OSP_DCHECK_GT(a, b) OSP_CHECK_GT(a, b)
123#define OSP_DCHECK_GE(a, b) OSP_CHECK_GE(a, b)
btolsch9d6900c2018-05-30 18:22:53 -0700124#else
btolschfc647682018-11-13 23:43:33 -0800125#define OSP_DCHECK_IS_ON() 0
126#define OSP_DCHECK(condition) OSP_EAT_STREAM
127#define OSP_DCHECK_EQ(a, b) OSP_EAT_STREAM
128#define OSP_DCHECK_NE(a, b) OSP_EAT_STREAM
129#define OSP_DCHECK_LT(a, b) OSP_EAT_STREAM
130#define OSP_DCHECK_LE(a, b) OSP_EAT_STREAM
131#define OSP_DCHECK_GT(a, b) OSP_EAT_STREAM
132#define OSP_DCHECK_GE(a, b) OSP_EAT_STREAM
btolsch9d6900c2018-05-30 18:22:53 -0700133#endif
134
btolschfc647682018-11-13 23:43:33 -0800135#define OSP_DLOG_INFO OSP_LOG_IF(INFO, OSP_DCHECK_IS_ON())
136#define OSP_DLOG_WARN OSP_LOG_IF(WARN, OSP_DCHECK_IS_ON())
137#define OSP_DLOG_ERROR OSP_LOG_IF(ERROR, OSP_DCHECK_IS_ON())
138#define OSP_DLOG_FATAL OSP_LOG_IF(FATAL, OSP_DCHECK_IS_ON())
139#define OSP_DLOG_IF(level, condition) \
140 OSP_LOG_IF(level, OSP_DCHECK_IS_ON() && (condition))
141#define OSP_DVLOG(l) OSP_VLOG_IF(l, OSP_DCHECK_IS_ON())
142#define OSP_DVLOG_IF(l, condition) \
143 OSP_VLOG_IF(l, OSP_DCHECK_IS_ON() && (condition))
btolsch834accf2018-06-13 23:10:28 -0700144
btolschfc647682018-11-13 23:43:33 -0800145#define OSP_UNIMPLEMENTED() OSP_LOG_ERROR << __func__ << ": unimplemented"
btolsch4b68dc92018-07-26 00:26:54 -0700146
btolsch9d6900c2018-05-30 18:22:53 -0700147} // namespace platform
148} // namespace openscreen
149
btolscha21e8ed2018-08-30 15:13:48 -0700150#endif // PLATFORM_API_LOGGING_H_