tlog.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * tinylog
  3. * Copyright (C) 2018-2021 Ruilin Peng (Nick) <[email protected]>
  4. * https://github.com/pymumu/tinylog
  5. */
  6. #ifndef TLOG_H
  7. #define TLOG_H
  8. #include <stdarg.h>
  9. #include <sys/stat.h>
  10. #include <sys/types.h>
  11. #ifdef __cplusplus
  12. #include <functional>
  13. #include <iostream>
  14. #include <memory>
  15. #include <sstream>
  16. #include <string>
  17. extern "C" {
  18. #endif /*__cplusplus */
  19. typedef enum {
  20. TLOG_DEBUG = 0,
  21. TLOG_INFO = 1,
  22. TLOG_NOTICE = 2,
  23. TLOG_WARN = 3,
  24. TLOG_ERROR = 4,
  25. TLOG_FATAL = 5,
  26. TLOG_END = 6
  27. } tlog_level;
  28. struct tlog_time {
  29. int year;
  30. unsigned int usec;
  31. unsigned char mon;
  32. unsigned char mday;
  33. unsigned char hour;
  34. unsigned char min;
  35. unsigned char sec;
  36. } __attribute__((packed));
  37. #ifndef TLOG_MAX_LINE_LEN
  38. #define TLOG_MAX_LINE_LEN (1024)
  39. #endif
  40. /* TLOG FLAGS LIST */
  41. /* set tlog not compress file when archive */
  42. #define TLOG_NOCOMPRESS (1 << 0)
  43. /* Set the segmentation mode to process the log, Used by the callback function to return a full log*/
  44. #define TLOG_SEGMENT (1 << 1)
  45. /*
  46. multiwrite: enable multi process write mode.
  47. NOTICE: maxlogsize in all processes must be same when enable this mode.
  48. */
  49. #define TLOG_MULTI_WRITE (1 << 2)
  50. /* Not Block if buffer is insufficient. */
  51. #define TLOG_NONBLOCK (1 << 3)
  52. /* enable log to screen */
  53. #define TLOG_SCREEN (1 << 4)
  54. /* enable support fork process */
  55. #define TLOG_SUPPORT_FORK (1 << 5)
  56. struct tlog_loginfo {
  57. tlog_level level;
  58. const char *file;
  59. const char *func;
  60. int line;
  61. struct tlog_time time;
  62. } __attribute__((packed));
  63. /*
  64. Function: Print log
  65. level: Current log Levels
  66. format: Log formats
  67. */
  68. #ifndef BASE_FILE_NAME
  69. #define BASE_FILE_NAME \
  70. (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 \
  71. : __FILE__)
  72. #endif
  73. #define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, NULL, format, ##__VA_ARGS__)
  74. extern int tlog_ext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, ...)
  75. __attribute__((format(printf, 6, 7))) __attribute__((nonnull(6)));
  76. extern int tlog_vext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, va_list ap);
  77. /* write buff to log file */
  78. extern int tlog_write_log(char *buff, int bufflen);
  79. /* set log level */
  80. extern int tlog_setlevel(tlog_level level);
  81. /* is log level enabled*/
  82. extern int tlog_log_enabled(tlog_level level);
  83. /* get log level */
  84. extern tlog_level tlog_getlevel(void);
  85. /* set log file */
  86. extern void tlog_set_logfile(const char *logfile);
  87. /* enable log to screen */
  88. extern void tlog_setlogscreen(int enable);
  89. /* enable early log to screen */
  90. extern void tlog_set_early_printf(int enable);
  91. /* Get log level in string */
  92. extern const char *tlog_get_level_string(tlog_level level);
  93. /* set max log count */
  94. extern void tlog_set_maxlog_count(int count);
  95. /*
  96. Function: Initialize log module
  97. logfile: log file.
  98. maxlogsize: The maximum size of a single log file.
  99. maxlogcount: Number of archived logs.
  100. buffsize: Buffer size, zero for default (128K)
  101. flag: read tlog flags
  102. */
  103. extern int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag);
  104. /* flush pending log message, and exit tlog */
  105. extern void tlog_exit(void);
  106. /*
  107. customize log output format
  108. steps:
  109. 1. define format function, function must be defined as tlog_format_func, use snprintf or vsnprintf format log to buffer
  110. 2. call tlog_reg_format_func to register format function.
  111. read _tlog_format for example.
  112. */
  113. typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_loginfo *info, void *userptr, const char *format, va_list ap);
  114. extern int tlog_reg_format_func(tlog_format_func func);
  115. /* register log output callback
  116. Note: info is invalid when flag TLOG_SEGMENT is not set.
  117. */
  118. typedef int (*tlog_log_output_func)(struct tlog_loginfo *info, const char *buff, int bufflen, void *private_data);
  119. extern int tlog_reg_log_output_func(tlog_log_output_func output, void *private_data);
  120. struct tlog_log;
  121. typedef struct tlog_log tlog_log;
  122. /* get root log handler */
  123. extern tlog_log *tlog_get_root(void);
  124. /*
  125. Function: open a new log stream, handler should close by tlog_close
  126. logfile: log file.
  127. maxlogsize: The maximum size of a single log file.
  128. maxlogcount: Number of archived logs.
  129. buffsize: Buffer size, zero for default (128K)
  130. flag: read tlog flags
  131. return: log stream handler.
  132. */
  133. extern tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag);
  134. /* write buff to log file */
  135. extern int tlog_write(struct tlog_log *log, const char *buff, int bufflen);
  136. /* close log stream */
  137. extern void tlog_close(tlog_log *log);
  138. /* change log file */
  139. extern void tlog_rename_logfile(struct tlog_log *log, const char *logfile);
  140. /*
  141. Function: Print log to log stream
  142. log: log stream
  143. format: Log formats
  144. */
  145. extern int tlog_printf(tlog_log *log, const char *format, ...) __attribute__((format(printf, 2, 3))) __attribute__((nonnull(1, 2)));
  146. /*
  147. Function: Print log to log stream with ap
  148. log: log stream
  149. format: Log formats
  150. va_list: args list
  151. */
  152. extern int tlog_vprintf(tlog_log *log, const char *format, va_list ap);
  153. /* enable log to screen */
  154. extern void tlog_logscreen(tlog_log *log, int enable);
  155. /* register output callback */
  156. typedef int (*tlog_output_func)(struct tlog_log *log, const char *buff, int bufflen);
  157. extern int tlog_reg_output_func(tlog_log *log, tlog_output_func output);
  158. /* set private data */
  159. extern void tlog_set_private(tlog_log *log, void *private_data);
  160. /* get private data */
  161. extern void *tlog_get_private(tlog_log *log);
  162. /* get local time */
  163. extern int tlog_localtime(struct tlog_time *tm);
  164. /* set max line size */
  165. extern void tlog_set_maxline_size(struct tlog_log *log, int size);
  166. /* set max log count */
  167. extern void tlog_logcount(struct tlog_log *log, int count);
  168. /*
  169. Function: set log file and archive permission
  170. log: log stream
  171. file: log file permission, default is 640
  172. archive: archive file permission, default is 440
  173. */
  174. extern void tlog_set_permission(struct tlog_log *log, mode_t file, mode_t archive);
  175. #ifdef __cplusplus
  176. class Tlog {
  177. public:
  178. Tlog(tlog_level level, const char *file, int line, const char *func, void *userptr)
  179. {
  180. level_ = level;
  181. file_ = file;
  182. line_ = line;
  183. func_ = func;
  184. userptr_ = userptr;
  185. }
  186. ~Tlog()
  187. {
  188. tlog_ext(level_, file_, line_, func_, userptr_, "%s", msg_.str().c_str());
  189. }
  190. std::ostream &Stream()
  191. {
  192. return msg_;
  193. }
  194. private:
  195. tlog_level level_;
  196. const char *file_;
  197. int line_;
  198. const char *func_;
  199. void *userptr_;
  200. std::ostringstream msg_;
  201. };
  202. class TlogOut {
  203. public:
  204. TlogOut(tlog_log *log)
  205. {
  206. log_ = log;
  207. }
  208. ~TlogOut()
  209. {
  210. if (log_ == nullptr) {
  211. return;
  212. }
  213. tlog_printf(log_, "%s", msg_.str().c_str());
  214. }
  215. std::ostream &Stream()
  216. {
  217. return msg_;
  218. }
  219. private:
  220. tlog_log *log_;
  221. std::ostringstream msg_;
  222. };
  223. #define Tlog_stream(level) \
  224. if (tlog_getlevel() <= level) \
  225. Tlog(level, BASE_FILE_NAME, __LINE__, __func__, NULL).Stream()
  226. #define tlog_debug Tlog_stream(TLOG_DEBUG)
  227. #define tlog_info Tlog_stream(TLOG_INFO)
  228. #define tlog_notice Tlog_stream(TLOG_NOTICE)
  229. #define tlog_warn Tlog_stream(TLOG_WARN)
  230. #define tlog_error Tlog_stream(TLOG_ERROR)
  231. #define tlog_fatal Tlog_stream(TLOG_FATAL)
  232. #define tlog_out(stream) TlogOut(stream).Stream()
  233. } /*__cplusplus */
  234. #else
  235. #define tlog_debug(...) tlog(TLOG_DEBUG, ##__VA_ARGS__)
  236. #define tlog_info(...) tlog(TLOG_INFO, ##__VA_ARGS__)
  237. #define tlog_notice(...) tlog(TLOG_NOTICE, ##__VA_ARGS__)
  238. #define tlog_warn(...) tlog(TLOG_WARN, ##__VA_ARGS__)
  239. #define tlog_error(...) tlog(TLOG_ERROR, ##__VA_ARGS__)
  240. #define tlog_fatal(...) tlog(TLOG_FATAL, ##__VA_ARGS__)
  241. #endif
  242. #endif // !TLOG_H