dEngine
Simple 2D C++ game engine
NanoLog.h
Go to the documentation of this file.
1 /*
2 https://github.com/Iyengar111/NanoLog
3 
4 Distributed under the MIT License (MIT)
5 
6  Copyright (c) 2016 Karthik Iyengar
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in the
10 Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished
13 to do so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
19 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
21 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 */
26 
27 #ifndef NANO_LOG_HEADER_GUARD
28 #define NANO_LOG_HEADER_GUARD
29 
30 #include <cstdint>
31 #include <memory>
32 #include <string>
33 #include <iosfwd>
34 #include <type_traits>
35 
36 
42 namespace nanolog
43 {
44  enum class LogLevel : uint8_t { INFO, WARN, CRIT };
45 
47  {
48  public:
49  NanoLogLine(LogLevel level, char const * file, char const * function, uint32_t line);
50  ~NanoLogLine();
51 
52  NanoLogLine(NanoLogLine &&) = default;
53  NanoLogLine& operator=(NanoLogLine &&) = default;
54 
55  void stringify(std::ostream & os);
56 
57  NanoLogLine& operator<<(char arg);
58  NanoLogLine& operator<<(int32_t arg);
59  NanoLogLine& operator<<(uint32_t arg);
60  NanoLogLine& operator<<(int64_t arg);
61  NanoLogLine& operator<<(uint64_t arg);
62  NanoLogLine& operator<<(double arg);
63  NanoLogLine& operator<<(std::string const & arg);
64 
65  template < size_t N >
66  NanoLogLine& operator<<(const char (&arg)[N])
67  {
68  //TODO: Make the console optional
69  printf("%s\n",string_literal_t(arg));
70  encode(string_literal_t(arg));
71  return *this;
72  }
73 
74  template < typename Arg >
75  typename std::enable_if < std::is_same < Arg, char const * >::value, NanoLogLine& >::type
76  operator<<(Arg const & arg)
77  {
78  encode(arg);
79  return *this;
80  }
81 
82  template < typename Arg >
83  typename std::enable_if < std::is_same < Arg, char * >::value, NanoLogLine& >::type
84  operator<<(Arg const & arg)
85  {
86  encode(arg);
87  return *this;
88  }
89 
91  {
92  explicit string_literal_t(char const * s) : m_s(s) {}
93  char const * m_s;
94  };
95 
96  private:
97  char * buffer();
98 
99  template < typename Arg >
100  void encode(Arg arg);
101 
102  template < typename Arg >
103  void encode(Arg arg, uint8_t type_id);
104 
105  void encode(char * arg);
106  void encode(char const * arg);
107  void encode(string_literal_t arg);
108  void encode_c_string(char const * arg, size_t length);
109  void resize_buffer_if_needed(size_t additional_bytes);
110  void stringify(std::ostream & os, char * start, char const * const end);
111 
112  private:
113  size_t m_bytes_used;
115  std::unique_ptr < char [] > m_heap_buffer;
116  char m_stack_buffer[256 - 2 * sizeof(size_t) - sizeof(decltype(m_heap_buffer)) - 8 /* Reserved */];
117  };
118 
119  struct NanoLog
120  {
121  /*
122  * Ideally this should have been operator+=
123  * Could not get that to compile, so here we are...
124  */
125  bool operator==(NanoLogLine &);
126  };
127 
128  void set_log_level(LogLevel level);
129 
130  bool is_logged(LogLevel level);
131 
132 
133  /*
134  * Non guaranteed logging. Uses a ring buffer to hold log lines.
135  * When the ring gets full, the previous log line in the slot will be dropped.
136  * Does not block producer even if the ring buffer is full.
137  * ring_buffer_size_mb - LogLines are pushed into a mpsc ring buffer whose size
138  * is determined by this parameter. Since each LogLine is 256 bytes,
139  * ring_buffer_size = ring_buffer_size_mb * 1024 * 1024 / 256
140  */
142  {
143  NonGuaranteedLogger(uint32_t ring_buffer_size_mb_) : ring_buffer_size_mb(ring_buffer_size_mb_) {}
145  };
146 
147  /*
148  * Provides a guarantee log lines will not be dropped.
149  */
151  {
152  };
153 
154  /*
155  * Ensure initialize() is called prior to any log statements.
156  * log_directory - where to create the logs. For example - "/tmp/"
157  * log_file_name - root of the file name. For example - "nanolog"
158  * This will create log files of the form -
159  * /tmp/nanolog.1.txt
160  * /tmp/nanolog.2.txt
161  * etc.
162  * log_file_roll_size_mb - mega bytes after which we roll to next log file.
163  */
164  void initialize(GuaranteedLogger gl, std::string const & log_directory, std::string const & log_file_name, uint32_t log_file_roll_size_mb);
165  void initialize(NonGuaranteedLogger ngl, std::string const & log_directory, std::string const & log_file_name, uint32_t log_file_roll_size_mb);
166 
167 } // namespace nanolog
168 
169 #define NANO_LOG(LEVEL) nanolog::NanoLog() == nanolog::NanoLogLine(LEVEL, __FILE__, __func__, __LINE__)
170 #define LOG_INFO nanolog::is_logged(nanolog::LogLevel::INFO) && NANO_LOG(nanolog::LogLevel::INFO)
171 #define LOG_WARN nanolog::is_logged(nanolog::LogLevel::WARN) && NANO_LOG(nanolog::LogLevel::WARN)
172 #define LOG_CRIT nanolog::is_logged(nanolog::LogLevel::CRIT) && NANO_LOG(nanolog::LogLevel::CRIT)
173 
174 #endif /* NANO_LOG_HEADER_GUARD */
string_literal_t(char const *s)
Definition: NanoLog.h:92
LogLevel
Definition: NanoLog.h:44
char const * m_s
Definition: NanoLog.h:93
size_t m_bytes_used
Definition: NanoLog.h:113
NonGuaranteedLogger(uint32_t ring_buffer_size_mb_)
Definition: NanoLog.h:143
Namespace consiting of the nanolog logger This logger is a third party application that was added to ...
Definition: NanoLog.h:42
uint32_t ring_buffer_size_mb
Definition: NanoLog.h:144
NanoLogLine & operator<<(const char(&arg)[N])
Definition: NanoLog.h:66
Definition: NanoLog.h:141
Definition: NanoLog.h:150
std::unique_ptr< char [] > m_heap_buffer
Definition: NanoLog.h:115
void initialize(GuaranteedLogger gl, std::string const &log_directory, std::string const &log_file_name, uint32_t log_file_roll_size_mb)
Definition: NanoLog.cpp:692
size_t m_buffer_size
Definition: NanoLog.h:114
void set_log_level(LogLevel level)
Definition: NanoLog.cpp:700
Definition: NanoLog.h:46
Definition: NanoLog.h:119
bool is_logged(LogLevel level)
Definition: NanoLog.cpp:705