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
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::Safe::String Format() const;
225
232 virtual Log& Format(std::string_view component, std::string_view format);
233
239 virtual StormByte::Safe::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
399 inline Log& operator<<(const std::string& v) {
400 if (!WillWrite()) [[likely]]
401 return *this;
402 WriteValue(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
424 if (!WillWrite()) [[likely]]
425 return *this;
426 WriteValue(static_cast<std::string_view>(v));
427 return *this;
428 }
429
435 inline Log& operator<<(std::wstring_view v) {
436 if (!WillWrite()) [[likely]]
437 return *this;
438 Write(v);
439 return *this;
440 }
441
447 inline Log& operator<<(const wchar_t* v) {
448 if (!WillWrite()) [[likely]]
449 return *this;
450 Write(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
472 if (!WillWrite()) [[likely]]
473 return *this;
474 Write(static_cast<std::wstring_view>(v));
475 return *this;
476 }
477
483 inline Log& operator<<(std::span<const std::byte> v) {
484 if (!WillWrite()) [[likely]]
485 return *this;
486 Write(v);
487 return *this;
488 }
489
496 if (!WillWrite()) [[likely]]
497 return *this;
498 Write(static_cast<std::span<const std::byte>>(v));
499 return *this;
500 }
501
507 inline Log& operator<<(const StormByte::Size& v) {
508 if (!WillWrite()) [[likely]]
509 return *this;
510 const std::string text = static_cast<std::string>(v);
511 WriteValue(std::string_view{text});
512 return *this;
513 }
514
521 if (!WillWrite()) [[likely]]
522 return *this;
523 const std::string text = static_cast<std::string>(v);
524 WriteValue(std::string_view{text});
525 return *this;
526 }
527
533 inline Log& operator<<(const Level& level) {
534 Write(level);
535 return *this;
536 }
537
543 inline Log& operator<<(std::ostream& (*manip)(std::ostream&)) {
544 Write(manip);
545 return *this;
546 }
547
553 inline Log& operator<<(Log& (*manip)(Log&) noexcept) {
554 Write(manip);
555 return *this;
556 }
557
564 Write(m);
565 return *this;
566 }
567
574 Write(m);
575 return *this;
576 }
577
584 Write(m);
585 return *this;
586 }
587
593 inline Log& operator<<(ColorManip manip) {
594 Write(manip);
595 return *this;
596 }
597
603 inline Log& operator<<(NoColorManip manip) {
604 Write(manip);
605 return *this;
606 }
607
613 inline Log& operator<<(FormatManip manip) {
614 Write(manip);
615 return *this;
616 }
617
624 Write(manip);
625 return *this;
626 }
627
633 inline Log& operator<<(GroupManip manip) {
634 Write(manip);
635 return *this;
636 }
637
644 Write(manip);
645 return *this;
646 }
647
654 Write(manip);
655 return *this;
656 }
657
664 Write(manip);
665 return *this;
666 }
667
669
670 protected:
679 Log(SinkWrite write, SinkManip manip, void* context, const Level& level, std::string_view format);
680
681 std::shared_ptr<Engine> m_engine;
683
688 bool WillWrite() const noexcept;
689
694 bool PrepareLine();
695
700 bool HasOpenOutputLine() const noexcept;
701
706 bool LineDecided() const noexcept;
707
712 bool LineAdmitted() const noexcept;
713
718 virtual bool BeginPayload();
719
725 template <typename T>
726 void WriteValue(const T& v);
727
732 PointerType Clone() const override;
733
738 PointerType Move() override;
739
744 virtual void Write(std::wstring_view v);
745
750 virtual void Write(const wchar_t* v);
751
756 virtual void Write(std::span<const std::byte> v);
757
762 virtual void Write(const Level& level);
763
768 virtual void Write(std::ostream& (*manip)(std::ostream&));
769
774 virtual void Write(Log& (*manip)(Log&) noexcept);
775
780 virtual void Write(RedactManip m);
781
786 virtual void Write(HexManip m);
787
792 virtual void Write(NoHexManip m);
793
798 virtual void Write(ColorManip manip);
799
804 virtual void Write(NoColorManip manip);
805
810 virtual void Write(FormatManip manip);
811
816 virtual void Write(PopFormatManip manip);
817
822 virtual void Write(GroupManip manip);
823
828 virtual void Write(ComponentManip manip);
829
834 virtual void Write(PopComponentManip manip);
835
840 virtual void Write(ResetComponentManip manip);
841 };
842
844 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<bool>(const bool& v);
845 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<char>(const char& v);
846 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<signed char>(const signed char& v);
847 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned char>(const unsigned char& v);
848 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<short>(const short& v);
849 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned short>(const unsigned short& v);
850 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<int>(const int& v);
851 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned int>(const unsigned int& v);
852 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<long>(const long& v);
853 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned long>(const unsigned long& v);
854 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<long long>(const long long& v);
855 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<unsigned long long>(const unsigned long long& v);
856 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<float>(const float& v);
857 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<double>(const double& v);
858 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<long double>(const long double& v);
859 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<std::string_view>(const std::string_view& v);
860 extern template STORMBYTE_LOGGER_PUBLIC void Log::WriteValue<const char*>(const char* const& v);
862
872 template<typename Ptr>
873 concept LogPointer =
874 StormByte::Type::NullablePointer<Ptr>
875 && StormByte::Type::DerivedFrom<typename std::remove_cvref_t<Ptr>::element_type, Log>;
876
885 template <typename Ptr, typename T>
886 Ptr& operator<<(Ptr& logger, const T& value) noexcept
887 requires LogPointer<Ptr> {
888 if (logger)
889 *logger << value;
890 return logger;
891 }
892
900 template <typename Ptr>
901 Ptr& operator<<(Ptr& logger, const Level& level) noexcept
902 requires LogPointer<Ptr> {
903 if (logger)
904 *logger << level;
905 return logger;
906 }
907
918 template <typename Ptr>
919 Ptr& operator<<(Ptr& logger, std::ostream& (*manip)(std::ostream&)) noexcept
920 requires LogPointer<Ptr> {
921 if (logger)
922 *logger << manip;
923 return logger;
924 }
925}
Public streaming facade for the StormByte logger.
Definition log.hxx:111
Log & operator<<(const StormByte::Safe::CString &v)
Stream owned UTF-8 bytes.
Definition log.hxx:411
Log & operator<<(std::span< const std::byte > v)
Stream raw bytes.
Definition log.hxx:483
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:653
Log & operator<<(const std::string &v)
Stream caller-owned narrow text without passing its std::string object across the DLL boundary.
Definition log.hxx:399
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:507
std::shared_ptr< Engine > m_engine
Shared backend.
Definition log.hxx:681
Log & operator<<(RedactManip m)
Apply redaction policy.
Definition log.hxx:563
Log & operator<<(FormatManip manip)
Save the current format and activate a temporary format.
Definition log.hxx:613
Log & operator<<(NoHexManip m)
Disable hex dumps.
Definition log.hxx:583
Log & operator<<(ComponentManip manip)
Push a component segment onto the current thread's stack.
Definition log.hxx:643
Log & operator<<(const StormByte::BinaryData &v)
Stream owned bytes.
Definition log.hxx:495
Log & operator<<(std::wstring_view v)
Stream wide text.
Definition log.hxx:435
Log & operator<<(ResetComponentManip manip)
Clear the current thread's component stack.
Definition log.hxx:663
friend Log & noredact(Log &log) noexcept
Disable redaction until the next redact / redact(n) / redact_first(n).
Log & operator<<(const StormByte::Safe::WCString &v)
Stream owned wide bytes.
Definition log.hxx:459
Log & operator<<(const StormByte::Safe::WString &v)
Stream owned wide text.
Definition log.hxx:471
Log(Log &&) noexcept=default
Move constructor.
Log & operator<<(ColorManip manip)
Apply a configured or explicit content color.
Definition log.hxx:593
Log & operator<<(PopFormatManip manip)
Restore the most recently saved format.
Definition log.hxx:623
Log & operator<<(const StormByte::Safe::String &v)
Stream owned UTF-8 text.
Definition log.hxx:423
Log & operator<<(GroupManip manip)
Set the producer group for the current line.
Definition log.hxx:633
Log & operator<<(std::ostream &(*manip)(std::ostream &))
Apply a stream manipulator (e.g.
Definition log.hxx:543
Log & operator<<(const wchar_t *v)
Stream a wide C string.
Definition log.hxx:447
StormByte::Safe::String m_scope_path
Sticky component path; empty = root facade.
Definition log.hxx:682
Log & operator<<(Log &(*manip)(Log &) noexcept)
Apply a Log manipulator.
Definition log.hxx:553
friend Log & humanreadable_bytes(Log &log) noexcept
Enable human-readable formatting for byte counts.
bool WillWrite() const noexcept
Whether the current line level will be written.
Log & operator<<(const StormByte::ByteSize &v)
Stream an octet count.
Definition log.hxx:520
Log & operator<<(HexManip m)
Dump subsequent payloads as hex bytes until nohex.
Definition log.hxx:573
StormByte::Safe::Clonable< Log >::PointerType PointerType
Owner returned by Clone, Move and Scope.
Definition log.hxx:121
Log & operator<<(NoColorManip manip)
Disable color for subsequent content.
Definition log.hxx:603
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:533
Pointer-like owner of Log or a derived logger.
Definition log.hxx:873
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