Replies: 5 comments 2 replies
-
hey,
e.g. void CustomHandler::write(fmt_buffer_t const& formatted_log_message, quill::TransitEvent const& log_event)
{
std::pair<MacroMetadata, detail::FormatToFn> const mf = log_event.header.metadata_and_format_fn();
MacroMetadata const& macro_metadata = mf.first;
} Let me know if that works for you
Then the backend thread (which is the non critical path) will read the copy of the object and pass it to It might worth to read this as you need to be aware of the user defined types you are logging https://github.com/odygrd/quill/blob/master/quill/include/quill/detail/Serialize.h#L130 It is also possible to pass objects as strings as you said if you use
a. Spawn another thread that is dedicated to database commits. Then pass the logs to that thread via a queue class CustomHandler : public quill::Handler
{
CustomHandler(SPSC* queue) : _queue(queue) {}
void CustomHandler::write(fmt_buffer_t const& formatted_log_message, quill::TransitEvent const& log_event) override
{
std::pair<MacroMetadata, detail::FormatToFn> const mf = log_event.header.metadata_and_format_fn();
MacroMetadata const& macro_metadata = mf.first;
// send record to the db commit thread
_queue.push(...)
}
};
// And a DbCommit thread that
// _queue.pop();
// batch_commits
// send the batch every eg 1 second b. Batch your commits in e.g. class CustomHandler : public quill::Handler
{
CustomHandler() = default;
void CustomHandler::write(fmt_buffer_t const& formatted_log_message, quill::TransitEvent const& log_event) override
{
std::pair<MacroMetadata, detail::FormatToFn> const mf = log_event.header.metadata_and_format_fn();
MacroMetadata const& macro_metadata = mf.first;
// add the log record to the commit batch
}
// Need a better name for this function
// This is called periodically by the backend worker thread and does not exist at the moment
void CustomHandler::loop() override
{
if ((now - last_time_commited) > interval)
{
// commit the batch to the database
}
}
}; |
Beta Was this translation helpful? Give feedback.
-
Hey! Thank you for your fast and detailed response! void Custom_handler::write(quill::fmt_buffer_t const &formatted_log_message, quill::TransitEvent const &log_event) {
std::pair<quill::MacroMetadata, quill::detail::FormatToFn> const mf = log_event.header.metadata_and_format_fn();
quill::MacroMetadata const ¯o_metadata = mf.first;
std::string log_message{log_event.formatted_msg.data(), log_event.formatted_msg.size()};
std::size_t type_pos = log_message.find("<<TYPE>>");
if (type_pos == std::string::npos) {
global_logger_db.insert_data(Log_data_info(formatter().format_timestamp(
std::chrono::nanoseconds{log_event.header.timestamp}),
quill::loglevel_to_string(macro_metadata.level()),
log_event.thread_id,
log_event.header.logger_details->name()),
std::move(log_message));
return;
}
.
. After some time, I managed to figure out how to log user defined types as well, based on the links you provided, which moved the serialization of the type off from the hot-path into the backendThread, which also helped performance. After further research, I was able to figure out how to log any kind of, user defined or external objects as well. Good advice on batching my commits! I haven't done anything like that, could you give me a starter there, or just say a few tips that I should pay attention to, in order to implement the batching the right way? Thank you for your time and asnwer! |
Beta Was this translation helpful? Give feedback.
-
Glad to hear it worked for you ! I haven't worked much with databases, but i had a case in the past where batch commits made a huge difference in performance. I have already added this function on the latest version which will be called when the backend thread is idle You can do the batch commits there. this function will get called when the thread has no more messages to process. It has the disadvantage that if a hot thread is logging in a loop for ever, then the backend thread will always have work to do and it will never get called, but it is unlikely under real scenarios. Also keep in mind that doing too much heavy work in |
Beta Was this translation helpful? Give feedback.
-
Hello! |
Beta Was this translation helpful? Give feedback.
-
@GJanos note that in the latest master I added a function that returns the void CustomHandler::write(fmt_buffer_t const& formatted_log_message, quill::TransitEvent const& log_event)
{
MacroMetadata const macro_metadata = log_event.metadata();
} |
Beta Was this translation helpful? Give feedback.
-
Hello!
I am currently making a logging library, for which I use quill as a base. I am very pleased with the current features, but I have one big problem, that I cannot seem to overcome.
My main focus is to log any kinds of data (user made objects, json, basic strings) to a given database. Quill has a support for it, by enabling me to inherit from the Handler class, than overriding the write function inside it.
But here I cannot get back the metadata that got parsed to be inside of the formatted_log_message, not even the TransitEvent is containing all the metadata that is needed for me. To fix this issue I first tried to change the library ,than used string opeartions to find the related information that I needed from the formatted_log_message.
These information can be found in the BackendWorker::_write_transit_event function as macro_metadata.
I tried to change the libraries code so that the MacroMetadata also gets passed into the handler->write function as a parameter, but failed. Performance is really important in my case, so I would like to remove the unnecessary string operations and somehow would make MacroMetadata available for the write function as well, because in the current case, to the best of my knowledge, there is no way to access the MacroMetadata's contents.
I am constructing log_data_info classes(that contain the metadata of the log, that are relevant for me) and pass them to functions that insert them later on into databases.
global_logger_db.insert_data(Log_data_info(std::move(timestamp), std::move(log_level), log_event.thread_id, log_event.header.logger_details->name()), std::move(log_message));
Instead of this it would be so nice to just:
I hope that you understood my concern, if not please write back to me so I can clarify it more. Thank you for your time!
Beta Was this translation helpful? Give feedback.
All reactions