Essentia  2.1-beta6-dev
debugging.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2021 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Essentia
5  *
6  * Essentia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef ESSENTIA_DEBUGGING_H
21 #define ESSENTIA_DEBUGGING_H
22 
23 #include <deque>
24 #include <string>
25 #include <algorithm> // for std::max
26 #include <climits> // for INT_MAX
27 #include "config.h"
28 #include "streamutil.h"
29 #include "stringutil.h"
30 
31 #ifndef _WIN32
32 #include <unistd.h>
33 #endif
34 
35 namespace essentia {
36 
37 // IMPORTANT:
38 // Make sure that each time you change something in this enum, you reflect the
39 // same changes in the python bindings, located in src/python/essentia/__init__.py
41 
42  EAlgorithm = 1 << 0,
43  EConnectors = 1 << 1,
44  EFactory = 1 << 2,
45  ENetwork = 1 << 3,
46  EGraph = 1 << 4,
47  EExecution = 1 << 5,
48  EMemory = 1 << 6, // for mem operations, such as new/delete
49  EScheduler = 1 << 7,
50 
51  EPython = 1 << 20, // for use in python scripts
52  EPyBindings = 1 << 21, // for use in python/C module
53  EUnittest = 1 << 22,
54 
55  EUser1 = 1 << 25, // freely available for the user
56  EUser2 = 1 << 26, // freely available for the user
57 
58  ENone = 0,
59  EAll = (1 << 30) - 1
60 };
61 
63 
67 extern int activatedDebugLevels;
68 
69 extern bool infoLevelActive;
70 extern bool warningLevelActive;
71 extern bool errorLevelActive;
72 
76 extern int debugIndentLevel;
77 
78 void setDebugLevel(int levels);
79 void unsetDebugLevel(int levels);
80 
83 
84 typedef int DebuggingSchedule[][3];
85 typedef std::vector<std::pair<std::pair<int, int>, int> > DebuggingScheduleVector;
86 
98 void scheduleDebug(DebuggingSchedule schedule, int nentries);
99 void scheduleDebug(const DebuggingScheduleVector& schedule);
100 
106 
110 class Logger {
111  protected:
112  std::deque<std::string> _msgQueue;
114 
115  void flush();
116 
117  std::string GREEN_FONT;
118  std::string YELLOW_FONT;
119  std::string RED_FONT;
120  std::string RESET_FONT;
121 
122  public:
123  Logger() : _addHeader(true) {
124  #ifndef _WIN32
125  if(isatty(2)) { // no colors if stderr is not a terminal
126  GREEN_FONT = "\x1B[0;32m";
127  YELLOW_FONT = "\x1B[0;33m";
128  RED_FONT = "\x1B[0;31m";
129  RESET_FONT = "\x1B[0m";
130  }
131  #endif
132  }
133 
134  void debug(DebuggingModule module, const std::string& msg, bool resetHeader = false);
135  void info(const std::string& msg);
136  void warning(const std::string& msg);
137  void error(const std::string& msg);
138 
139 };
140 
141 extern Logger loggerInstance;
142 
143 } // namespace essentia
144 
145 
146 #if DEBUGGING_ENABLED
147 
148 # define E_DEBUG_INDENT debugIndentLevel++
149 # define E_DEBUG_OUTDENT debugIndentLevel--
150 
151 # define E_ACTIVE(module) ((module) & activatedDebugLevels)
152 # define E_STRINGIFY(msg) (Stringifier() << msg).str()
153 
154 // the if(E_ACTIVE) is an optimization, it is not necessary but avoids sending
155 // everything to the Stringifier if the debug level is not activated
156 # define E_DEBUG_NONL(module, msg) if (E_ACTIVE(module)) loggerInstance.debug(module, E_STRINGIFY(msg), false)
157 # define E_DEBUG(module, msg) if (E_ACTIVE(module)) loggerInstance.debug(module, E_STRINGIFY(msg << '\n'), true)
158 
159 // NB: the following #define macros only work when used inside one of streaming::Algorithm's methods
160 # define ALGONAME _name << std::string((std::max)(15-(int)_name.size(), 0), ' ') << ": "
161 # define EXEC_DEBUG(msg) E_DEBUG(EExecution, ALGONAME << nProcess << " - " << msg)
162 
163 # define E_INFO(msg) loggerInstance.info(E_STRINGIFY(msg))
164 # define E_WARNING(msg) loggerInstance.warning(E_STRINGIFY(msg))
165 # define E_ERROR(msg) loggerInstance.error(E_STRINGIFY(msg))
166 
167 #else // DEBUGGING_ENABLED
168 
169 # define E_DEBUG_INDENT
170 # define E_DEBUG_OUTDENT
171 # define E_ACTIVE(module) false
172 # define E_STRINGIFY(msg) ""
173 # define E_DEBUG_NONL(module, msg)
174 # define E_DEBUG(module, msg)
175 # define ALGONAME
176 # define EXEC_DEBUG(msg)
177 # define E_INFO(msg)
178 # define E_WARNING(msg)
179 # define E_ERROR(msg)
180 
181 #endif // DEBUGGING_ENABLED
182 
183 
184 
185 #endif // ESSENTIA_DEBUGGING_H
Definition: debugging.h:110
void error(const std::string &msg)
std::string YELLOW_FONT
Definition: debugging.h:118
Logger()
Definition: debugging.h:123
void debug(DebuggingModule module, const std::string &msg, bool resetHeader=false)
std::string GREEN_FONT
Definition: debugging.h:117
void warning(const std::string &msg)
bool _addHeader
Definition: debugging.h:113
std::string RESET_FONT
Definition: debugging.h:120
std::deque< std::string > _msgQueue
Definition: debugging.h:112
void info(const std::string &msg)
std::string RED_FONT
Definition: debugging.h:119
Definition: algorithm.h:28
const char * debugModuleDescription(DebuggingModule module)
void setDebugLevelForTimeIndex(int index)
Logger loggerInstance
int debugIndentLevel
std::vector< std::pair< std::pair< int, int >, int > > DebuggingScheduleVector
Definition: debugging.h:85
int activatedDebugLevels
bool errorLevelActive
bool infoLevelActive
void unsetDebugLevel(int levels)
void scheduleDebug(DebuggingSchedule schedule, int nentries)
int DebuggingSchedule[][3]
Definition: debugging.h:84
void restoreDebugLevels()
DebuggingModule
Definition: debugging.h:40
@ EExecution
Definition: debugging.h:47
@ EMemory
Definition: debugging.h:48
@ EFactory
Definition: debugging.h:44
@ EConnectors
Definition: debugging.h:43
@ EPyBindings
Definition: debugging.h:52
@ ENone
Definition: debugging.h:58
@ EUnittest
Definition: debugging.h:53
@ ENetwork
Definition: debugging.h:45
@ EAll
Definition: debugging.h:59
@ EUser1
Definition: debugging.h:55
@ EPython
Definition: debugging.h:51
@ EAlgorithm
Definition: debugging.h:42
@ EScheduler
Definition: debugging.h:49
@ EUser2
Definition: debugging.h:56
@ EGraph
Definition: debugging.h:46
void setDebugLevel(int levels)
bool warningLevelActive
void saveDebugLevels()