2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the LGPL License, Version 2.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * https://www.gnu.org/licenses/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <type_traits>
25 enum class LogLevel : uint8_t { INFO, WARN, CRIT, OFF };
30 VDebug& debug() { return *this; }
31 VDebug(LogLevel level, char const* file, char const* function,
35 VDebug(VDebug&&) = default;
36 VDebug& operator=(VDebug&&) = default;
38 void stringify(std::ostream& os);
40 VDebug& operator<<(char arg);
41 VDebug& operator<<(int32_t arg);
42 VDebug& operator<<(uint32_t arg);
43 // VDebug& operator<<(int64_t arg);
44 // VDebug& operator<<(uint64_t arg);
46 VDebug& operator<<(long arg);
47 VDebug& operator<<(unsigned long arg);
48 VDebug& operator<<(double arg);
49 VDebug& operator<<(std::string const& arg);
52 VDebug& operator<<(const char (&arg)[N])
54 encode(string_literal_t(arg));
58 template <typename Arg>
59 typename std::enable_if<std::is_same<Arg, char const*>::value,
61 operator<<(Arg const& arg)
67 template <typename Arg>
68 typename std::enable_if<std::is_same<Arg, char*>::value, VDebug&>::type
69 operator<<(Arg const& arg)
75 struct string_literal_t {
76 explicit string_literal_t(char const* s) : m_s(s) {}
83 template <typename Arg>
86 template <typename Arg>
87 void encode(Arg arg, uint8_t type_id);
89 void encode(char* arg);
90 void encode(char const* arg);
91 void encode(string_literal_t arg);
92 void encode_c_string(char const* arg, size_t length);
93 void resize_buffer_if_needed(size_t additional_bytes);
94 void stringify(std::ostream& os, char* start, char const* const end);
97 size_t m_bytes_used{0};
98 size_t m_buffer_size{0};
99 std::unique_ptr<char[]> m_heap_buffer;
101 char m_stack_buffer[256 - sizeof(bool) - 2 * sizeof(size_t) -
102 sizeof(decltype(m_heap_buffer)) - 8 /* Reserved */];
105 struct VDebugServer {
107 * Ideally this should have been operator+=
108 * Could not get that to compile, so here we are...
110 bool operator==(VDebug&);
113 void set_log_level(LogLevel level);
115 bool is_logged(LogLevel level);
118 * Non guaranteed logging. Uses a ring buffer to hold log lines.
119 * When the ring gets full, the previous log line in the slot will be dropped.
120 * Does not block producer even if the ring buffer is full.
121 * ring_buffer_size_mb - LogLines are pushed into a mpsc ring buffer whose size
122 * is determined by this parameter. Since each LogLine is 256 bytes,
123 * ring_buffer_size = ring_buffer_size_mb * 1024 * 1024 / 256
125 struct NonGuaranteedLogger {
126 NonGuaranteedLogger(uint32_t ring_buffer_size_mb_)
127 : ring_buffer_size_mb(ring_buffer_size_mb_)
130 uint32_t ring_buffer_size_mb;
134 * Provides a guarantee log lines will not be dropped.
136 struct GuaranteedLogger {
140 * Ensure initialize() is called prior to any log statements.
141 * log_directory - where to create the logs. For example - "/tmp/"
142 * log_file_name - root of the file name. For example - "nanolog"
143 * This will create log files of the form -
147 * log_file_roll_size_mb - mega bytes after which we roll to next log file.
149 void initialize(GuaranteedLogger gl, std::string const& log_directory,
150 std::string const& log_file_name,
151 uint32_t log_file_roll_size_mb);
152 void initialize(NonGuaranteedLogger ngl, std::string const& log_directory,
153 std::string const& log_file_name,
154 uint32_t log_file_roll_size_mb);
156 #define VDEBUG_LOG(LEVEL) \
157 VDebugServer() == VDebug(LEVEL, __FILE__, __func__, __LINE__).debug()
158 #define vDebug is_logged(LogLevel::INFO) && VDEBUG_LOG(LogLevel::INFO)
159 #define vWarning is_logged(LogLevel::WARN) && VDEBUG_LOG(LogLevel::WARN)
160 #define vCritical is_logged(LogLevel::CRIT) && VDEBUG_LOG(LogLevel::CRIT)