OpenMS
Loading...
Searching...
No Matches
LogStream.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Chris Bielow $
6// $Authors: Chris Bielow, Stephan Aiche, Andreas Bertsch$
7// --------------------------------------------------------------------------
8
9#pragma once
10
13
14#include <sstream>
15#include <iostream>
16#include <list>
17#include <vector>
18#include <ctime>
19#include <map>
20
21namespace OpenMS
22{
23 class Colorizer;
24
51 namespace Logger
52 {
53 // forward declarations
54 class LogStream;
56
78 class OPENMS_DLLAPI LogStreamBuf :
79 public std::streambuf
80 {
81
82 friend class LogStream;
83
84public:
85
87
88 static const time_t MAX_TIME;
89 static const std::string UNKNOWN_LOG_LEVEL;
91
93
94
95
102 LogStreamBuf(const std::string& log_level = UNKNOWN_LOG_LEVEL, Colorizer* col = nullptr);
103
114 LogStreamBuf(LogStreamBuf* source_buf, Colorizer* col = nullptr);
115
119 ~LogStreamBuf() override;
120
122
124
125
136 int sync() override;
137
142 int overflow(int c = -1) override;
144
145
147
148
153 void setLevel(std::string level);
154
155
159 std::string getLevel();
161
167 struct OPENMS_DLLAPI StreamStruct
168 {
169 std::ostream * stream;
170 std::string prefix;
172
174 stream(nullptr),
175 target(nullptr)
176 {}
177
181
182 };
183
190
191protected:
192
194 void distribute_(const std::string& outstring);
195
197 std::string expandPrefix_(const std::string & prefix, time_t time) const;
198
200 std::list<StreamStruct>& getStreamList_();
201 const std::list<StreamStruct>& getStreamList_() const;
202
203 char * pbuf_ = nullptr;
204 std::string level_;
205 std::list<StreamStruct> stream_list_;
206 std::string incomplete_line_;
207 Colorizer* colorizer_ = nullptr;
209
210
215 {
218 };
219
224 Size log_cache_counter_ = 0;
225
227 std::map<std::string, LogCacheStruct> log_cache_;
229 std::map<Size, std::string> log_time_cache_;
230
232 bool isInCache_(std::string const & line);
233
242 std::string addToCache_(std::string const & line);
243
246
248 int syncLF_();
250 };
251
266 class OPENMS_DLLAPI LogStreamNotifier
267 {
268public:
269
272
275
282 virtual void logNotify();
283
293 void registerAt(LogStream & log_stream);
294
302
303protected:
304 std::stringstream stream_;
305
307 };
308
309
339 class OPENMS_DLLAPI LogStream :
340 public std::ostream
341 {
342public:
343
345
346
356 LogStream(LogStreamBuf * buf = nullptr, bool delete_buf = true, std::ostream * stream = nullptr);
357
359 ~LogStream() override;
361
363
364
372
376
377
379
380
386 void setLevel(std::string level);
387
388
392 std::string getLevel();
394
396
397
412 void insert(std::ostream & s);
413
424 void remove(std::ostream & s);
425
433
435 void insertNotification(std::ostream & s,
436 LogStreamNotifier & target);
437
458 void setPrefix(const std::ostream & s, const std::string & prefix);
459
460
462 void setPrefix(const std::string & prefix);
463
465 void flush();
466
474
476 bool hasStream(std::ostream & stream);
478private:
479
480 typedef std::list<LogStreamBuf::StreamStruct>::iterator StreamIterator;
481
482 StreamIterator findStream_(const std::ostream & stream);
483 bool hasStream_(std::ostream & stream);
484 bool bound_() const;
485
491
492 }; //LogStream
493
517 class OPENMS_DLLAPI LogSinkGuard
518 {
519 public:
527 LogSinkGuard(LogStream& log_stream, std::ostream& stream)
528 : log_stream_(log_stream), stream_(stream), was_attached_(log_stream.hasStream(stream))
529 {
530 if (!was_attached_)
531 {
532 return;
533 }
534 // Drain pending output so pre-guard text reaches this sink before it is detached.
535 log_stream_.flushIncomplete();
536 log_stream_.remove(stream_);
537 }
538
541 {
542 if (!was_attached_)
543 {
544 return;
545 }
546 // Drain buffered output while the sink is still detached so it does not leak through.
547 log_stream_.flushIncomplete();
548 log_stream_.insert(stream_);
549 }
550
551 // Non-copyable and non-movable
552 LogSinkGuard(const LogSinkGuard&) = delete;
556
557 private:
559 std::ostream& stream_;
561 const bool was_attached_;
562 };
563
564 } // namespace Logger
565
566 //
567 // Thread-Local Log Stream Accessors
568 //
569 // These functions return thread-local LogStream instances, eliminating data races
570 // in the logging system. Each thread gets its own buffers and state.
571 // See GitHub Issue #8596 for details on the race conditions this fixes.
572 //
573 // RESTRICTIONS (document these clearly):
574 // - Log configuration (via LogConfigHandler) should be done ONCE at program start,
575 // BEFORE spawning threads. Thread-local streams copy config from globals on first access.
576 // - OpenMP thread pools reuse threads, so thread_local state persists across parallel regions.
577 // - Do not reconfigure logging while threads are actively logging.
578 //
579
582
585
588
591
594
595 //
596 // Logging Macros (thread-safe via thread-local streams)
597 //
598
600#define OPENMS_LOG_FATAL_ERROR \
601 OpenMS::getThreadLocalLogFatal() << __FILE__ << "(" << __LINE__ << "): "
602
604#define OPENMS_LOG_ERROR \
605 OpenMS::getThreadLocalLogError()
606
608#define OPENMS_LOG_WARN \
609 OpenMS::getThreadLocalLogWarn()
610
612#define OPENMS_LOG_INFO \
613 OpenMS::getThreadLocalLogInfo()
614
616#define OPENMS_LOG_DEBUG \
617 OpenMS::getThreadLocalLogDebug() << past_last_slash(__FILE__) << "(" << __LINE__ << "): "
618
620#define OPENMS_LOG_DEBUG_NOFILE \
621 OpenMS::getThreadLocalLogDebug()
622
633
648
663
678
693
711
713
714} // namespace OpenMS
Color and style the fonts shown on cout/cerr (or other streams)
Definition Colorizer.h:71
RAII guard that temporarily removes an attached stream from a LogStream and re-inserts it on scope ex...
Definition LogStream.h:518
LogSinkGuard(LogSinkGuard &&)=delete
LogSinkGuard(const LogSinkGuard &)=delete
LogSinkGuard & operator=(const LogSinkGuard &)=delete
LogSinkGuard(LogStream &log_stream, std::ostream &stream)
Construct a guard that removes stream, if attached, and re-inserts it on destruction.
Definition LogStream.h:527
LogSinkGuard & operator=(LogSinkGuard &&)=delete
~LogSinkGuard()
Destructor discards any suppressed output, then re-inserts the sink.
Definition LogStream.h:540
LogStream & log_stream_
Definition LogStream.h:558
std::ostream & stream_
Definition LogStream.h:559
const bool was_attached_
was the sink attached when the guard was constructed? if not, the guard does nothing
Definition LogStream.h:561
Stream buffer used by LogStream.
Definition LogStream.h:80
Size getNextLogCounter_()
Returns the next free index for a log message.
std::map< Size, std::string > log_time_cache_
Cache of the occurrence sequence of the last two log messages.
Definition LogStream.h:229
std::string expandPrefix_(const std::string &prefix, time_t time) const
Interpret the prefix format string and return the expanded prefix.
LogStreamBuf(LogStreamBuf *source_buf, Colorizer *col=nullptr)
std::string level_
Definition LogStream.h:204
std::list< StreamStruct > stream_list_
Stream list for this buffer.
Definition LogStream.h:205
int counter
Definition LogStream.h:217
Size timestamp
Definition LogStream.h:216
const std::list< StreamStruct > & getStreamList_() const
std::map< std::string, LogCacheStruct > log_cache_
Cache of the last two log messages.
Definition LogStream.h:227
LogStreamBuf(const std::string &log_level=UNKNOWN_LOG_LEVEL, Colorizer *col=nullptr)
int syncLF_()
Non-lock acquiring sync function called in the d'tor.
void setLevel(std::string level)
std::string addToCache_(std::string const &line)
std::string incomplete_line_
Definition LogStream.h:206
void distribute_(const std::string &outstring)
Distribute a new message to connected streams.
std::list< StreamStruct > & getStreamList_()
Returns the stream list (owned or shared)
static const std::string UNKNOWN_LOG_LEVEL
Definition LogStream.h:89
bool isInCache_(std::string const &line)
Checks if the line is already in the cache.
static const time_t MAX_TIME
Definition LogStream.h:88
int overflow(int c=-1) override
Holds a counter of occurrences and an index for the occurrence sequence of the corresponding log mess...
Definition LogStream.h:215
Sink-side hook that is notified whenever a LogStream flushes a complete message.
Definition LogStream.h:267
void unregister()
Detach from the currently registered LogStream, if any.
virtual ~LogStreamNotifier()
Destructor; calls unregister so the LogStream stops dispatching to this notifier.
virtual void logNotify()
Hook called by the registered LogStream after each complete message has been flushed.
LogStreamNotifier()
Construct a detached notifier; registered_at_ starts at nullptr.
LogStream * registered_at_
The LogStream this notifier is currently attached to, or nullptr if detached. Managed by registerAt /...
Definition LogStream.h:306
void registerAt(LogStream &log_stream)
Attach this notifier to log_stream so its logNotify is invoked after every flushed message.
std::stringstream stream_
Buffer that receives the formatted log line from the registered LogStream; read inside logNotify.
Definition LogStream.h:304
Log Stream Class.
Definition LogStream.h:341
bool hasStream_(std::ostream &stream)
LogStream(LogStreamBuf *buf=nullptr, bool delete_buf=true, std::ostream *stream=nullptr)
void insert(std::ostream &s)
bool hasStream(std::ostream &stream)
Is stream currently one of this LogStream's output destinations?
std::list< LogStreamBuf::StreamStruct >::iterator StreamIterator
Definition LogStream.h:480
~LogStream() override
Clears all message buffers.
LogStreamBuf * operator->()
Arrow operator.
void setPrefix(const std::ostream &s, const std::string &prefix)
bool delete_buffer_
Definition LogStream.h:490
void insertNotification(std::ostream &s, LogStreamNotifier &target)
Add a notification target.
void setPrefix(const std::string &prefix)
Set prefix of all output streams, details see setPrefix method with ostream.
void setLevel(std::string level)
LogStreamBuf * rdbuf()
void remove(std::ostream &s)
StreamIterator findStream_(const std::ostream &stream)
void flushIncomplete()
Flush any incomplete line (text not terminated by newline) to all streams.
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition Types.h:97
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
Logger::LogStream & getGlobalLogDebug()
Get the global debug log stream for configuration purposes.
Logger::LogStream & getThreadLocalLogDebug()
Get thread-local debug log stream.
Logger::LogStream & getGlobalLogError()
Get the global error log stream for configuration purposes.
Logger::LogStream & getThreadLocalLogInfo()
Get thread-local info log stream.
Logger::LogStream & getThreadLocalLogWarn()
Get thread-local warning log stream.
Logger::LogStream & getGlobalLogFatal()
Get the global fatal error log stream for configuration purposes.
Logger::LogStream & getThreadLocalLogFatal()
Get thread-local fatal error log stream.
Logger::LogStream & getGlobalLogWarn()
Get the global warning log stream for configuration purposes.
Logger::LogStream & getThreadLocalLogError()
Get thread-local error log stream.
Logger::LogStream & getGlobalLogInfo()
Get the global info log stream for configuration purposes.
Holds a stream that is connected to the LogStream. It also includes the minimum and maximum level at ...
Definition LogStream.h:168
std::string prefix
Definition LogStream.h:170
StreamStruct()
Definition LogStream.h:173
LogStreamNotifier * target
Definition LogStream.h:171
~StreamStruct()
Delete the notification target.
Definition LogStream.h:179
std::ostream * stream
Definition LogStream.h:169