YARP
Yet Another Robot Platform
LogStream.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #ifndef YARP_OS_LOGSTREAM_H
7 #define YARP_OS_LOGSTREAM_H
8 
9 #include <yarp/os/api.h>
10 
11 #include <yarp/os/Log.h>
12 #include <yarp/os/LogComponent.h>
13 #include <yarp/os/Os.h>
14 #include <yarp/os/SystemClock.h>
15 #include <yarp/os/Time.h>
16 
17 #include <cstdio>
18 #include <cstdlib>
19 #include <iosfwd>
20 #include <sstream>
21 #include <string>
22 #include <vector>
23 
24 namespace yarp {
25 namespace os {
26 
28 {
29  struct Stream
30  {
31  Stream(Log::LogType t,
32  const char* fn,
33  unsigned int l,
34  const char* f,
35  const double ct,
36  const yarp::os::Log::Predicate pred,
37  const LogComponent& c) :
38  type(t),
39  file(fn),
40  line(l),
41  func(f),
44  externaltime(ct),
45  pred(pred),
46  comp(c),
47  ref(1)
48  {
49  }
50  std::ostringstream oss;
51  Log::LogType type;
52  const char* file;
53  unsigned int line;
54  const char* func;
55  double systemtime;
56  double networktime;
57  double externaltime;
58  const yarp::os::Log::Predicate pred;
59  const LogComponent& comp;
60  int ref;
61  bool nospace {false};
62  } * stream;
63 
64 public:
65  inline LogStream(Log::LogType type,
66  const char* file,
67  unsigned int line,
68  const char* func,
69  const double externaltime,
70  const yarp::os::Log::Predicate pred = nullptr,
71  const LogComponent& comp = Log::defaultLogComponent()) :
72  stream(new Stream(type, file, line, func, externaltime, pred, comp))
73  {
74  }
75 
76  inline LogStream(const LogStream& o) :
77  stream(o.stream)
78  {
79  ++stream->ref;
80  }
81 
82  inline ~LogStream()
83  {
84  if (!--stream->ref) {
85  if (!stream->pred || stream->pred()) {
86  std::string s = stream->oss.str();
87  if (!s.empty()) {
88  // remove the last character if it an empty space (i.e.
89  // always unless the user defined an operator<< that
90  // does not add an empty space.
91  if (s.back() == ' ') {
92  s.pop_back();
93  } else {
94  yarp::os::Log(stream->file, stream->line, stream->func, nullptr, yarp::os::Log::logInternalComponent()).warning(
95  "' ' was expected. Some `operator<<` does not add an extra space at the end");
96  }
97  // remove the last character if it is a \n
98  if (s.back() == '\n') {
99  yarp::os::Log(stream->file, stream->line, stream->func, nullptr, yarp::os::Log::logInternalComponent()).warning(
100  "Removing extra \\n (stream-style)");
101  s.pop_back();
102  }
103  }
104  Log::do_log(stream->type,
105  s.c_str(),
106  stream->file,
107  stream->line,
108  stream->func,
109  stream->systemtime,
110  stream->networktime,
111  stream->externaltime,
112  stream->comp);
113  }
114 
115  if (stream->type == yarp::os::Log::FatalType) {
116  yarp_print_trace(stderr, stream->file, stream->line);
117  delete stream;
118  std::exit(-1);
119  }
120  delete stream;
121  }
122  }
123 
124  inline LogStream& operator<<(bool t)
125  {
126  stream->oss << (t ? "true" : "false");
127  if (!stream->nospace) {
128  stream->oss << ' ';
129  }
130  return *this;
131  }
132  inline LogStream& operator<<(char t)
133  {
134  stream->oss << t;
135  if (!stream->nospace) {
136  stream->oss << ' ';
137  }
138  return *this;
139  }
140  inline LogStream& operator<<(signed short t)
141  {
142  stream->oss << t;
143  if (!stream->nospace) {
144  stream->oss << ' ';
145  }
146  return *this;
147  }
148  inline LogStream& operator<<(unsigned short t)
149  {
150  stream->oss << t;
151  if (!stream->nospace) {
152  stream->oss << ' ';
153  }
154  return *this;
155  }
156  inline LogStream& operator<<(signed int t)
157  {
158  stream->oss << t;
159  if (!stream->nospace) {
160  stream->oss << ' ';
161  }
162  return *this;
163  }
164  inline LogStream& operator<<(unsigned int t)
165  {
166  stream->oss << t;
167  if (!stream->nospace) {
168  stream->oss << ' ';
169  }
170  return *this;
171  }
172  inline LogStream& operator<<(signed long t)
173  {
174  stream->oss << t;
175  if (!stream->nospace) {
176  stream->oss << ' ';
177  }
178  return *this;
179  }
180  inline LogStream& operator<<(unsigned long t)
181  {
182  stream->oss << t;
183  if (!stream->nospace) {
184  stream->oss << ' ';
185  }
186  return *this;
187  }
188  inline LogStream& operator<<(signed long long t)
189  {
190  stream->oss << t;
191  if (!stream->nospace) {
192  stream->oss << ' ';
193  }
194  return *this;
195  }
196  inline LogStream& operator<<(unsigned long long t)
197  {
198  stream->oss << t;
199  if (!stream->nospace) {
200  stream->oss << ' ';
201  }
202  return *this;
203  }
204  inline LogStream& operator<<(float t)
205  {
206  stream->oss << t;
207  if (!stream->nospace) {
208  stream->oss << ' ';
209  }
210  return *this;
211  }
212  inline LogStream& operator<<(double t)
213  {
214  stream->oss << t;
215  if (!stream->nospace) {
216  stream->oss << ' ';
217  }
218  return *this;
219  }
220  inline LogStream& operator<<(const char* t)
221  {
222  stream->oss << t;
223  if (!stream->nospace) {
224  stream->oss << ' ';
225  }
226  return *this;
227  }
228  inline LogStream& operator<<(const void* t)
229  {
230  stream->oss << t;
231  if (!stream->nospace) {
232  stream->oss << ' ';
233  }
234  return *this;
235  }
236 
237  inline LogStream& operator<<(const std::string& t)
238  {
239  stream->oss << t.c_str();
240  if (!stream->nospace) {
241  stream->oss << ' ';
242  }
243  return *this;
244  }
245 
246  template <typename T>
247  inline LogStream& operator<<(const std::vector<T>& t)
248  {
249  bool nospace = stream->nospace;
250  stream->nospace = true;
251  stream->oss << '[';
252  for (typename std::vector<T>::const_iterator it = t.begin(); it != t.end(); ++it) {
253  const T& p = *it;
254  if (it != t.begin()) {
255  stream->oss << ", ";
256  }
257  *this << p;
258  }
259  stream->oss << ']';
260  stream->nospace = nospace;
261  if (!stream->nospace) {
262  stream->oss << ' ';
263  }
264  return *this;
265 }
266 
267 }; // class LogStream
268 
269 } // namespace os
270 } // namespace yarp
271 
272 #endif // YARP_OS_LOGSTREAM_H
float t
void yarp_print_trace(FILE *out, const char *file, unsigned int line)
Low level function for printing a stack trace, if implemented (ACE or gcc/Linux).
Definition: Log.cpp:1065
LogStream & operator<<(unsigned short t)
Definition: LogStream.h:148
LogStream & operator<<(const void *t)
Definition: LogStream.h:228
LogStream & operator<<(unsigned int t)
Definition: LogStream.h:164
LogStream & operator<<(const std::vector< T > &t)
Definition: LogStream.h:247
LogStream & operator<<(char t)
Definition: LogStream.h:132
LogStream & operator<<(bool t)
Definition: LogStream.h:124
LogStream & operator<<(unsigned long long t)
Definition: LogStream.h:196
LogStream(Log::LogType type, const char *file, unsigned int line, const char *func, const double externaltime, const yarp::os::Log::Predicate pred=nullptr, const LogComponent &comp=Log::defaultLogComponent())
Definition: LogStream.h:65
LogStream & operator<<(double t)
Definition: LogStream.h:212
LogStream & operator<<(unsigned long t)
Definition: LogStream.h:180
LogStream & operator<<(float t)
Definition: LogStream.h:204
LogStream & operator<<(const std::string &t)
Definition: LogStream.h:237
LogStream & operator<<(signed long long t)
Definition: LogStream.h:188
LogStream & operator<<(const char *t)
Definition: LogStream.h:220
LogStream & operator<<(signed int t)
Definition: LogStream.h:156
LogStream(const LogStream &o)
Definition: LogStream.h:76
LogStream & operator<<(signed short t)
Definition: LogStream.h:140
LogStream & operator<<(signed long t)
Definition: LogStream.h:172
bool(*)() Predicate
Definition: Log.h:52
void warning(const char *msg,...) const
Definition: Log.cpp:1005
@ FatalType
Definition: Log.h:79
static double nowSystem()
Definition: SystemClock.cpp:34
bool isClockInitialized()
Check if YARP clock is initialized.
Definition: Time.cpp:257
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:121
bool isSystemClock()
Check if YARP is providing system time.
Definition: Time.cpp:262
The main, catch-all namespace for YARP.
Definition: dirs.h:16
#define YARP_os_API
Definition: api.h:18