Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
odygrd committed Dec 30, 2024
1 parent a40d996 commit c0473a9
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 15 deletions.
74 changes: 72 additions & 2 deletions docs/json_logging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ Logging Json to Console
auto json_sink = quill::Frontend::create_or_get_sink<quill::JsonConsoleSink>("json_sink_1");
// When logging json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.
// PatternFormatter is only used for non-structured logs formatting
// When logging only json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.
quill::Logger* logger = quill::Frontend::create_or_get_logger(
"json_logger", std::move(json_sink), quill::PatternFormatterOptions { "", "%H:%M:%S.%Qns", quill::Timezone::GmtTime });
Expand Down Expand Up @@ -68,7 +69,8 @@ Logging Json to File
return config;
}());
// When logging json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.
// PatternFormatter is only used for non-structured logs formatting
// When logging only json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.
quill::Logger* logger = quill::Frontend::create_or_get_logger(
"json_logger", std::move(json_sink), quill::PatternFormatterOptions { "", "%H:%M:%S.%Qns", quill::Timezone::GmtTime });
Expand All @@ -82,6 +84,74 @@ Logging Json to File
LOG_INFO(logger, "A json message with {var_1} and {var_2}", var_a, var_b);
}
Customising Json Format
-----------------------

To customize the JSON format, define a custom sink that derives from one of the following classes:

- :cpp:class:`JsonFileSink`
- :cpp:class:`JsonConsoleSink`
- :cpp:class:`RotatingJsonFileSink`

.. code:: cpp
#include "quill/Backend.h"
#include "quill/Frontend.h"
#include "quill/LogMacros.h"
#include "quill/Logger.h"
#include "quill/sinks/JsonSink.h"
class MyJsonConsoleSink : public quill::JsonConsoleSink
{
void generate_json_message(quill::MacroMetadata const* /** log_metadata **/, uint64_t log_timestamp,
std::string_view /** thread_id **/, std::string_view /** thread_name **/,
std::string const& /** process_id **/, std::string_view /** logger_name **/,
quill::LogLevel /** log_level **/, std::string_view log_level_description,
std::string_view /** log_level_short_code **/,
std::vector<std::pair<std::string, std::string>> const* named_args,
std::string_view /** log_message **/,
std::string_view /** log_statement **/, char const* message_format) override
{
// format json as desired
_json_message.append(fmtquill::format(R"({{"timestamp":"{}","log_level":"{}","message":"{}")",
std::to_string(log_timestamp), log_level_description, message_format));
// add log statement arguments as key-values to the json
if (named_args)
{
for (auto const& [key, value] : *named_args)
{
_json_message.append(std::string_view{",\""});
_json_message.append(key);
_json_message.append(std::string_view{"\":\""});
_json_message.append(value);
_json_message.append(std::string_view{"\""});
}
}
}
};
int main()
{
// Start the backend thread
quill::BackendOptions backend_options;
quill::Backend::start(backend_options);
// Frontend
auto json_sink = quill::Frontend::create_or_get_sink<MyJsonConsoleSink>("json_sink_1");
// PatternFormatter is only used for non-structured logs formatting
// When logging only json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.
quill::Logger* logger = quill::Frontend::create_or_get_logger(
"json_logger", std::move(json_sink),
quill::PatternFormatterOptions{"", "%H:%M:%S.%Qns", quill::Timezone::GmtTime});
int var_a = 123;
std::string var_b = "test";
LOG_INFO(logger, "A json message with {var_1} and {var_2}", var_a, var_b);
}
Combining JSON and Standard Log Patterns
----------------------------------------

Expand Down
7 changes: 6 additions & 1 deletion docs/sink_types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,9 @@ The :cpp:class:`JsonFileSink` and :cpp:class:`JsonConsoleSink` enable the creati
for (int i = 0; i < 2; ++i)
{
LOG_INFO(hybrid_logger, "{method} to {endpoint} took {elapsed} ms", "POST", "http://", 10 * i);
}
}
RotatingJsonFileSink
~~~~~~~~~~~~~~~~~~~~

