Blender V5.0
log.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "util/defines.h"
8#include "util/string.h"
9#include "util/types.h"
10
11#include <sstream>
12
14
15/* Log Levels */
16
18 LOG_LEVEL_FATAL = 0, /* Fatal error, application will abort */
19 LOG_LEVEL_DFATAL = 1, /* Fatal error in debug build only */
20 LOG_LEVEL_ERROR = 2, /* Error */
21 LOG_LEVEL_DERROR = 3, /* Error in debug build only */
22 LOG_LEVEL_WARNING = 4, /* Warning */
23 LOG_LEVEL_DWARNING = 5, /* Warning in debug build only */
24 LOG_LEVEL_INFO_IMPORTANT = 6, /* Important info that is printed by default */
25 LOG_LEVEL_INFO = 7, /* Info about devices, scene contents and features used. */
26 LOG_LEVEL_DEBUG = 8, /* Work being performed and timing/memory stats about that work. */
27 LOG_LEVEL_TRACE = 9, /* Verbose debug messages, to trace code being executed. */
29};
30
31const char *log_level_to_string(const LogLevel level);
32LogLevel log_string_to_level(const string &str);
33
34/* Log Configuration API
35 *
36 * By default will print to stdout and stderr, but a custom log function can be set
37 * to change this behavior. */
38
39using LogFunction = void (*)(const LogLevel level,
40 const char *file_line,
41 const char *func,
42 const char *msg);
43
44void log_init(const LogFunction func = nullptr);
45void log_level_set(const LogLevel level);
46void log_level_set(const string &level);
47
48/* Internal logging API */
49
50void _log_message(const LogLevel level, const char *file_line, const char *func, const char *msg);
51
53 public:
54 LogMessage(enum LogLevel level, const char *file_line, const char *func)
55 : level_(level), file_line_(file_line), func_(func)
56 {
57 }
58
60 {
61 _log_message(level_, file_line_, func_, stream_.str().c_str());
62 }
63
64 std::ostream &stream()
65 {
66 return stream_;
67 }
68
69 protected:
71 const char *file_line_;
72 const char *func_;
73 std::stringstream stream_;
74};
75
76extern LogLevel LOG_LEVEL;
77
78#define LOG_STRINGIFY_APPEND(a, b) "" a #b
79#define LOG_STRINGIFY(x) LOG_STRINGIFY_APPEND("", x)
80
81/* Macro to ensure lazy evaluation of both condition and logging text. */
82#ifdef NDEBUG
83# define LOG_IF(level, condition) \
84 if constexpr (level != LOG_LEVEL_DFATAL && level != LOG_LEVEL_DERROR && \
85 level != LOG_LEVEL_DWARNING) \
86 if (UNLIKELY(level <= LOG_LEVEL && (condition))) \
87 LogMessage(level, __FILE__ ":" LOG_STRINGIFY(__LINE__), __func__).stream()
88#else
89# define LOG_IF(level, condition) \
90 if (UNLIKELY(level <= LOG_LEVEL && (condition))) \
91 LogMessage(level, __FILE__ ":" LOG_STRINGIFY(__LINE__), __func__).stream()
92#endif
93
94/* Log a message at the desired level.
95 *
96 * Example: LOG_INFO << "This is a log message"; */
97#define LOG(level) LOG_IF(level, true)
98
99#define LOG_FATAL LOG(LOG_LEVEL_FATAL)
100#define LOG_DFATAL LOG(LOG_LEVEL_DFATAL)
101#define LOG_ERROR LOG(LOG_LEVEL_ERROR)
102#define LOG_DERROR LOG(LOG_LEVEL_DERROR)
103#define LOG_WARNING LOG(LOG_LEVEL_WARNING)
104#define LOG_DWARNING LOG(LOG_LEVEL_DWARNING)
105#define LOG_INFO_IMPORTANT LOG(LOG_LEVEL_INFO_IMPORTANT)
106#define LOG_INFO LOG(LOG_LEVEL_INFO)
107#define LOG_DEBUG LOG(LOG_LEVEL_DEBUG)
108#define LOG_TRACE LOG(LOG_LEVEL_TRACE)
109
110/* Check if logging is enabled, to avoid doing expensive work to compute
111 * the logging message. Note that any work to the right of LOG(level) will
112 * not be evaulated if logging for that level is disabled. */
113#define LOG_IS_ON(level) ((level) <= LOG_LEVEL)
114
115/* Check if expression and conditions hold true, failure will exit the program. */
116#define CHECK(expression) LOG_IF(LOG_LEVEL_FATAL, !(expression))
117#define CHECK_OP(op, a, b) LOG_IF(LOG_LEVEL_FATAL, !((a)op(b)))
118#define CHECK_GE(a, b) CHECK_OP(>=, a, b)
119#define CHECK_NE(a, b) CHECK_OP(!=, a, b)
120#define CHECK_EQ(a, b) CHECK_OP(==, a, b)
121#define CHECK_GT(a, b) CHECK_OP(>, a, b)
122#define CHECK_LT(a, b) CHECK_OP(<, a, b)
123#define CHECK_LE(a, b) CHECK_OP(<=, a, b)
124
125/* Same checks for expressions and conditions, but only active in debug builds. */
126#ifndef NDEBUG
127template<typename T> T DCheckNotNull(T &&t, const char *expression)
128{
129 if (t == nullptr) {
130 LOG_FATAL << "Failed " << expression << "is not null";
131 }
132 return std::forward<T>(t);
133}
134
135# define DCHECK(expression) \
136 LOG_IF(LOG_LEVEL_DFATAL, !(expression)) << LOG_STRINGIFY(expression) << " "
137# define DCHECK_NOTNULL(expression) DCheckNotNull(expression, LOG_STRINGIFY(expression))
138# define DCHECK_OP(op, a, b) \
139 LOG_IF(LOG_LEVEL_DFATAL, !((a)op(b))) \
140 << "Failed " << LOG_STRINGIFY(a) << " (" << a << ") " << LOG_STRINGIFY(op) << " " \
141 << LOG_STRINGIFY(b) << " (" << b << ") "
142# define DCHECK_GE(a, b) DCHECK_OP(>=, a, b)
143# define DCHECK_NE(a, b) DCHECK_OP(!=, a, b)
144# define DCHECK_EQ(a, b) DCHECK_OP(==, a, b)
145# define DCHECK_GT(a, b) DCHECK_OP(>, a, b)
146# define DCHECK_LT(a, b) DCHECK_OP(<, a, b)
147# define DCHECK_LE(a, b) DCHECK_OP(<=, a, b)
148#else
149# define LOG_SUPPRESS() LOG_IF(LOG_LEVEL_TRACE, false)
150# define DCHECK(expression) LOG_SUPPRESS()
151# define DCHECK_NOTNULL(expression) (expression)
152# define DCHECK_GE(a, b) LOG_SUPPRESS()
153# define DCHECK_NE(a, b) LOG_SUPPRESS()
154# define DCHECK_EQ(a, b) LOG_SUPPRESS()
155# define DCHECK_GT(a, b) LOG_SUPPRESS()
156# define DCHECK_LT(a, b) LOG_SUPPRESS()
157# define DCHECK_LE(a, b) LOG_SUPPRESS()
158#endif
159
160/* Convenient logging of common data structures. */
161struct int2;
162struct float3;
163struct float4;
164
165std::ostream &operator<<(std::ostream &os, const int2 &value);
166std::ostream &operator<<(std::ostream &os, const float3 &value);
167std::ostream &operator<<(std::ostream &os, const float4 &value);
168
std::ostream & stream()
Definition log.h:64
std::stringstream stream_
Definition log.h:73
const char * file_line_
Definition log.h:71
LogLevel level_
Definition log.h:70
~LogMessage()
Definition log.h:59
LogMessage(enum LogLevel level, const char *file_line, const char *func)
Definition log.h:54
const char * func_
Definition log.h:72
#define CCL_NAMESPACE_END
#define str(s)
CCL_NAMESPACE_BEGIN LogLevel LOG_LEVEL
Definition log.cpp:17
std::ostream & operator<<(std::ostream &os, const int2 &value)
Definition log.cpp:131
void _log_message(const LogLevel level, const char *file_line, const char *func, const char *msg)
Definition log.cpp:104
LogLevel log_string_to_level(const string &str)
Definition log.cpp:47
void log_init(const LogFunction func=nullptr)
Definition log.cpp:72
T DCheckNotNull(T &&t, const char *expression)
Definition log.h:127
#define LOG_FATAL
Definition log.h:99
LogLevel
Definition log.h:17
@ LOG_LEVEL_DERROR
Definition log.h:21
@ LOG_LEVEL_INFO_IMPORTANT
Definition log.h:24
@ LOG_LEVEL_DEBUG
Definition log.h:26
@ LOG_LEVEL_ERROR
Definition log.h:20
@ LOG_LEVEL_WARNING
Definition log.h:22
@ LOG_LEVEL_FATAL
Definition log.h:18
@ LOG_LEVEL_TRACE
Definition log.h:27
@ LOG_LEVEL_UNKNOWN
Definition log.h:28
@ LOG_LEVEL_DFATAL
Definition log.h:19
@ LOG_LEVEL_INFO
Definition log.h:25
@ LOG_LEVEL_DWARNING
Definition log.h:23
void log_level_set(const LogLevel level)
Definition log.cpp:78
const char * log_level_to_string(const LogLevel level)
Definition log.cpp:21
void(*)(const LogLevel level, const char *file_line, const char *func, const char *msg) LogFunction
Definition log.h:39
#define T