9 #include "quill/core/Attributes.h" 10 #include "quill/core/Filesystem.h" 11 #include "quill/core/LogLevel.h" 12 #include "quill/core/QuillError.h" 13 #include "quill/sinks/Sink.h" 22 #include <string_view> 23 #include <system_error> 38 std::function<void(fs::path const& file_path)> before_open;
39 std::function<void(fs::path const& file_path, FILE* f)> after_open;
40 std::function<void(fs::path const& file_path, FILE* f)> before_close;
41 std::function<void(fs::path const& file_path)> after_close;
42 std::function<std::string(std::string_view message)> before_write;
59 explicit StreamSink(fs::path stream, FILE* file =
nullptr,
60 std::optional<PatternFormatterOptions>
const& override_pattern_formatter_options = std::nullopt,
62 :
Sink(override_pattern_formatter_options),
63 _filename(std::move(stream)),
65 _file_event_notifier(std::move(file_event_notifier))
68 if (_filename == std::string{
"stdout"})
72 else if (_filename == std::string{
"stderr"})
76 else if (_filename == std::string{
"/dev/null"})
86 if (!_filename.parent_path().empty())
88 parent_path = _filename.parent_path();
96 auto const st = fs::status(parent_path, ec);
97 if (!is_directory(st))
99 fs::create_directories(parent_path, ec);
103 QUILL_THROW(
QuillError{std::string{
"cannot create directories for path "} +
104 parent_path.string() + std::string{
" - error: "} + ec.message()});
110 parent_path = fs::current_path();
114 fs::path
const canonical_path = fs::canonical(parent_path, ec);
119 QUILL_THROW(
QuillError{std::string{
"cannot create canonical path for path "} +
120 parent_path.string() + std::string{
" - error: "} + ec.message()});
124 _filename = canonical_path / _filename.filename();
134 uint64_t , std::string_view ,
135 std::string_view , std::string
const& ,
136 std::string_view , LogLevel ,
139 std::vector<std::pair<std::string, std::string>>
const* ,
140 std::string_view , std::string_view log_statement)
override 142 if (QUILL_UNLIKELY(!_file))
148 if (_file_event_notifier.before_write)
150 std::string
const user_log_statement = _file_event_notifier.before_write(log_statement);
151 safe_fwrite(user_log_statement.data(),
sizeof(char), user_log_statement.size(), _file);
152 _file_size += user_log_statement.size();
156 safe_fwrite(log_statement.data(),
sizeof(char), log_statement.size(), _file);
157 _file_size += log_statement.size();
160 _write_occurred =
true;
168 if (!_write_occurred || !_file)
180 QUILL_NODISCARD
virtual fs::path
const&
get_filename() const noexcept {
return _filename; }
186 QUILL_NODISCARD
bool is_null() const noexcept {
return _is_null; }
195 QUILL_ATTRIBUTE_HOT
static void safe_fwrite(
void const* ptr,
size_t size,
size_t count, FILE* stream)
197 size_t const written = std::fwrite(ptr, size, count, stream);
199 if (QUILL_UNLIKELY(written < count))
201 QUILL_THROW(
QuillError{std::string{
"fwrite failed errno: "} + std::to_string(errno) +
202 " error: " + strerror(errno)});
212 _write_occurred =
false;
218 FILE* _file{
nullptr};
219 size_t _file_size{0};
221 bool _is_null{
false};
222 bool _write_occurred{
false};
QUILL_ATTRIBUTE_HOT void write_log(MacroMetadata const *, uint64_t, std::string_view, std::string_view, std::string const &, std::string_view, LogLevel, std::string_view, std::string_view, std::vector< std::pair< std::string, std::string >> const *, std::string_view, std::string_view log_statement) override
Writes a formatted log message to the stream.
Definition: StreamSink.h:133
Base class for sinks.
Definition: Sink.h:40
QUILL_NODISCARD bool is_null() const noexcept
Checks if the stream is null.
Definition: StreamSink.h:186
StreamSink(fs::path stream, FILE *file=nullptr, std::optional< PatternFormatterOptions > const &override_pattern_formatter_options=std::nullopt, FileEventNotifier file_event_notifier=FileEventNotifier{})
Constructor for StreamSink.
Definition: StreamSink.h:59
static QUILL_ATTRIBUTE_HOT void safe_fwrite(void const *ptr, size_t size, size_t count, FILE *stream)
Writes data safely to the stream.
Definition: StreamSink.h:195
custom exception
Definition: QuillError.h:45
QUILL_ATTRIBUTE_HOT void flush_sink() override
Flushes the stream.
Definition: StreamSink.h:166
Notifies on file events by calling the appropriate callback, the callback is executed on the backend ...
Definition: StreamSink.h:36
StreamSink class for handling log messages.
Definition: StreamSink.h:48
QUILL_ATTRIBUTE_HOT void flush()
Flushes the stream.
Definition: StreamSink.h:210
virtual QUILL_NODISCARD fs::path const & get_filename() const noexcept
Returns the name of the file.
Definition: StreamSink.h:180