The :cpp:class:`RotatingJsonFileSink` is built on top of the `JsonFileSink` and provides log file rotation based on specified time intervals, file sizes, or daily schedules.
12 changes: 12 additions & 0 deletions docs/users-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ FileSink Class
.. doxygenclass:: FileSink
:members:

RotatingSink Class
----------------------------

.. doxygenclass:: RotatingSink
:members:

RotatingFileSinkConfig Class
----------------------------

Expand All @@ -110,6 +116,12 @@ JsonConsoleSink Class
.. doxygenclass:: JsonConsoleSink
:members:

RotatingJsonFileSink Class
----------------------------

.. doxygenclass:: RotatingJsonFileSink
:members:

CsvWriter Class
---------------

Expand Down
5 changes: 3 additions & 2 deletions examples/json_console_logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ int main()

// Create a json sink
auto json_sink = quill::Frontend::create_or_get_sink<quill::JsonConsoleSink>("json_sink_1");

// When logging json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.

// PatternFormatter is only used for non-structured logs formatting
// When logging only json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.
quill::Logger* logger = quill::Frontend::create_or_get_logger(
"json_logger", std::move(json_sink),
quill::PatternFormatterOptions{"", "%H:%M:%S.%Qns", quill::Timezone::GmtTime});
Expand Down
3 changes: 2 additions & 1 deletion examples/json_console_logging_custom_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ int main()
// Create a json sink
auto json_sink = quill::Frontend::create_or_get_sink<MyJsonConsoleSink>("json_sink_1");

// When logging json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.
// PatternFormatter is only used for non-structured logs formatting
// When logging only json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting.
quill::Logger* logger = quill::Frontend::create_or_get_logger(
"json_logger", std::move(json_sink),
quill::PatternFormatterOptions{"", "%H:%M:%S.%Qns", quill::Timezone::GmtTime});
Expand Down
19 changes: 10 additions & 9 deletions examples/rotating_json_file_logging_custom_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <utility>

/**
* This example demonstrates how to create a RotatingFileSink with daily rotation and automatic
* This example demonstrates how to create a RotatingJsonFileSink with daily rotation and automatic
* rotation based on maximum file size, providing your own custom json formatting
* For additional configuration options, refer to RotatingFileSinkConfig.
*/
Expand All @@ -18,21 +18,22 @@ class CustomJsonSink : public quill::RotatingJsonFileSink
public:
using quill::RotatingJsonFileSink::RotatingJsonFileSink;

QUILL_ATTRIBUTE_HOT void generate_json_message(
quill::MacroMetadata const* log_metadata, uint64_t log_timestamp, std::string_view thread_id,
std::string_view /** thread_name **/, std::string const& /** process_id **/,
std::string_view logger_name, quill::LogLevel /** log_level **/,
std::string_view log_level_description, std::string_view /** log_level_short_code **/,
std::vector<std::pair<std::string, std::string>> const* named_args, std::string_view /** log_message **/,
std::string_view /** log_statement **/, char const* message_format) override
void generate_json_message(quill::MacroMetadata const* log_metadata, uint64_t log_timestamp,
std::string_view thread_id, std::string_view /** thread_name **/,
std::string const& /** process_id **/, std::string_view logger_name,
quill::LogLevel /** log_level **/, std::string_view log_level_description,
std::string_view /** log_level_short_code **/,
std::vector<std::pair<std::string, std::string>> const* named_args,
std::string_view /** log_message **/,
std::string_view /** log_statement **/, char const* message_format) override
{
// e.g. custom time formatting
std::time_t log_timestamp_seconds = log_timestamp / 1'000'000'000;

// Convert to localtime
std::tm* tm = std::localtime(&log_timestamp_seconds);

// Format the time as YYYY MM DD HH:MM:SS
// Format the time as YYYY-MM-DD HH:MM:SS
char formatted_time[20];
std::strftime(formatted_time, sizeof(formatted_time), "%Y-%m-%d %H:%M:%S", tm);

Expand Down

0 comments on commit c0473a9

Please sign in to comment.