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 <atomic>
15#include <sstream>
16#include <iostream>
17#include <list>
18#include <vector>
19#include <ctime>
20#include <map>
21
22namespace OpenMS
23{
24 class Colorizer;
25
52 namespace Logger
53 {
54 // forward declarations
55 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
115 LogStreamBuf(LogStreamBuf* source_buf, Colorizer* col = nullptr);
116
120 ~LogStreamBuf() override;
121
123
125
126
137 int sync() override;
138
143 int overflow(int c = -1) override;
145
146
148
149
154 void setLevel(std::string level);
155
156
160 std::string getLevel();
162
168 struct OPENMS_DLLAPI StreamStruct
169 {
170 std::ostream * stream;
171 std::string prefix;
174
176 stream(nullptr),
177 id(0)
178 {}
179 };
180
187
188protected:
189
191 void distribute_(const std::string& outstring);
192
198 void distributeNew_(const std::string& line);
199
201 std::string expandPrefix_(const std::string & prefix, time_t time) const;
202
204 std::list<StreamStruct>& getStreamList_();
205 const std::list<StreamStruct>& getStreamList_() const;
206
209
212
215
217 bool guarded_(const std::ostream* stream) const;
218
220 std::list<StreamStruct>& prefixableStreams_();
221
224
225 char * pbuf_ = nullptr;
226 std::string level_;
227 std::list<StreamStruct> stream_list_;
228 std::string incomplete_line_;
230 LogStreamBuf* parent_ = nullptr;
232 std::atomic<Size> version_{0};
234 Size parent_version_ = 0;
236 std::list<StreamStruct> own_streams_;
239 std::vector<Size> hidden_ids_;
241 std::vector<const std::ostream*> guarded_streams_;
242 Colorizer* colorizer_ = nullptr;
244
245
250 {
253 };
254
259 Size log_cache_counter_ = 0;
260
262 std::map<std::string, LogCacheStruct> log_cache_;
264 std::map<Size, std::string> log_time_cache_;
265
267 bool isInCache_(std::string const & line);
268
277 std::string addToCache_(std::string const & line);
278
281
283 int syncLF_();
284
286 std::vector<std::string> repeatSummaries_() const;
287
293 void forgetRepeatsAfterChange_(const std::vector<Size>& previous);
295
297 std::vector<Size> destinations_() const;
298
300 void write_(StreamStruct& s, const std::string& line);
301 };
302
333 class OPENMS_DLLAPI LogStream :
334 public std::ostream
335 {
336public:
337
339
340
350 LogStream(LogStreamBuf * buf = nullptr, bool delete_buf = true, std::ostream * stream = nullptr);
351
353 ~LogStream() override;
355
357
358
366
370
371
373
374
380 void setLevel(std::string level);
381
382
386 std::string getLevel();
388
410
425 void insert(std::ostream & s);
426
437 void remove(std::ostream & s);
438
446
467 void setPrefix(const std::ostream & s, const std::string & prefix);
468
469
471 void setPrefix(const std::string & prefix);
472
474 void flush();
475
483
485 bool hasStream(std::ostream & stream);
487private:
488
489 typedef std::list<LogStreamBuf::StreamStruct>::iterator StreamIterator;
490
491 StreamIterator findStream_(const std::ostream & stream);
492 bool hasStream_(std::ostream & stream);
493 bool bound_() const;
494
496 friend struct ThreadLocalLogAccess;
497
498 friend class LogSinkGuard;
499
502 {
503 bool reinsert = false;
504 std::string prefix;
505 Size id = 0;
506 };
507
514
519 void restoreForGuard_(std::ostream& s, const GuardedRemoval& removal);
520
523
526
528 void drain_();
529
532
539
545
546 }; //LogStream
547
578 class OPENMS_DLLAPI LogSinkGuard
579 {
580 public:
588 LogSinkGuard(LogStream& log_stream, std::ostream& stream)
589 : log_stream_(log_stream), stream_(stream), was_attached_(log_stream.hasStream(stream))
590 {
591 if (!was_attached_)
592 {
593 return;
594 }
595 // Drains pending output first, so that pre-guard text reaches this sink before it is detached.
596 removal_ = log_stream_.removeForGuard_(stream_);
597 }
598
601 {
602 if (!was_attached_)
603 {
604 return;
605 }
606 log_stream_.restoreForGuard_(stream_, removal_);
607 }
608
609 // Non-copyable and non-movable
610 LogSinkGuard(const LogSinkGuard&) = delete;
614
615 private:
617 std::ostream& stream_;
619 const bool was_attached_;
622 };
623
624 } // namespace Logger
625
626 //
627 // Thread-Local Log Stream Accessors
628 //
629 // These functions return thread-local LogStream instances, eliminating data races
630 // in the logging system. Each thread gets its own buffers and state.
631 // See GitHub Issue #8596 for details on the race conditions this fixes.
632 //
633 // Each thread-local stream writes to the destinations of the corresponding global stream
634 // (getGlobalLog*()). A change of the global destinations (e.g. via LogConfigHandler) takes
635 // effect in every thread at its next message, including threads that have logged before;
636 // a destination removed from the global stream is not written to afterwards, so it may be
637 // destroyed. Changes of a thread-local stream itself apply on top, to its thread only
638 // (see LogStream::insert()).
639 //
640 // A thread-local stream without destinations (e.g. the debug stream, unless debug output is enabled) does
641 // not format messages: it is in a failed state (badbit) until it has a destination again. The arguments of
642 // a message are still evaluated, except with OPENMS_LOG_DEBUG, which skips the whole message then.
643 // Each call of these accessors (as in the OPENMS_LOG_* macros) applies changes
644 // of the global destinations to the calling thread's stream; a reference kept across such a change picks it up
645 // with the next call on that thread, or with insert() or remove() on it.
646 //
647 // RESTRICTIONS:
648 // - Change the global configuration from one thread at a time.
649 // - OpenMP thread pools reuse threads, so thread_local state (e.g. local changes) persists across parallel regions.
650 //
651
654
657
660
663
666
676 OPENMS_DLLAPI void setConsoleDebugLogging(bool enabled);
677
678 //
679 // Logging Macros (thread-safe via thread-local streams)
680 //
681
683#define OPENMS_LOG_FATAL_ERROR \
684 OpenMS::getThreadLocalLogFatal() << __FILE__ << "(" << __LINE__ << "): "
685
687#define OPENMS_LOG_ERROR \
688 OpenMS::getThreadLocalLogError()
689
691#define OPENMS_LOG_WARN \
692 OpenMS::getThreadLocalLogWarn()
693
695#define OPENMS_LOG_INFO \
696 OpenMS::getThreadLocalLogInfo()
697
698 namespace Logger
699 {
702 {
703 void operator&(std::ostream&) const {}
704 };
705 }
706
714#define OPENMS_LOG_DEBUG \
715 !OpenMS::getThreadLocalLogDebug().good() ? (void)0 : OpenMS::Logger::LogVoidify() & \
716 OpenMS::getThreadLocalLogDebug() << past_last_slash(__FILE__) << "(" << __LINE__ << "): "
717
719#define OPENMS_LOG_DEBUG_NOFILE \
720 !OpenMS::getThreadLocalLogDebug().good() ? (void)0 : OpenMS::Logger::LogVoidify() & OpenMS::getThreadLocalLogDebug()
721
732
747
762
777
792
810
812
813} // 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:579
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:588
LogSinkGuard & operator=(LogSinkGuard &&)=delete
LogStream::GuardedRemoval removal_
what the guard removed, restored on destruction
Definition LogStream.h:621
~LogSinkGuard()
Destructor writes output pending inside the scope to the other destinations, then restores the sink.
Definition LogStream.h:600
LogStream & log_stream_
Definition LogStream.h:616
std::ostream & stream_
Definition LogStream.h:617
const bool was_attached_
was the sink attached when the guard was constructed? if not, the guard does nothing
Definition LogStream.h:619
Stream buffer used by LogStream.
Definition LogStream.h:80
Size getNextLogCounter_()
Returns the next free index for a log message.
void updateFromParent_()
Updates stream_list_ if parent_ changed its destinations since the last update. Locks the sink mutex.
void updateFromParentLocked_()
Same as updateFromParent_(), but the caller holds the sink mutex.
std::map< Size, std::string > log_time_cache_
Cache of the occurrence sequence of the last two log messages.
Definition LogStream.h:264
void write_(StreamStruct &s, const std::string &line)
Writes line to the destination s, with its prefix and color. The caller holds the sink mutex.
void forgetRepeatsAfterChange_(const std::vector< Size > &previous)
std::string expandPrefix_(const std::string &prefix, time_t time) const
Interpret the prefix format string and return the expanded prefix.
void rebuildStreamList_()
Rebuilds stream_list_ from parent_'s destinations and this buffer's own changes. The caller holds the...
LogStreamBuf(LogStreamBuf *source_buf, Colorizer *col=nullptr)
std::list< StreamStruct > & prefixableStreams_()
Entries whose prefix may be changed: stream_list_, or own_streams_ for a following buffer (the prefix...
std::string level_
Definition LogStream.h:226
std::list< StreamStruct > stream_list_
Destinations of this buffer (for a following buffer: derived from parent_, own_streams_ and hidden_id...
Definition LogStream.h:227
int counter
Definition LogStream.h:252
std::vector< Size > destinations_() const
The destinations in stream_list_ (their StreamStruct::id), sorted.
Size timestamp
Definition LogStream.h:251
std::vector< std::string > repeatSummaries_() const
"<message> occurred N times" for each cached message that was repeated
const std::list< StreamStruct > & getStreamList_() const
std::vector< Size > hidden_ids_
Definition LogStream.h:239
bool guarded_(const std::ostream *stream) const
Is stream suppressed by a LogSinkGuard on this following buffer (see guarded_streams_)?
std::map< std::string, LogCacheStruct > log_cache_
Cache of the last two log messages.
Definition LogStream.h:262
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)
void distributeNew_(const std::string &line)
void destinationsChanged_()
Publishes a change of the destinations to following buffers (or rebuilds stream_list_)....
std::vector< const std::ostream * > guarded_streams_
Streams that a LogSinkGuard suppresses on this following buffer (one entry per guard),...
Definition LogStream.h:241
std::string addToCache_(std::string const &line)
std::string incomplete_line_
Definition LogStream.h:228
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.
std::list< StreamStruct > own_streams_
Destinations inserted into this following buffer; they replace parent_'s entry for the same stream.
Definition LogStream.h:236
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:250
Log Stream Class.
Definition LogStream.h:335
bool hasStream_(std::ostream &stream)
LogStream(LogStreamBuf *buf=nullptr, bool delete_buf=true, std::ostream *stream=nullptr)
void followParent_()
For a thread-local stream: applies changes of the global destinations made since the last call,...
LogStream * threadLocalFollower_()
For a global stream: the calling thread's thread-local stream of the same level, or 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:489
GuardedRemoval removeForGuard_(std::ostream &s)
GuardedRemoval detachLocked_(std::ostream &s)
Removes s from the destinations (for a thread-local stream: hides inherited ones) and returns what it...
~LogStream() override
Clears all message buffers.
LogStreamBuf * operator->()
Arrow operator.
std::string prefix
Definition LogStream.h:504
void setPrefix(const std::ostream &s, const std::string &prefix)
bool delete_buffer_
Definition LogStream.h:544
void drain_()
Writes pending text (also an incomplete line) and repeat counts to the current destinations.
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)
void restoreForGuard_(std::ostream &s, const GuardedRemoval &removal)
StreamIterator findStream_(const std::ostream &stream)
void flushIncomplete()
Flush any incomplete line (text not terminated by newline) to all streams.
A destination that LogSinkGuard removed from a global stream (see removeForGuard_()),...
Definition LogStream.h:502
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.
void setConsoleDebugLogging(bool enabled)
Enables or disables writing OPENMS_LOG_DEBUG messages to std::cout.
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:169
std::string prefix
Definition LogStream.h:171
Size id
Unique for each insertion: a stream inserted again, or a new stream at the address of a destroyed one...
Definition LogStream.h:173
StreamStruct()
Definition LogStream.h:175
std::ostream * stream
Definition LogStream.h:170
Turns a whole message into a void expression, which OPENMS_LOG_DEBUG skips when debug output is disab...
Definition LogStream.h:702
void operator&(std::ostream &) const
Definition LogStream.h:703