argos_log.h
Go to the documentation of this file.
1 
16 #ifndef ARGOSLOG_H
17 #define ARGOSLOG_H
18 
19 #include <argos3/core/config.h>
20 #include <iomanip>
21 #include <string>
22 #include <iostream>
23 #include <fstream>
24 #include <cstdio>
25 #include <cstring>
26 #include <cstdlib>
27 
28 #ifdef ARGOS_THREADSAFE_LOG
29 #include <pthread.h>
30 #include <sstream>
31 #include <map>
32 #include <vector>
33 #endif
34 
35 namespace argos {
36  class CARGOSLogger;
37 }
38 
39 #include <argos3/core/utility/logging/argos_colored_text.h>
40 
41 namespace argos {
42 
43  /****************************************/
44  /****************************************/
45 
46  extern size_t DEBUG_INDENTATION;
47 
48 #define DEBUG(MSG, ...) { fprintf(stderr, "[DEBUG] "); for(size_t ARGOS_I = 0; ARGOS_I < DEBUG_INDENTATION; ++ARGOS_I) fprintf(stderr, " "); fprintf(stderr, MSG, ##__VA_ARGS__); }
49 
50 #define DEBUG_FUNCTION_ENTER { ++DEBUG_INDENTATION; DEBUG("%s - START\n", __PRETTY_FUNCTION__ ); }
51 
52 #define DEBUG_FUNCTION_EXIT { DEBUG("%s - END\n", __PRETTY_FUNCTION__ ); --DEBUG_INDENTATION; }
53 
54 #define TRACE(LINE) LINE; DEBUG(#LINE "\n");
55 
56  /****************************************/
57  /****************************************/
58 
59  class CARGoSLog {
60 
61  private:
62 
64  std::ostream& m_cStream;
65 
67  SLogColor m_sLogColor;
68 
70  bool m_bColoredOutput;
71 
72 #ifdef ARGOS_THREADSAFE_LOG
73 
74  std::map<pthread_t, size_t> m_mapStreamOrder;
75 
77  std::vector<std::stringstream*> m_vecStreams;
78 
80  pthread_mutex_t m_tMutex;
81 #endif
82 
83  public:
84 
85  CARGoSLog(std::ostream& c_stream,
86  const SLogColor& s_log_color,
87  bool b_colored_output_enabled = true) :
88  m_cStream(c_stream),
89  m_sLogColor(s_log_color),
90  m_bColoredOutput(b_colored_output_enabled) {
91 #ifdef ARGOS_THREADSAFE_LOG
92  pthread_mutex_init(&m_tMutex, NULL);
93  AddThreadSafeBuffer();
94 #endif
95  }
96 
98 #ifdef ARGOS_THREADSAFE_LOG
99  pthread_mutex_destroy(&m_tMutex);
100  while(!m_vecStreams.empty()) {
101  delete m_vecStreams.back();
102  m_vecStreams.pop_back();
103  }
104 #endif
105  if(m_bColoredOutput) {
106  reset(m_cStream);
107  }
108  }
109 
110  inline void EnableColoredOutput() {
111  m_bColoredOutput = true;
112  }
113 
114  inline void DisableColoredOutput() {
115  m_bColoredOutput = false;
116  }
117 
118  inline bool IsColoredOutput() const {
119  return m_bColoredOutput;
120  }
121 
122  inline std::ostream& GetStream() {
123  return m_cStream;
124  }
125 
126  inline void RedirectToFile(const std::string& str_fname) {
127  m_cStream.rdbuf(std::ofstream(str_fname.c_str(), std::ios::out | std::ios::trunc).rdbuf());
128  }
129 
130 #ifdef ARGOS_THREADSAFE_LOG
131  inline void Flush() {
132  pthread_mutex_lock(&m_tMutex);
133  for(size_t i = 0; i < m_vecStreams.size(); ++i) {
134  m_cStream << m_vecStreams[i]->str();
135  m_vecStreams[i]->str("");
136  }
137  pthread_mutex_unlock(&m_tMutex);
138  }
139 
140  inline void AddThreadSafeBuffer() {
141  pthread_mutex_lock(&m_tMutex);
142  m_mapStreamOrder.insert(std::make_pair<pthread_t, size_t>(pthread_self(), m_vecStreams.size()));
143  m_vecStreams.push_back(new std::stringstream);
144  pthread_mutex_unlock(&m_tMutex);
145  }
146 #else
147  void Flush() {}
148 #endif
149 
150  inline CARGoSLog& operator<<(std::ostream& (*c_stream)(std::ostream&)) {
151 #ifdef ARGOS_THREADSAFE_LOG
152  *(m_vecStreams[m_mapStreamOrder.find(pthread_self())->second]) << c_stream;
153 #else
154  m_cStream << c_stream;
155 #endif
156  return *this;
157  }
158 
159  template <typename T> CARGoSLog& operator<<(const T t_msg) {
160  if(m_bColoredOutput) {
161 #ifdef ARGOS_THREADSAFE_LOG
162  *(m_vecStreams[m_mapStreamOrder.find(pthread_self())->second]) << m_sLogColor << t_msg << reset;
163 #else
164  m_cStream << m_sLogColor << t_msg << reset;
165 #endif
166  }
167  else {
168 #ifdef ARGOS_THREADSAFE_LOG
169  *(m_vecStreams[m_mapStreamOrder.find(pthread_self())->second]) << t_msg;
170 #else
171  m_cStream << m_sLogColor << t_msg << reset;
172 #endif
173  }
174  return *this;
175  }
176 
177  };
178 
179  extern CARGoSLog LOG;
181 
182 }
183 
184  /****************************************/
185  /****************************************/
186 
187 #define RLOG LOG << "[" << GetId() << "] "
188 #define RLOGERR LOGERR << "[" << GetId() << "] "
189 
190  /****************************************/
191  /****************************************/
192 
193 #endif
CARGoSLog(std::ostream &c_stream, const SLogColor &s_log_color, bool b_colored_output_enabled=true)
Definition: argos_log.h:85
void RedirectToFile(const std::string &str_fname)
Definition: argos_log.h:126
CARGoSLog LOG(std::cout, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_GREEN))
Definition: argos_log.h:179
Stream modifier to set attribute and color of the subsequent text.
bool IsColoredOutput() const
Definition: argos_log.h:118
std::ostream & reset(std::ostream &c_os)
Resets the text to the default settings.
CARGoSLog LOGERR(std::cerr, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_RED))
Definition: argos_log.h:180
CARGoSLog & operator<<(const T t_msg)
Definition: argos_log.h:159
size_t DEBUG_INDENTATION
Definition: argos_log.cpp:11
CARGoSLog & operator<<(std::ostream &(*c_stream)(std::ostream &))
Definition: argos_log.h:150
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
std::ostream & GetStream()
Definition: argos_log.h:122
void EnableColoredOutput()
Definition: argos_log.h:110
void DisableColoredOutput()
Definition: argos_log.h:114