quill icon indicating copy to clipboard operation
quill copied to clipboard

How can I get a daily log?I couldn't do it with RotatingFileSink

Open shevaxp opened this issue 8 months ago • 5 comments

I want a daily log. AS system_20250508.log at 2025-05-08 and system_20250509.log at 2025-05-09. I try to do this with RotatingFileSink auto file_sink = quill::Frontend::create_or_get_sink<quill::RotatingFileSink>( "system.log", []() { quill::v9::RotatingFileSinkConfig cfg; cfg.set_open_mode('a'); cfg.set_filename_append_option(quill::FilenameAppendOption::StartDate); cfg.set_rotation_time_daily("00:00"); cfg.set_rotation_max_file_size(1024 * 1024 * 50); // 50M return cfg; }(), quill::FileEventNotifier{}); sinks.push_back(file_sink); and I work it between 2025.05.08 23:55 to 2025.05.09 1:00. However, it didn't work as I expected. It did split the log, but the way it split was into 20250508.log and 20250508.1.log.

I wish that it works as 20250508.log 20250508.1.log at 2025-05-08 and 20250509.log 20250509.1.log at 2025-05-09.

How can I get it??

shevaxp avatar May 09 '25 00:05 shevaxp

hey, try with

      cfg.set_filename_append_option(quill::FilenameAppendOption::None);
      cfg.set_rotation_naming_scheme(quill::RotatingFileSinkConfig::RotationNamingScheme::Date);
      cfg.set_timezone(quill::Timezone::LocalTime); // or GmtTime

Current active written log file won't have a date, but any file that was rotated will have the date that was initially opened in the filename

odygrd avatar May 09 '25 02:05 odygrd

There are some mistakes in codes. And it couldn't work with your code. my code is auto file_sink = quill::Frontend::create_or_get_sink<quill::RotatingFileSink>( "sys.log", []() { quill::v9::RotatingFileSinkConfig cfg; cfg.set_open_mode('a'); // cfg.set_filename_append_option(quill::FilenameAppendOption::StartDate); // cfg.set_rotation_time_daily("00:00"); // daily cut // cfg.set_rotation_max_file_size(1024 * 1024 * 500); // 500M cfg.set_filename_append_option(quill::FilenameAppendOption::None); cfg.set_rotation_naming_scheme(quill::RotatingFileSinkConfig::RotationNamingScheme::Date); cfg.set_timezone(quill::Timezone::LocalTime); // cfg.set_rotation_max_file_size(1024); // 500M return cfg; }(), quill::FileEventNotifier{}); and I find that it couldn't append date to sys.log at _clean_and_recover_files function.

shevaxp avatar May 09 '25 07:05 shevaxp

Hey, there is no _clean_and_recover_files when RotationNamingScheme::Date is used, it is not needed, so it doesn't do anything

I tried the below example and the behaviour seems as expected, I am not exactly sure what behaviour you are trying to achieve

For example if you run the below example at 23:59 and maybe add some sleep delay between LOG_INFO calls you can get rotated files like this

sys.20250510.1.log // rotated due to size 1024 - size rotation sys.20250510.log // rotated due to size 1024 - size rotation sys.20250509.log // rotated - daily rotation sys.log // current open log file

#include "quill/Backend.h"
#include "quill/Frontend.h"
#include "quill/LogMacros.h"
#include "quill/Logger.h"
#include "quill/sinks/RotatingFileSink.h"

#include <utility>

int main()
{
  // Start the backend thread
  quill::BackendOptions backend_options;
  quill::Backend::start(backend_options);

  auto file_sink = quill::Frontend::create_or_get_sink<quill::RotatingFileSink>(
    "sys.log",
    []()
    {
      quill::v9::RotatingFileSinkConfig cfg;
      cfg.set_open_mode('a');
      cfg.set_rotation_time_daily("00:00"); // daily cut
      cfg.set_filename_append_option(quill::FilenameAppendOption::None);
      cfg.set_rotation_naming_scheme(quill::RotatingFileSinkConfig::RotationNamingScheme::Date);
      cfg.set_timezone(quill::Timezone::LocalTime);
      cfg.set_rotation_max_file_size(1024);
      return cfg;
    }(),
    quill::FileEventNotifier{});

  quill::Logger* logger = quill::Frontend::create_or_get_logger(
    "root", std::move(file_sink),
    quill::PatternFormatterOptions{"%(time) [%(thread_id)] %(short_source_location:<28) "
                                   "LOG_%(log_level:<9) %(logger:<12) %(message)",
                                   "%H:%M:%S.%Qns", quill::Timezone::GmtTime});

  for (int i = 0; i < 20; ++i)
  {
    LOG_INFO(logger, "Hello from rotating logger, index is {}", i);
  }
}

odygrd avatar May 10 '25 00:05 odygrd

I don't think it can run very well. It works well as Index model. The fundamental problem actually lies in the fact that in the _rotate_files function, In this function ,we need to redirect this ->_filename,but no code do this. As Index model,wo don't need to redicect. Because it turn sys.log,sys.1.log... to sys.1.log sys.2.log...... then write sys.log also. It's OK. but rotating by date,wo need redirect this ->_filename and reopen it.

shevaxp avatar May 12 '25 08:05 shevaxp

After reviewing the RotatingSink class and _rotate_files function, I believe the current implementation is working as intended.

Current Rotation Model

sys.20250509.log    // Yesterday's rotated file
sys.log             // Current active file (always this name)

In this model, we don't need to redirect this->_filename because:

  1. The active file is always the base filename (sys.log)
  2. After rotation, we correctly reopen the same base filename

If you want a different rotation pattern where the active file includes the current date, it is currently not supported, you would need to create a custom sink. For example https://github.com/odygrd/quill/blob/master/examples/user_defined_sink.cpp

odygrd avatar May 24 '25 16:05 odygrd