log.h 2.65 KB
Newer Older
1
2
3
4
/*!
 * Copyright (c) 2016 Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See LICENSE file in the project root for license information.
 */
Guolin Ke's avatar
Guolin Ke committed
5
6
7
#ifndef LIGHTGBM_UTILS_LOG_H_
#define LIGHTGBM_UTILS_LOG_H_

8
9
#include <string>
#include <cstdarg>
Guolin Ke's avatar
Guolin Ke committed
10
11
12
#include <cstdio>
#include <cstdlib>
#include <cstring>
13
#include <exception>
14
#include <iostream>
15
#include <stdexcept>
Guolin Ke's avatar
Guolin Ke committed
16
17
18

namespace LightGBM {

19
#if defined(_MSC_VER)
20
#define THREAD_LOCAL __declspec(thread)
21
22
23
#else
#define THREAD_LOCAL thread_local
#endif
Guolin Ke's avatar
Guolin Ke committed
24

Qiwei Ye's avatar
Qiwei Ye committed
25
26
27
28
#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
29
#endif
Qiwei Ye's avatar
Qiwei Ye committed
30
31
32

#ifndef CHECK_NOTNULL
#define CHECK_NOTNULL(pointer)                             \
Guolin Ke's avatar
Guolin Ke committed
33
  if ((pointer) == nullptr) LightGBM::Log::Fatal(#pointer " Can't be NULL at %s, line %d .\n", __FILE__,  __LINE__);
Guolin Ke's avatar
Guolin Ke committed
34
#endif
Qiwei Ye's avatar
Qiwei Ye committed
35

Guolin Ke's avatar
Guolin Ke committed
36

Guolin Ke's avatar
Guolin Ke committed
37
38
enum class LogLevel: int {
  Fatal = -1,
Qiwei Ye's avatar
Qiwei Ye committed
39
  Warning = 0,
Qiwei Ye's avatar
Qiwei Ye committed
40
  Info = 1,
Guolin Ke's avatar
Guolin Ke committed
41
  Debug = 2,
Guolin Ke's avatar
Guolin Ke committed
42
43
};

Qiwei Ye's avatar
Qiwei Ye committed
44
45

/*!
46
* \brief A static Log class
Qiwei Ye's avatar
Qiwei Ye committed
47
48
*/
class Log {
Nikita Titov's avatar
Nikita Titov committed
49
 public:
Qiwei Ye's avatar
Qiwei Ye committed
50
51
52
53
  /*!
  * \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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  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
70
  static void Warning(const char *format, ...) {
Guolin Ke's avatar
Guolin Ke committed
71
72
    va_list val;
    va_start(val, format);
Qiwei Ye's avatar
Qiwei Ye committed
73
    Write(LogLevel::Warning, "Warning", format, val);
Guolin Ke's avatar
Guolin Ke committed
74
75
76
77
    va_end(val);
  }
  static void Fatal(const char *format, ...) {
    va_list val;
78
    char str_buf[1024];
Guolin Ke's avatar
Guolin Ke committed
79
    va_start(val, format);
80
81
82
83
84
#ifdef _MSC_VER
    vsprintf_s(str_buf, format, val);
#else
    vsprintf(str_buf, format, val);
#endif
Guolin Ke's avatar
Guolin Ke committed
85
    va_end(val);
Guolin Ke's avatar
Guolin Ke committed
86
87
    fprintf(stderr, "[LightGBM] [Fatal] %s\n", str_buf);
    fflush(stderr);
88
    throw std::runtime_error(std::string(str_buf));
Guolin Ke's avatar
Guolin Ke committed
89
  }
Qiwei Ye's avatar
Qiwei Ye committed
90

Nikita Titov's avatar
Nikita Titov committed
91
 private:
Guolin Ke's avatar
Guolin Ke committed
92
93
94
95
96
  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);
97
      printf("\n");
Guolin Ke's avatar
Guolin Ke committed
98
99
100
101
      fflush(stdout);
    }
  }

102
  // a trick to use static variable in header file.
Guolin Ke's avatar
Guolin Ke committed
103
  // May be not good, but avoid to use an additional cpp file
104
  static LogLevel& GetLevel() { static THREAD_LOCAL LogLevel level = LogLevel::Info; return level; }
Qiwei Ye's avatar
Qiwei Ye committed
105
};
Guolin Ke's avatar
Guolin Ke committed
106
107

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