@@ -101,8 +101,6 @@ BOOST_LOG_ATTRIBUTE_KEYWORD(named_scope, "Scope", logr::attributes::named_scope:
101
101
BOOST_LOG_ATTRIBUTE_KEYWORD (utc_timestamp, " Timestamp" , logr::attributes::utc_clock::value_type);
102
102
103
103
namespace mtconnect ::configuration {
104
- AGENT_LIB_API
105
- boost::log::trivial::logger_type *gAgentLogger = nullptr ;
106
104
107
105
AgentConfiguration::AgentConfiguration ()
108
106
: m_context {make_unique<AsyncContext>()}, m_monitorTimer(m_context->get ())
@@ -235,8 +233,10 @@ namespace mtconnect::configuration {
235
233
#endif
236
234
m_context.reset ();
237
235
238
- if (m_sink)
239
- m_sink.reset ();
236
+ for (auto &[channelName, logChannel] : m_logChannels)
237
+ logChannel.m_logSink .reset ();
238
+
239
+ m_logChannels.clear ();
240
240
241
241
logr::core::get ()->remove_all_sinks ();
242
242
}
@@ -432,9 +432,8 @@ namespace mtconnect::configuration {
432
432
433
433
void AgentConfiguration::setLoggingLevel (const logr::trivial::severity_level level)
434
434
{
435
- using namespace logr ::trivial;
436
- m_logLevel = level;
437
- logr::core::get ()->set_filter (severity >= level);
435
+ for ( auto &[channelName, logChannel] : m_logChannels)
436
+ logChannel.m_logLevel = level;
438
437
}
439
438
440
439
static logr::trivial::severity_level StringToLogLevel (const std::string &level)
@@ -476,25 +475,54 @@ namespace mtconnect::configuration {
476
475
void AgentConfiguration::configureLogger (const ptree &config)
477
476
{
478
477
using namespace logr ::trivial;
479
- namespace kw = boost::log::keywords;
480
478
namespace expr = logr::expressions;
481
479
482
- logr::core::get ()->remove_all_sinks ();
483
- m_sink.reset ();
480
+ auto core = logr::core::get ();
481
+
482
+ core->remove_all_sinks ();
484
483
485
484
// // Add the commonly used attributes; includes TimeStamp, ProcessID and ThreadID and others
486
485
logr::add_common_attributes ();
487
- logr:: core::get () ->add_global_attribute (" Scope" , logr::attributes::named_scope ());
488
- logr:: core::get () ->add_global_attribute (logr::aux::default_attribute_names::thread_id (),
486
+ core->add_global_attribute (" Scope" , logr::attributes::named_scope ());
487
+ core->add_global_attribute (logr::aux::default_attribute_names::thread_id (),
489
488
logr::attributes::current_thread_id ());
490
- logr::core::get ()->add_global_attribute (" Timestamp" , logr::attributes::utc_clock ());
489
+ core->add_global_attribute (" Timestamp" , logr::attributes::utc_clock ());
490
+
491
+ m_logger = &::boost::log::trivial::logger::get ();
492
+
493
+ auto formatter =
494
+ expr::stream << expr::format_date_time<boost::posix_time::ptime>(" Timestamp" ,
495
+ " %Y-%m-%dT%H:%M:%S.%fZ " )
496
+ << " ("
497
+ << expr::attr<logr::attributes::current_thread_id::value_type>(" ThreadID" )
498
+ << " ) [" << severity << " ] " << named_scope << " : " << expr::smessage;
499
+
500
+ configureLoggerChannel (" agent" , config, formatter);
501
+ }
502
+
503
+ void AgentConfiguration::configureLoggerChannel (const std::string &channelName, const ptree &config, std::optional<boost::log::basic_formatter<char >> formatter)
504
+ {
505
+ using namespace logr ::trivial;
506
+ namespace expr = logr::expressions;
507
+ namespace kw = boost::log::keywords;
508
+
509
+ auto &logChannel = m_logChannels[channelName];
510
+ if (logChannel.m_channelName == " " )
511
+ logChannel.m_channelName = channelName;
512
+
513
+ if (!formatter)
514
+ {
515
+ formatter =
516
+ expr::stream << expr::format_date_time<boost::posix_time::ptime>(" Timestamp" ,
517
+ " %Y-%m-%dT%H:%M:%S.%fZ " )
518
+ << std::setw (7 ) << std::left << boost::log::trivial::severity << " " << expr::message;
519
+ }
491
520
492
521
ptree empty;
493
522
auto logger = config.get_child_optional (" logger_config" ).value_or (empty);
494
- setLoggingLevel (severity_level::info);
495
523
496
- static const string defaultFileName { " agent .log" } ;
497
- static const string defaultArchivePattern ( " agent_ %Y-%m-%d_%H-%M-%S_%N.log" ) ;
524
+ const string defaultFileName = channelName + " .log" ;
525
+ const string defaultArchivePattern = channelName + " _ %Y-%m-%d_%H-%M-%S_%N.log" ;
498
526
499
527
ConfigOptions options;
500
528
AddDefaultedOptions (logger, options,
@@ -507,19 +535,10 @@ namespace mtconnect::configuration {
507
535
{{" output" , string ()}, {" level" , string ()}, {" logging_level" , string ()}});
508
536
509
537
auto output = GetOption<string>(options, " output" );
510
- auto level = setLoggingLevel (
538
+ auto level = StringToLogLevel (
511
539
GetOption<string>(options, " level" )
512
540
.value_or (GetOption<string>(options, " logging_level" ).value_or (" info" s)));
513
541
514
- gAgentLogger = m_logger = &::boost::log::trivial::logger::get ();
515
-
516
- auto formatter =
517
- expr::stream << expr::format_date_time<boost::posix_time::ptime>(" Timestamp" ,
518
- " %Y-%m-%dT%H:%M:%S.%fZ " )
519
- << " ("
520
- << expr::attr<logr::attributes::current_thread_id::value_type>(" ThreadID" )
521
- << " ) [" << severity << " ] " << named_scope << " : " << expr::smessage;
522
-
523
542
if (m_isDebug || (output && (*output == " cout" || *output == " cerr" )))
524
543
{
525
544
ostream *out;
@@ -528,11 +547,21 @@ namespace mtconnect::configuration {
528
547
else
529
548
out = &std::cout;
530
549
531
- logr::add_console_log (*out, kw::format = formatter, kw::auto_flush = true );
532
-
533
550
if (m_isDebug && level >= severity_level::debug)
534
- setLoggingLevel (severity_level::debug);
551
+ level = severity_level::debug;
552
+
553
+ auto sink = boost::make_shared<console_sink>();
554
+ logChannel.m_logSink = sink;
555
+ logChannel.m_logLevel = level;
556
+ logChannel.m_logFileName = output.value_or (" debug" );
557
+
558
+ sink->locked_backend ()->add_stream (boost::shared_ptr<std::ostream>(out, boost::null_deleter ()));
559
+ sink->locked_backend ()->auto_flush (true );
560
+
561
+ sink->set_formatter (formatter.value ());
562
+ sink->set_filter (expr::attr<std::string>(" Channel" ) == logChannel.m_channelName && severity >= logChannel.m_logLevel );
535
563
564
+ logr::core::get ()->add_sink (sink);
536
565
return ;
537
566
}
538
567
@@ -560,16 +589,23 @@ namespace mtconnect::configuration {
560
589
}
561
590
}
562
591
563
- m_maxLogFileSize = ConvertFileSize (options, " max_size" , m_maxLogFileSize);
564
- m_logRotationSize = ConvertFileSize (options, " rotation_size" , m_logRotationSize);
592
+ auto &maxLogFileSize = logChannel.m_maxLogFileSize ;
593
+ auto &logRotationSize = logChannel.m_logRotationSize ;
594
+ auto &rotationLogInterval = logChannel.m_rotationLogInterval ;
595
+ auto &logArchivePattern = logChannel.m_logArchivePattern ;
596
+ auto &logDirectory = logChannel.m_logDirectory ;
597
+ auto &logFileName = logChannel.m_logFileName ;
598
+
599
+ maxLogFileSize = ConvertFileSize (options, " max_size" , maxLogFileSize);
600
+ logRotationSize = ConvertFileSize (options, " rotation_size" , logRotationSize);
565
601
int max_index = *GetOption<int >(options, " max_index" );
566
602
567
603
if (auto sched = GetOption<string>(options, " schedule" ))
568
604
{
569
605
if (*sched == " DAILY" )
570
- m_rotationLogInterval = 24 ;
606
+ rotationLogInterval = 24 ;
571
607
else if (*sched == " WEEKLY" )
572
- m_rotationLogInterval = 168 ;
608
+ rotationLogInterval = 168 ;
573
609
else if (*sched != " NEVER" )
574
610
LOG (error) << " Invalid schedule value." ;
575
611
}
@@ -578,52 +614,55 @@ namespace mtconnect::configuration {
578
614
auto file_name = *GetOption<string>(options, " file_name" );
579
615
auto archive_pattern = *GetOption<string>(options, " archive_pattern" );
580
616
581
- m_logArchivePattern = fs::path (archive_pattern);
582
- if (!m_logArchivePattern .has_filename ())
617
+ logArchivePattern = fs::path (archive_pattern);
618
+ if (!logArchivePattern .has_filename ())
583
619
{
584
- m_logArchivePattern =
585
- m_logArchivePattern / archiveFileName (get<string>(options[" file_name" ]));
620
+ logArchivePattern =
621
+ logArchivePattern / archiveFileName (get<string>(options[" file_name" ]));
586
622
}
587
623
588
- if (m_logArchivePattern .is_relative ())
589
- m_logArchivePattern = fs::current_path () / m_logArchivePattern ;
624
+ if (logArchivePattern .is_relative ())
625
+ logArchivePattern = fs::current_path () / logArchivePattern ;
590
626
591
627
// Get the log directory from the archive path.
592
- m_logDirectory = m_logArchivePattern .parent_path ();
628
+ logDirectory = logArchivePattern .parent_path ();
593
629
594
630
// If the file name does not specify a log directory, use the
595
631
// archive directory
596
- m_logFileName = fs::path (file_name);
597
- if (!m_logFileName.has_parent_path ())
598
- m_logFileName = m_logDirectory / m_logFileName;
599
- else if (m_logFileName.is_relative ())
600
- m_logFileName = fs::current_path () / m_logFileName;
601
-
602
- boost::shared_ptr<logr::core> core = logr::core::get ();
632
+ logFileName = fs::path (file_name);
633
+ if (!logFileName.has_parent_path ())
634
+ logFileName = logDirectory / logFileName;
635
+ else if (logFileName.is_relative ())
636
+ logFileName = fs::current_path () / logFileName;
603
637
604
638
// Create a text file sink
605
- m_sink = boost::make_shared<text_sink>(
606
- kw::file_name = m_logFileName , kw::target_file_name = m_logArchivePattern .filename (),
607
- kw::auto_flush = true , kw::rotation_size = m_logRotationSize ,
639
+ auto sink = boost::make_shared<text_sink>(
640
+ kw::file_name = logFileName , kw::target_file_name = logArchivePattern .filename (),
641
+ kw::auto_flush = true , kw::rotation_size = logRotationSize ,
608
642
kw::open_mode = ios_base::out | ios_base::app, kw::format = formatter);
609
643
644
+ logChannel.m_logSink = sink;
645
+ logChannel.m_logLevel = level;
646
+
610
647
// Set up where the rotated files will be stored
611
- m_sink ->locked_backend ()->set_file_collector (logr::sinks::file::make_collector (
612
- kw::target = m_logDirectory , kw::max_size = m_maxLogFileSize , kw::max_files = max_index));
648
+ sink ->locked_backend ()->set_file_collector (logr::sinks::file::make_collector (
649
+ kw::target = logDirectory , kw::max_size = maxLogFileSize , kw::max_files = max_index));
613
650
614
- if (m_rotationLogInterval > 0 )
651
+ if (rotationLogInterval > 0 )
615
652
{
616
- m_sink ->locked_backend ()->set_time_based_rotation (
653
+ sink ->locked_backend ()->set_time_based_rotation (
617
654
logr::sinks::file::rotation_at_time_interval (
618
- boost::posix_time::hours (m_rotationLogInterval )));
655
+ boost::posix_time::hours (rotationLogInterval )));
619
656
}
620
657
621
658
// Upon restart, scan the target directory for files matching the file_name pattern
622
- m_sink->locked_backend ()->scan_for_files ();
623
- m_sink->set_formatter (formatter);
659
+ sink->locked_backend ()->scan_for_files ();
660
+
661
+ sink->set_formatter (formatter.value ());
662
+ sink->set_filter (expr::attr<std::string>(" Channel" ) == logChannel.m_channelName && severity >= logChannel.m_logLevel );
624
663
625
664
// Formatter for the logger
626
- core->add_sink (m_sink );
665
+ logr:: core::get () ->add_sink (sink );
627
666
}
628
667
629
668
static std::string ExpandValue (const std::map<std::string, std::string> &values,
@@ -736,8 +775,8 @@ namespace mtconnect::configuration {
736
775
cerr << " could not load config file: " << e.what () << endl;
737
776
throw e;
738
777
}
739
- // if (!m_loggerFile)
740
- if (!m_sink )
778
+
779
+ if (m_logChannels. empty () )
741
780
{
742
781
configureLogger (config);
743
782
}
0 commit comments