Skip to content

Commit fe957db

Browse files
authored
Make Trunk-Recorder logrotate friendly, via syslogFriendly bool config option. (#1080)
* Added a `syslogFriendly` config option, that by default is `false`. When set to `true` creates a `trunk-recorder.log` file that can be rotated with logrotate via logrotate sending a `SIGHUP` signal. Closes #833. * Added `syslogFriendly` information to `CONFIGURE.md` docs.
1 parent 0a13335 commit fe957db

File tree

4 files changed

+47
-9
lines changed

4 files changed

+47
-9
lines changed

docs/CONFIGURE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ There is a list of available Plugins [here](./Plugins.md).
151151
| newCallFromUpdate | | true | **true** / **false** | Allow for UPDATE trunking messages to start a new Call, in addition to GRANT messages. This may result in more Calls with no transmisions, and use more Recorders. The flipside is that it may catch parts of a Call that would have otherwise been missed. Turn this off if you are running out of Recorders. |
152152
| softVocoder | | false | **true** / **false** | Use the Software Decode vocoder from OP25 for P25 and DMR. Give it a try if you are hearing weird tones in your audio. Whether it makes your audio sound better or worse is a matter of preference. |
153153
| recordUUVCalls | | true | **true** / **false** | *P25 only* Record Unit to Unit Voice calls. |
154+
| syslogFriendly | | false | **true** / **false** | Uses static filename `trunk-recorder.log` for use with syslog when `true`. |
154155

155156

156157
## Source Object

trunk-recorder/config.cc

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ namespace sinks = boost::log::sinks;
1414

1515
using namespace std;
1616

17+
// Global log sink for SIGHUP rotation support
18+
boost::shared_ptr<sinks::synchronous_sink<sinks::text_file_backend>> global_log_sink;
19+
1720
void set_logging_level(std::string log_level) {
1821
boost::log::trivial::severity_level sev_level = boost::log::trivial::info;
1922

@@ -67,20 +70,26 @@ void setup_console_log(std::string log_color, std::string time_fmt) {
6770
console_sink->imbue(loc);
6871
}
6972

70-
void setup_file_log(std::string log_dir, std::string log_color, std::string time_fmt) {
71-
boost::shared_ptr<sinks::synchronous_sink<sinks::text_file_backend>> log_sink = logging::add_file_log(
72-
keywords::file_name = log_dir + "/%m-%d-%Y_%H%M_%2N.log",
73-
keywords::rotation_size = 100 * 1024 * 1024,
74-
keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
75-
keywords::auto_flush = true);
73+
void setup_file_log(std::string log_dir, std::string log_color, std::string time_fmt, bool syslog_friendly) {
74+
if (syslog_friendly) {
75+
global_log_sink = logging::add_file_log(
76+
keywords::file_name = log_dir + "/trunk-recorder.log",
77+
keywords::auto_flush = true);
78+
} else {
79+
global_log_sink = logging::add_file_log(
80+
keywords::file_name = log_dir + "/%m-%d-%Y_%H%M_%2N.log",
81+
keywords::rotation_size = 100 * 1024 * 1024,
82+
keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
83+
keywords::auto_flush = true);
84+
}
7685

7786
if ((log_color == "logfile") || (log_color == "all")) {
78-
log_sink->set_formatter(logging::expressions::format("[%1%] (%2%) %3%") %
87+
global_log_sink->set_formatter(logging::expressions::format("[%1%] (%2%) %3%") %
7988
logging::expressions::format_date_time<boost::posix_time::ptime>("TimeStamp", time_fmt) %
8089
logging::expressions::attr<logging::trivial::severity_level>("Severity") %
8190
logging::expressions::smessage);
8291
} else {
83-
log_sink->set_formatter(logging::expressions::format("[%1%] (%2%) %3%") %
92+
global_log_sink->set_formatter(logging::expressions::format("[%1%] (%2%) %3%") %
8493
logging::expressions::format_date_time<boost::posix_time::ptime>("TimeStamp", time_fmt) %
8594
logging::expressions::attr<logging::trivial::severity_level>("Severity") %
8695
logging::expressions::wrap_formatter(NoColorLoggingFormatter{}));
@@ -134,8 +143,9 @@ bool load_config(string config_file, Config &config, gr::top_block_sptr &tb, std
134143

135144
config.log_file = data.value("logFile", false);
136145
config.log_dir = data.value("logDir", "logs");
146+
config.syslog_friendly = data.value("syslogFriendly", false);
137147
if (config.log_file) {
138-
setup_file_log(config.log_dir, config.log_color, "%Y-%m-%d %H:%M:%S.%f");
148+
setup_file_log(config.log_dir, config.log_color, "%Y-%m-%d %H:%M:%S.%f", config.syslog_friendly);
139149
}
140150

141151
double config_ver = data.value("ver", 0.0);
@@ -153,6 +163,7 @@ bool load_config(string config_file, Config &config, gr::top_block_sptr &tb, std
153163

154164
BOOST_LOG_TRIVIAL(info) << "Log to File: " << config.log_file;
155165
BOOST_LOG_TRIVIAL(info) << "Log Directory: " << config.log_dir;
166+
BOOST_LOG_TRIVIAL(info) << "Syslog Friendly Mode: " << config.syslog_friendly;
156167

157168
std::string defaultTempDir = boost::filesystem::current_path().string();
158169

trunk-recorder/global_structs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct Config {
4141
double call_timeout;
4242
bool console_log;
4343
bool log_file;
44+
bool syslog_friendly;
4445
std::string log_color;
4546
int control_message_warn_rate;
4647
int control_retune_limit;

trunk-recorder/monitor_systems.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
#include "monitor_systems.h"
22
#include "recorders/p25_recorder.h"
3+
#include <boost/log/sinks/text_file_backend.hpp>
4+
#include <boost/log/core.hpp>
5+
36
using namespace std;
47

8+
// External reference to global log sink for SIGHUP rotation
9+
extern boost::shared_ptr<boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend>> global_log_sink;
10+
511
volatile sig_atomic_t exit_flag = 0;
12+
volatile sig_atomic_t rotate_log_flag = 0;
613
int exit_code = EXIT_SUCCESS;
714

815
void exit_interupt(int sig) { // can be called asynchronously
916
exit_flag = 1; // set flag
1017
}
1118

19+
void rotate_log_signal(int sig) { // can be called asynchronously
20+
rotate_log_flag = 1; // set flag
21+
}
22+
1223
uint64_t time_since_epoch_millisec() {
1324
using namespace std::chrono;
1425
return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
@@ -848,6 +859,7 @@ int monitor_messages(Config &config, gr::top_block_sptr &tb, std::vector<Source
848859
P25Parser *p25_parser;
849860

850861
signal(SIGINT, exit_interupt);
862+
signal(SIGHUP, rotate_log_signal);
851863

852864
smartnet_parser = new SmartnetParser(systems.front()); // this has to eventually be generic;
853865
p25_parser = new P25Parser();
@@ -874,6 +886,19 @@ int monitor_messages(Config &config, gr::top_block_sptr &tb, std::vector<Source
874886
return exit_code;
875887
}
876888

889+
if (rotate_log_flag) { // SIGHUP received for log rotation
890+
rotate_log_flag = 0; // reset flag
891+
if (global_log_sink) {
892+
BOOST_LOG_TRIVIAL(info) << "Received SIGHUP signal - rotating log file...";
893+
// Flush the sink
894+
global_log_sink->flush();
895+
// Rotate the log file by removing and re-adding the backend
896+
boost::log::core::get()->remove_sink(global_log_sink);
897+
boost::log::core::get()->add_sink(global_log_sink);
898+
BOOST_LOG_TRIVIAL(info) << "Log file rotation complete";
899+
}
900+
}
901+
877902
process_message_queues(systems);
878903
process_recorder_message_queues(calls);
879904

0 commit comments

Comments
 (0)