AVPKit
Logger.h
1 /*******************************************************************************
2  * Copyright (c) 2024, 2026, Olivier Ayache. All rights reserved.
3  *
4  * This file is part of AVPKit.
5  *
6  * AVPKit is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * AVPKit is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with AVPKit. If not, see <http://www.gnu.org/licenses/>.
18  *******************************************************************************/
19 
20 #ifndef LOGGER_H_
21 #define LOGGER_H_
22 
23 #include <cstdarg>
24 
25 #ifdef VS_DEBUG
26 #include <assert.h>
27 #endif // VS_DEBUG
28 
29 #include <com/avpkit/ferry/Ferry.h>
30 #include <com/avpkit/ferry/Mutex.h>
31 
32 namespace com { namespace avpkit { namespace ferry {
47  class VS_API_FERRY Logger
48  {
49  public:
53  typedef enum Level
54  {
55  LEVEL_ERROR=0,
56  LEVEL_WARN=1,
57  LEVEL_INFO=2,
58  LEVEL_DEBUG=3,
59  LEVEL_TRACE=4
60  } Level;
61 
69  static Logger* getLogger(const char *aLoggerName);
70 
81  static Logger* getStaticLogger(const char *aLoggerName);
82 
94  bool log(const char* filename, int lineNo, Level level, const char *format, ...);
95 #ifndef SWIG // SWIG shouldn't know about this.
96  bool logVA(const char* filename, int lineNo, Level level, const char *format, va_list ap);
97 #endif // SWIG
98  /*
99  * A series of convenience methods that model the slf4j
100  * API
101  */
102  bool error(const char* filename, int lineNo,const char* format, ...);
103  bool warn(const char* filename, int lineNo, const char* format, ...);
104  bool info(const char* filename, int lineNo, const char* format, ...);
105  bool debug(const char* filename, int lineNo, const char* format, ...);
106  bool trace(const char* filename, int lineNo, const char* format, ...);
107 
108 
109  bool isLogging(Level level);
110  void setIsLogging(Level level, bool value);
111  static bool isGlobalLogging(Level level);
112  static void setGlobalIsLogging(Level level, bool value);
113  const char * getName();
114 
115  virtual ~Logger();
116 
117  protected:
118  Logger(const char* loggerName, jobject aJavaLogger);
119  private:
120  static bool init();
121  static void initJavaBindings(JavaVM* vm, void* closure);
122  static bool mInitialized;
123  static void shutdownJavaBindings(JavaVM* vm, void* closure);
124  // This is the maximum size of a log message. If
125  // needed, someone should eventually reimplement this with
126  // the right buffer-growth stuff, and with thread-safe
127  // semantics, but for now, this implementation just allocates
128  // this buffer on the stack before handing off to Java/stdio.
129  static const int cMaxLogMessageLength=16384;
130  static const int cMaxLoggerNameLength=255;
131  char mLoggerName[cMaxLoggerNameLength+1];
132  bool mIsLogging[5];
133 
134  bool doLog(Level level, const char*msg);
135  bool doNativeLog(Level level, const char *msg);
136  bool doJavaLog(Level level, const char* msg);
137 
138  jobject mJavaLogger;
139  static jclass mClass;
140  static jmethodID mGetLoggerMethod;
141  static jmethodID mLogMethod;
142 
143  static Mutex *mClassMutex;
144  static bool mGlobalIsLogging[5];
145  };
146 }}}
147 
148 /*
149  * Now, for the wackly logging convenience macros
150  */
151 #ifndef VS_CPP_PACKAGE
152 #define VS_CPP_PACKAGE native.__FILE
153 #endif // ! VS_CPP_PACKAGE
154 
155 /*
156  * To use this, put the following at the top of your CPP file:
157  *
158  * <code>
159  * VS_LOG_SETUP(VS_CPP_PACKAGE);
160  * </code>
161  *
162  * Then, you can use any of these macros anywhere in the file to
163  * log:
164  *
165  * <code>
166  * VS_LOG_ERROR("an example: %s", aStringVariable);
167  * </code>
168  *
169  * IMPORTANT NOTE: These macros use "Variadic Macros" which are
170  * not guaranteed to work on all compilers, but work on our
171  * set of GCC 4.x, Visual Studio 2005+.
172  * See http://en.wikipedia.org/wiki/Variadic_macro
173  *
174  */
175 #define VS_TOSTRING( S ) #S
176 
177 #define VS_LOG_SETUP( LOGGERNAME ) \
178  static com::avpkit::ferry::Logger* vs_logger_static_context( \
179  com::avpkit::ferry::Logger::getStaticLogger( VS_TOSTRING( LOGGERNAME ) ) )
180 
181 #define VS_LOG_ERROR(...) \
182  (void) vs_logger_static_context->error(__FILE__, __LINE__, __VA_ARGS__)
183 
184 #define VS_LOG_WARN(...) \
185  (void) vs_logger_static_context->warn(__FILE__, __LINE__, __VA_ARGS__)
186 
187 #define VS_LOG_INFO(...) \
188  (void) vs_logger_static_context->info(__FILE__, __LINE__, __VA_ARGS__)
189 
190 #define VS_LOG_DEBUG(...) \
191  (void) vs_logger_static_context->debug(__FILE__, __LINE__, __VA_ARGS__)
192 
193 #define VS_LOG_TRACE(...) \
194  (void) vs_logger_static_context->trace(__FILE__, __LINE__, __VA_ARGS__)
195 
196 #ifdef VS_DEBUG
197 #define VS_ASSERT( expr , msg ) \
198  do { \
199  if ( ! ( expr ) ) {\
200  VS_LOG_ERROR("!!!ASSERTION FAILED!!! \"" VS_TOSTRING (expr) "\" with message \"%s\"", msg); \
201  } \
202  assert(expr); \
203  } while (0)
204 #else
205 // don't insert anything if we're not debugging
206 #define VS_ASSERT( expr, msg ) (void) vs_logger_static_context;
207 #endif // VS_DEBUG
208 
209 /*
210  * Now, some logic to turn logging off on the compile line if needed.
211  *
212  * You can define the following on the compiler command line. The
213  * most conservative definition will win.
214  *
215  * VS_LOG_LOGLEVELS_NONE : no log messages get compiled in.
216  * VS_LOG_LOGLEVELS_ERROR : only ERROR messages get compiled in.
217  * VS_LOG_LOGLEVELS_WARN : only ERROR and WARN messages get compiled in.
218  * VS_LOG_LOGLEVELS_INFO : ERROR, WARN and INFO messages get compiled in.
219  * VS_LOG_LOGLEVELS_DEBUG: ERROR, WARN, INFO and Debug messages get compiled in.
220  * VS_LOG_LEVLEVELS_ALL: All debug messages get compiled in.
221  * none of these terms on CC line: All debug messages get compiled in.
222  */
223 #ifdef VS_LOG_LOGLEVELS_NONE
224 #undef VS_LOG_ERROR
225 #undef VS_LOG_WARN
226 #undef VS_LOG_INFO
227 #undef VS_LOG_DEBUG
228 #undef VS_LOG_TRACE
229 #define VS_LOG_ERROR(...) do {} while(0)
230 #define VS_LOG_WARN(...) do {} while(0)
231 #define VS_LOG_INFO(...) do {} while(0)
232 #define VS_LOG_DEBUG(...) do {} while(0)
233 #define VS_LOG_TRACE(...) do {} while(0)
234 #else
235 #ifdef VS_LOG_LOGLEVELS_ERROR
236 #undef VS_LOG_WARN
237 #undef VS_LOG_INFO
238 #undef VS_LOG_DEBUG
239 #undef VS_LOG_TRACE
240 #define VS_LOG_WARN(...) do {} while(0)
241 #define VS_LOG_INFO(...) do {} while(0)
242 #define VS_LOG_DEBUG(...) do {} while(0)
243 #define VS_LOG_TRACE(...) do {} while(0)
244 #else
245 #ifdef VS_LOG_LOGLEVELS_WARN
246 #undef VS_LOG_INFO
247 #undef VS_LOG_DEBUG
248 #undef VS_LOG_TRACE
249 #define VS_LOG_INFO(...) do {} while(0)
250 #define VS_LOG_DEBUG(...) do {} while(0)
251 #define VS_LOG_TRACE(...) do {} while(0)
252 #else
253 #ifdef VS_LOG_LOGLEVELS_INFO
254 #undef VS_LOG_DEBUG
255 #undef VS_LOG_TRACE
256 #define VS_LOG_DEBUG(...) do {} while(0)
257 #define VS_LOG_TRACE(...) do {} while(0)
258 #else
259 #ifdef VS_LOG_LOGLEVELS_DEBUG
260 #undef VS_LOG_TRACE
261 #define VS_LOG_TRACE(...) do {} while(0)
262 #else
263 #ifdef VS_LOG_LOGLEVELS_ALL
264 #else
265 #ifndef VS_DEBUG
266 #undef VS_LOG_TRACE
267 #define VS_LOG_TRACE(...) do {} while(0)
268 #endif // ! VS_DEBUG
269 #endif // VS_LOG_LOGLEVELS_ALL
270 #endif // VS_LOG_LOGLEVELS_DEBUG
271 #endif // VS_LOG_LOGLEVELS_INFO
272 #endif // VS_LOG_LOGLEVELS_WARN
273 #endif // VS_LOG_LOGLEVELS_ERROR
274 #endif // VS_LOG_LOGLEVELS_NONE
275 
276 #endif /*LOGGER_H_*/
Internal Only.
Definition: Logger.h:48
Level
Different logging levels (noiseness) supported by us.
Definition: Logger.h:54
Internal Only.
Definition: Mutex.h:41
WARNING: Do not use logging in this class, and do not set any static file variables to values other t...