log.h 2.12 KB
Newer Older
Guolin Ke's avatar
Guolin Ke committed
1
2
3
4
5
6
7
8
9
10
11
#ifndef LIGHTGBM_UTILS_LOG_H_
#define LIGHTGBM_UTILS_LOG_H_

#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <cstring>

namespace LightGBM {


Qiwei Ye's avatar
Qiwei Ye committed
12
13
14
15
#ifndef CHECK
#define CHECK(condition)                                   \
  if (!(condition)) Log::Fatal("Check failed: " #condition \
     " at %s, line %d .\n", __FILE__,  __LINE__);
Guolin Ke's avatar
Guolin Ke committed
16
#endif
Qiwei Ye's avatar
Qiwei Ye committed
17
18
19

#ifndef CHECK_NOTNULL
#define CHECK_NOTNULL(pointer)                             \
20
  if ((pointer) == nullptr) LightGBM::Log::Fatal(#pointer " Can't be NULL");
Guolin Ke's avatar
Guolin Ke committed
21
#endif
Qiwei Ye's avatar
Qiwei Ye committed
22

Guolin Ke's avatar
Guolin Ke committed
23

Guolin Ke's avatar
Guolin Ke committed
24
25
enum class LogLevel: int {
  Fatal = -1,
Qiwei Ye's avatar
Qiwei Ye committed
26
  Warning = 0,
Qiwei Ye's avatar
Qiwei Ye committed
27
  Info = 1,
Guolin Ke's avatar
Guolin Ke committed
28
  Debug = 2,
Guolin Ke's avatar
Guolin Ke committed
29
30
};

Qiwei Ye's avatar
Qiwei Ye committed
31
32

/*!
Guolin Ke's avatar
Guolin Ke committed
33
* \brief A static Log class 
Qiwei Ye's avatar
Qiwei Ye committed
34
35
36
37
38
39
40
*/
class Log {
public:
  /*!
  * \brief Resets the minimal log level. It is INFO by default.
  * \param level The new minimal log level.
  */
Guolin Ke's avatar
Guolin Ke committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  static void ResetLogLevel(LogLevel level) {
    GetLevel() = level;
  }

  static void Debug(const char *format, ...) {
    va_list val;
    va_start(val, format);
    Write(LogLevel::Debug, "Debug", format, val);
    va_end(val);
  }
  static void Info(const char *format, ...) {
    va_list val;
    va_start(val, format);
    Write(LogLevel::Info, "Info", format, val);
    va_end(val);
  }
Qiwei Ye's avatar
Qiwei Ye committed
57
  static void Warning(const char *format, ...) {
Guolin Ke's avatar
Guolin Ke committed
58
59
    va_list val;
    va_start(val, format);
Qiwei Ye's avatar
Qiwei Ye committed
60
    Write(LogLevel::Warning, "Warning", format, val);
Guolin Ke's avatar
Guolin Ke committed
61
62
63
64
65
    va_end(val);
  }
  static void Fatal(const char *format, ...) {
    va_list val;
    va_start(val, format);
wxchan's avatar
wxchan committed
66
    fprintf(stderr, "[LightGBM] [Fatal] ");
67
68
69
    vfprintf(stderr, format, val);
    fprintf(stderr, "\n");
    fflush(stderr);
Guolin Ke's avatar
Guolin Ke committed
70
    va_end(val);
71
    exit(1);
Guolin Ke's avatar
Guolin Ke committed
72
  }
Qiwei Ye's avatar
Qiwei Ye committed
73
74

private:
Guolin Ke's avatar
Guolin Ke committed
75
76
77
78
79
80

  static void Write(LogLevel level, const char* level_str, const char *format, va_list val) {
    if (level <= GetLevel()) {  // omit the message with low level
      // write to STDOUT
      printf("[LightGBM] [%s] ", level_str);
      vprintf(format, val);
81
      printf("\n");
Guolin Ke's avatar
Guolin Ke committed
82
83
84
85
86
87
      fflush(stdout);
    }
  }

  // a trick to use static variable in header file. 
  // May be not good, but avoid to use an additional cpp file
xuehui's avatar
xuehui committed
88
89
  static LogLevel& GetLevel() { static LogLevel level; return level; }
  
Qiwei Ye's avatar
Qiwei Ye committed
90
};
Guolin Ke's avatar
Guolin Ke committed
91
92

}  // namespace LightGBM
Guolin Ke's avatar
Guolin Ke committed
93
#endif   // LightGBM_UTILS_LOG_H_