Simple-Log  alpha-v0.7
OStreamSink.hpp
Go to the documentation of this file.
1 // Copyright Dominic Koepke 2021 - 2021.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // https://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef SL_LOG_OSTREAM_SINK_HPP
7 #define SL_LOG_OSTREAM_SINK_HPP
8 
9 #pragma once
10 
11 #include "BasicSink.hpp"
12 #include "FlushPolicies.hpp"
13 #include "Record.hpp"
14 
15 #include <memory>
16 #include <mutex>
17 #include <ostream>
18 #include <string_view>
19 
20 namespace sl::log
21 {
32  template <Record TRecord>
33  class OStreamSink :
34  public BasicSink<TRecord>
35  {
36  using Super = BasicSink<TRecord>;
37 
38  public:
39  using typename Super::Record_t;
40  using typename Super::Formatter_t;
41  using typename Super::Filter_t;
42  using FlushPolicy_t = std::unique_ptr<detail::AbstractFlushPolicyWrapper<Record_t>>;
43 
44  protected:
45  [[nodiscard]]
46  static constexpr FlushPolicy_t defaultFlushPolicy() noexcept
47  {
48  return std::make_unique<detail::FlushPolicyWrapper<Record_t, AlwaysFlushPolicy>>();
49  }
50 
51  public:
56  explicit OStreamSink(std::ostream& stream) :
57  Super{},
58  m_Stream{ stream }
59  {
60  }
61 
66  ~OStreamSink() noexcept = default;
67 
71  OStreamSink(const OStreamSink&) = delete;
75  OStreamSink& operator =(const OStreamSink&) = delete;
76 
80  OStreamSink(OStreamSink&&) = delete;
84  OStreamSink& operator =(OStreamSink&&) = delete;
85 
91  template <FlushPolicyFor<Record_t> TPolicy>
92  void setFlushPolicy(TPolicy&& policy)
93  {
94  std::scoped_lock lock{ m_FlushPolicyMx };
95  m_FlushPolicy = std::make_unique<detail::FlushPolicyWrapper<TRecord, TPolicy>>(std::forward<TPolicy>(policy));
96  }
97 
103  {
104  std::scoped_lock lock{ m_FlushPolicyMx };
105  m_FlushPolicy = defaultFlushPolicy();
106  }
107 
112  void flush()
113  {
114  std::scoped_lock lock{ m_StreamMx };
115  flushImpl();
116  }
117 
118  protected:
128  template <class TData>
129  void writeToStream(TData&& data)
130  {
131  std::scoped_lock lock{ m_StreamMx };
132  m_Stream << std::forward<TData>(data);
133  flushImpl();
134  }
135 
143  virtual void beforeMessageWrite(const Record_t& record, std::string_view message)
144  {
145  }
146 
154  virtual void afterMessageWrite(const Record_t& record, std::string_view message)
155  {
156  }
157 
158  private:
159  std::recursive_mutex m_StreamMx;
160  std::ostream& m_Stream;
161 
162  std::mutex m_FlushPolicyMx;
163  FlushPolicy_t m_FlushPolicy{ defaultFlushPolicy() };
164 
165  void handleFlushPolicy(const Record_t& record, std::size_t messageByteSize)
166  {
167  if (std::scoped_lock lock{ m_FlushPolicyMx }; !std::invoke(*m_FlushPolicy, record, messageByteSize))
168  return;
169 
170  flushImpl();
171  }
172 
173  void flushImpl()
174  {
175  m_Stream << std::flush;
176  m_FlushPolicy->flushed();
177  }
178 
179  void writeMessage(const Record_t& record, std::string_view message) final override
180  {
181  const auto msgSize = std::size(message) * sizeof(std::string_view::value_type);
182 
183  std::scoped_lock lock{ m_StreamMx };
184  beforeMessageWrite(record, message);
185  m_Stream << message << "\n";
186  afterMessageWrite(record, message);
187  handleFlushPolicy(record, msgSize);
188  }
189  };
190 
192 }
193 
194 #endif
Abstract Sink class which offers basic filtering, formatting functionality.
Definition: BasicSink.hpp:52
std::function< bool(const Record_t &)> Filter_t
Definition: BasicSink.hpp:59
std::function< std::string(const Record_t &)> Formatter_t
Definition: BasicSink.hpp:58
std::remove_cvref_t< TRecord > Record_t
Used Record type.
Definition: ISink.hpp:34
Sink interface class.
Definition: ISink.hpp:29
std::remove_cvref_t< TRecord > Record_t
Used Record type.
Definition: ISink.hpp:34
An std::ostream orientated Sink class which extends BasicSink.
Definition: OStreamSink.hpp:35
std::unique_ptr< detail::AbstractFlushPolicyWrapper< Record_t > > FlushPolicy_t
Definition: OStreamSink.hpp:42
void removeFlushPolicy()
Replaces the current Flush-Policy with the default one.
Definition: OStreamSink.hpp:102
void writeToStream(TData &&data)
Writes directly to the internal stream.
Definition: OStreamSink.hpp:129
~OStreamSink() noexcept=default
Default destructor.
void flush()
Flushes all pending output of the internal stream.
Definition: OStreamSink.hpp:112
OStreamSink(std::ostream &stream)
Constructor.
Definition: OStreamSink.hpp:56
std::remove_cvref_t< TRecord > Record_t
Used Record type.
Definition: ISink.hpp:34
virtual void beforeMessageWrite(const Record_t &record, std::string_view message)
Virtual method which will be called before the actual message is written to the stream.
Definition: OStreamSink.hpp:143
static constexpr FlushPolicy_t defaultFlushPolicy() noexcept
Definition: OStreamSink.hpp:46
void setFlushPolicy(TPolicy &&policy)
Sets the active Flush-Policy.
Definition: OStreamSink.hpp:92
virtual void afterMessageWrite(const Record_t &record, std::string_view message)
Virtual method which will be called after the actual message is written to the stream.
Definition: OStreamSink.hpp:154
Definition: BasicSink.hpp:22
concept FlushPolicyFor
Concept for invokable flush policies.
Definition: FlushPolicies.hpp:27