StormByte-Logger 2.0.0
C++26 logger module of the StormByte suite
 
Loading...
Searching...
No Matches
log.hxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024-2026 David C. Manuelda (StormBytePP)
3 *
4 * This file is part of StormByte-Logger.
5 *
6 * StormByte-Logger original source is dual-licensed:
7 *
8 * 1. GNU Lesser General Public License v3.0 (or later)
9 * You may redistribute and/or modify this file under the terms of the
10 * GNU Lesser General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * 2. Commercial license
15 * Alternatively, this file may be used under the terms of a commercial
16 * license agreement with the copyright holder
17 * (David C. Manuelda <StormByte@gmail.com>).
18 *
19 * Both licenses apply only to original StormByte-Logger source in this
20 * repository. They do not cover other StormByte modules or any third-party
21 * material shipped with this repository (including everything under
22 * thirdparty/, and in particular the bundled StormByte-String tree and
23 * the StormByte Base tree it vendors), which remains under its own license.
24 *
25 * Neither license grants any patent rights. Any patent licenses required
26 * to use this software or third-party components must be obtained separately
27 * from the patent holders.
28 *
29 * StormByte-Logger is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU Lesser General Public License for more details.
33 *
34 * You should have received a copy of the GNU Lesser General Public License
35 * version 3 along with StormByte-Logger. If not, see
36 * <https://www.gnu.org/licenses/lgpl-3.0.html>.
37 *
38 * SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-StormByte-Commercial
39 */
40
41#pragma once
42
46#include <StormByte/cstring.hxx>
49#include <StormByte/size.hxx>
54
55#include <cstddef>
56#include <memory>
57#include <ostream>
58#include <span>
59#include <string>
60#include <string_view>
61
66namespace StormByte::Logger {
67 class Engine;
68
77 inline void OStreamWrite(void* context, const char* data, std::size_t size) {
78 if (context == nullptr || data == nullptr || size == 0)
79 return;
80 static_cast<std::ostream*>(context)->write(data, static_cast<std::streamsize>(size));
81 }
82
88 inline void OStreamManip(void* context, std::ostream& (*manip)(std::ostream&)) {
89 if (context == nullptr || manip == nullptr)
90 return;
91 *static_cast<std::ostream*>(context) << manip;
92 }
93
115 friend STORMBYTE_LOGGER_PUBLIC Log& noredact(Log& log) noexcept;
116
117 public:
122
132 Log(std::ostream& out, const Level& level = Level::Info, std::string_view format = "[%L] %T")
133 : Log(&OStreamWrite, &OStreamManip, &out, level, format) {}
134
139 Log(const Log&) = default;
140
144 Log(Log&&) noexcept = default;
145
149 ~Log() noexcept override;
150
156 Log& operator=(const Log&);
157
162 Log& operator=(Log&&) noexcept;
163
171 PointerType Scope(std::string_view path);
172
179 bool Enabled(const Level& level) const noexcept;
180
187 virtual Log& Color(const Level& level, const StormByte::Logger::Color& color);
188
194 virtual StormByte::Logger::Color Color(const Level& level) const;
195
203 virtual Log& Color(std::string_view component, const Level& level, const StormByte::Logger::Color& color);
204
211 virtual StormByte::Logger::Color Color(std::string_view component, const Level& level) const;
212
218 virtual Log& Format(std::string_view format);
219
224 virtual StormByte::String::String Format() const;
225
232 virtual Log& Format(std::string_view component, std::string_view format);
233
239 virtual StormByte::String::String Format(std::string_view component) const;
240
246 virtual Log& Throttle(const ThrottleSpec& spec);
247
253 virtual Log& NoThrottle(const ThrottleSpec& spec);
254
261 virtual Log& Throttle(double rate, std::size_t burst);
262
272 virtual Log& Throttle(double rate, std::size_t burst, ThrottlePolicy policy, std::size_t value, std::size_t period = 0);
273
281 virtual Log& Throttle(const Level& level, double rate, std::size_t burst);
282
290 virtual Log& Throttle(GroupManip group, double rate, std::size_t burst);
291
299 virtual Log& Throttle(ComponentManip component, double rate, std::size_t burst);
300
313 virtual Log& Throttle(ComponentManip component, const Level& level, GroupManip group, double rate, std::size_t burst, ThrottlePolicy policy = ThrottlePolicy::Drop, std::size_t value = 0, std::size_t period = 0);
314
319 virtual Log& NoThrottle();
320
326 virtual Log& NoThrottle(const Level& level);
327
333 virtual Log& NoThrottle(GroupManip group);
334
340 virtual Log& NoThrottle(ComponentManip component);
341
349 virtual Log& NoThrottle(ComponentManip component, const Level& level, GroupManip group);
350
355 virtual Log& FlushThrottle();
356
362 virtual Log& FlushThrottle(const ThrottleSpec& spec);
363
368
375 template <typename T>
376 inline Log& operator<<(const T& v)
377 requires (
378 (StormByte::Type::Arithmetic<std::decay_t<T>> && !StormByte::Type::SameAs<std::decay_t<T>, wchar_t>)
379 || StormByte::Type::SameAs<std::decay_t<T>, std::string_view>
380 || StormByte::Type::SameAs<std::decay_t<T>, const char*>
381 || StormByte::Type::SameAs<std::decay_t<T>, char*>
382 ) {
383 if (!WillWrite()) [[likely]]
384 return *this;
386 WriteValue(static_cast<const char*>(v));
387 else if constexpr (StormByte::Type::SameAs<std::decay_t<T>, std::string_view>)
388 WriteValue(v);
389 else
390 WriteValue(static_cast<std::decay_t<T>>(v));
391 return *this;
392 }
393
400 if (!WillWrite()) [[likely]]
401 return *this;
402 WriteValue(static_cast<std::string_view>(v));
403 return *this;
404 }
405
412 if (!WillWrite()) [[likely]]
413 return *this;
414 WriteValue(static_cast<std::string_view>(v));
415 return *this;
416 }
417
423 inline Log& operator<<(std::wstring_view v) {
424 if (!WillWrite()) [[likely]]
425 return *this;
426 Write(v);
427 return *this;
428 }
429
435 inline Log& operator<<(const wchar_t* v) {
436 if (!WillWrite()) [[likely]]
437 return *this;
438 Write(v);
439 return *this;
440 }
441
448 if (!WillWrite()) [[likely]]
449 return *this;
450 Write(static_cast<std::wstring_view>(v));
451 return *this;
452 }
453
460 if (!WillWrite()) [[likely]]
461 return *this;
462 Write(static_cast<std::wstring_view>(v));
463 return *this;
464 }
465
471 inline Log& operator<<(std::span<const std::byte> v) {
472 if (!WillWrite()) [[likely]]
473 return *this;
474 Write(v);
475 return *this;
476 }
477
484 if (!WillWrite()) [[likely]]
485 return *this;
486 Write(static_cast<std::span<const std::byte>>(v));
487 return *this;
488 }
489
495 inline Log& operator<<(const StormByte::Size& v) {
496 if (!WillWrite()) [[likely]]
497 return *this;
498 const std::string text = static_cast<std::string>(v);
499 WriteValue(std::string_view{text});
500 return *this;
501 }
502
509 if (!WillWrite()) [[likely]]
510 return *this;
511 const std::string text = static_cast<std::string>(v);
512 WriteValue(std::string_view{text});
513 return *this;
514 }
515
521 inline Log& operator<<(const Level& level) {
522 Write(level);
523 return *this;
524 }
525
531 inline Log& operator<<(std::ostream& (*manip)(std::ostream&)) {
532 Write(manip);
533 return *this;
534 }
535
541 inline Log& operator<<(Log& (*manip)(Log&) noexcept) {
542 Write(manip);
543 return *this;
544 }
545
552 Write(m);
553 return *this;
554 }
555
562 Write(m);
563 return *this;
564 }
565
572 Write(m);
573 return *this;
574 }
575
581 inline Log& operator<<(ColorManip manip) {
582 Write(manip);
583 return *this;
584 }
585
591 inline Log& operator<<(NoColorManip manip) {
592 Write(manip);
593 return *this;
594 }
595
601 inline Log& operator<<(FormatManip manip) {
602 Write(manip);
603 return *this;
604 }
605
612 Write(manip);
613 return *this;
614 }
615
621 inline Log& operator<<(GroupManip manip) {
622 Write(manip);
623 return *this;
624 }
625
632 Write(manip);
633 return *this;
634 }
635
642 Write(manip);
643 return *this;
644 }
645
652 Write(manip);
653 return *this;
654 }
655
657
658 protected:
667 Log(SinkWrite write, SinkManip manip, void* context, const Level& level, std::string_view format);
668
669 std::shared_ptr<Engine> m_engine;
671
676 bool WillWrite() const noexcept;
677
682 bool PrepareLine();
683
688 bool HasOpenOutputLine() const noexcept;
689
694 bool LineDecided() const noexcept;
695
700 bool LineAdmitted() const noexcept;
701
706 virtual bool BeginPayload();
707
713 template <typename T>
714 void WriteValue(const T& v);
715
720 PointerType Clone() const override;
721
726 PointerType Move() override;
727
732 virtual void Write(std::wstring_view v);
733
738 virtual void Write(const wchar_t* v);
739
744 virtual void Write(std::span<const std::byte> v);
745
750 virtual void Write(const Level& level);
751
756 virtual void Write(std::ostream& (*manip)(std::ostream&));
757
762 virtual void Write(Log& (*manip)(Log&) noexcept);
763
768 virtual void Write(RedactManip m);
769
774 virtual void Write(HexManip m);
775
780 virtual void Write(NoHexManip m);
781
786 virtual void Write(ColorManip manip);
787
792 virtual void Write(NoColorManip manip);
793
798 virtual void Write(FormatManip manip);
799
804 virtual void Write(PopFormatManip manip);
805
810 virtual void Write(GroupManip manip);
811
816 virtual void Write(ComponentManip manip);
817
822 virtual void Write(PopComponentManip manip);
823
828 virtual void Write(ResetComponentManip manip);
829 };
830
832 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<bool>(const bool& v);
833 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<char>(const char& v);
834 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<signed char>(const signed char& v);
835 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned char>(const unsigned char& v);
836 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<short>(const short& v);
837 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned short>(const unsigned short& v);
838 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<int>(const int& v);
839 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned int>(const unsigned int& v);
840 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<long>(const long& v);
841 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned long>(const unsigned long& v);
842 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<long long>(const long long& v);
843 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned long long>(const unsigned long long& v);
844 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<float>(const float& v);
845 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<double>(const double& v);
846 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<long double>(const long double& v);
847 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<std::string_view>(const std::string_view& v);
848 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<const char*>(const char* const& v);
850
860 template<typename Ptr>
861 concept LogPointer =
862 StormByte::Type::NullablePointer<Ptr>
863 && StormByte::Type::DerivedFrom<typename std::remove_cvref_t<Ptr>::element_type, Log>;
864
873 template <typename Ptr, typename T>
874 Ptr& operator<<(Ptr& logger, const T& value) noexcept
875 requires LogPointer<Ptr> {
876 if (logger)
877 *logger << value;
878 return logger;
879 }
880
888 template <typename Ptr>
889 Ptr& operator<<(Ptr& logger, const Level& level) noexcept
890 requires LogPointer<Ptr> {
891 if (logger)
892 *logger << level;
893 return logger;
894 }
895
906 template <typename Ptr>
907 Ptr& operator<<(Ptr& logger, std::ostream& (*manip)(std::ostream&)) noexcept
908 requires LogPointer<Ptr> {
909 if (logger)
910 *logger << manip;
911 return logger;
912 }
913}
SmartPointer PointerType
Public streaming facade for the StormByte logger.
Definition log.hxx:111
Log & operator<<(std::span< const std::byte > v)
Stream raw bytes.
Definition log.hxx:471
friend Log & nohumanreadable(Log &log) noexcept
Disable human-readable formatting (raw numbers).
Log & operator<<(PopComponentManip manip)
Pop one component segment from the current thread's stack.
Definition log.hxx:641
Log(SinkWrite write, SinkManip manip, void *context, const Level &level, std::string_view format)
Construct a logger that emits through caller callbacks.
Log & operator<<(const StormByte::Size &v)
Stream a byte count.
Definition log.hxx:495
Log & operator<<(const StormByte::CString &v)
Stream owned UTF-8 bytes.
Definition log.hxx:399
std::shared_ptr< Engine > m_engine
Shared backend.
Definition log.hxx:669
Log & operator<<(RedactManip m)
Apply redaction policy.
Definition log.hxx:551
Log & operator<<(FormatManip manip)
Save the current format and activate a temporary format.
Definition log.hxx:601
Log & operator<<(NoHexManip m)
Disable hex dumps.
Definition log.hxx:571
Log & operator<<(ComponentManip manip)
Push a component segment onto the current thread's stack.
Definition log.hxx:631
StormByte::Clonable< Log >::PointerType PointerType
Owner returned by Clone, Move and Scope.
Definition log.hxx:121
Log & operator<<(const StormByte::BinaryData &v)
Stream owned bytes.
Definition log.hxx:483
Log & operator<<(std::wstring_view v)
Stream wide text.
Definition log.hxx:423
Log & operator<<(ResetComponentManip manip)
Clear the current thread's component stack.
Definition log.hxx:651
friend Log & noredact(Log &log) noexcept
Disable redaction until the next redact / redact(n) / redact_first(n).
Log & operator<<(const StormByte::String::WString &v)
Stream owned wide text.
Definition log.hxx:459
Log(Log &&) noexcept=default
Move constructor.
Log & operator<<(ColorManip manip)
Apply a configured or explicit content color.
Definition log.hxx:581
Log & operator<<(PopFormatManip manip)
Restore the most recently saved format.
Definition log.hxx:611
Log & operator<<(GroupManip manip)
Set the producer group for the current line.
Definition log.hxx:621
Log & operator<<(std::ostream &(*manip)(std::ostream &))
Apply a stream manipulator (e.g.
Definition log.hxx:531
Log & operator<<(const wchar_t *v)
Stream a wide C string.
Definition log.hxx:435
Log & operator<<(Log &(*manip)(Log &) noexcept)
Apply a Log manipulator.
Definition log.hxx:541
friend Log & humanreadable_bytes(Log &log) noexcept
Enable human-readable formatting for byte counts.
StormByte::String::String m_scope_path
Sticky component path; empty = root facade.
Definition log.hxx:670
Log & operator<<(const StormByte::String::String &v)
Stream owned UTF-8 text.
Definition log.hxx:411
bool WillWrite() const noexcept
Whether the current line level will be written.
Log & operator<<(const StormByte::WCString &v)
Stream owned wide bytes.
Definition log.hxx:447
Log & operator<<(const StormByte::ByteSize &v)
Stream an octet count.
Definition log.hxx:508
Log & operator<<(HexManip m)
Dump subsequent payloads as hex bytes until nohex.
Definition log.hxx:561
Log & operator<<(NoColorManip manip)
Disable color for subsequent content.
Definition log.hxx:591
Log(const Log &)=default
Copy constructor.
friend Log & humanreadable_number(Log &log) noexcept
Enable human-readable formatting for numeric values.
Log(std::ostream &out, const Level &level=Level::Info, std::string_view format="[%L] %T")
Construct a Log writing to out.
Definition log.hxx:132
Log & operator<<(const Level &level)
Set the level of the current line.
Definition log.hxx:521
Pointer-like owner of Log or a derived logger.
Definition log.hxx:861
Logger module of the StormByte suite.
void OStreamWrite(void *context, const char *data, std::size_t size)
Write raw bytes into an std::ostream owned by the caller.
Definition log.hxx:77
ThrottlePolicy
Count policy applied before the optional rate bucket.
Definition manipulators.hxx:62
void(*)(void *context, std::ostream &(*manip)(std::ostream &)) SinkManip
Caller-side application of an std::ostream manipulator.
Definition typedefs.hxx:128
Level
Severity levels used by the logger.
Definition typedefs.hxx:87
Color
ANSI foreground colors supported by the logger.
Definition typedefs.hxx:58
void(*)(void *context, const char *data, std::size_t size) SinkWrite
Caller-side write of raw bytes into the sink.
Definition typedefs.hxx:120
void OStreamManip(void *context, std::ostream &(*manip)(std::ostream &))
Apply an std::ostream manipulator in the caller's module.
Definition log.hxx:88
std::ostream & operator<<(std::ostream &stream, ByteSize size)
STL namespace.
Temporarily selects a configured or explicit content color.
Definition manipulators.hxx:208
Selects the sticky component for the current thread.
Definition manipulators.hxx:119
Temporarily replaces the logger format and saves the previous one.
Definition manipulators.hxx:173
Labels the current logging line with a producer group.
Definition manipulators.hxx:91
Dump subsequent payloads as hex bytes until nohex.
Definition manipulators.hxx:306
Disables color for subsequent content until changed.
Definition manipulators.hxx:230
Disable hex dumps and restore default payload formatting.
Definition manipulators.hxx:328
Pops one segment from the current thread's component stack.
Definition manipulators.hxx:161
Restores the most recently saved logger format.
Definition manipulators.hxx:181
Stateful redaction manipulator.
Definition manipulators.hxx:255
Clears the component associated with the current thread.
Definition manipulators.hxx:147
Immutable rule description used by Log::Throttle.
Definition manipulators.hxx:75
#define STORMBYTE_LOGGER_PUBLIC
Definition visibility.h:53