Skip to content

Commit b865912

Browse files
authored
Add support for logrotate in sairedis (sonic-net#192)
* Add support for logrotate in sairedis * Fix attribute id access * Fix logrotate variable name * Address comments
1 parent e98ea8f commit b865912

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

lib/inc/sai_redis.h

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ extern std::string joinFieldValues(
3636
_In_ const std::vector<swss::FieldValueTuple> &values);
3737

3838
extern volatile bool g_useTempView;
39+
extern volatile bool g_logrotate;
3940

4041
// other global declarations
4142

lib/inc/sairedis.h

+19
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,25 @@ typedef enum _sai_redis_switch_attr_t
8282
*/
8383
SAI_REDIS_SWITCH_ATTR_RECORDING_OUTPUT_DIR,
8484

85+
/**
86+
* @brief Log rotate.
87+
*
88+
* This is action attribute. When set to true then at the next log line
89+
* write it will close recording file and open it again. This is desired
90+
* when doing log rotate, since sairedis holds handle to recording file for
91+
* performance reasons. We are assuming logrotate will move recording file
92+
* to ".n" suffix, and when we reopen file, we will actually create new
93+
* one.
94+
*
95+
* This attribute is only setting variable in memroy, it's safe to call
96+
* this from signal handler.
97+
*
98+
* @type bool
99+
* @flags CREATE_AND_SET
100+
* @default false
101+
*/
102+
SAI_REDIS_SWITCH_ATTR_PERFORM_LOG_ROTATE,
103+
85104
} sai_redis_switch_attr_t;
86105

87106
/*

lib/src/sai_redis_record.cpp

+38-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,34 @@ std::string getTimestamp()
2222

2323
// recording needs to be enabled explicitly
2424
volatile bool g_record = false;
25+
volatile bool g_logrotate = false;
2526

2627
std::ofstream recording;
2728
std::mutex g_recordMutex;
2829

30+
std::string recfile = "dummy.rec";
31+
32+
void logfileReopen()
33+
{
34+
SWSS_LOG_ENTER();
35+
36+
recording.close();
37+
38+
/*
39+
* On log rotate we will use the same file name, we are assuming that
40+
* logrotate deamon move filename to filename.1 and we will create new
41+
* empty file here.
42+
*/
43+
44+
recording.open(recfile);
45+
46+
if (!recording.is_open())
47+
{
48+
SWSS_LOG_ERROR("failed to open recording file %s: %s", recfile.c_str(), strerror(errno));
49+
return;
50+
}
51+
}
52+
2953
void recordLine(std::string s)
3054
{
3155
std::lock_guard<std::mutex> lock(g_recordMutex);
@@ -36,9 +60,21 @@ void recordLine(std::string s)
3660
{
3761
recording << getTimestamp() << "|" << s << std::endl;
3862
}
39-
}
4063

41-
std::string recfile = "dummy.rec";
64+
if (g_logrotate)
65+
{
66+
g_logrotate = false;
67+
68+
logfileReopen();
69+
70+
/* double check since reopen could fail */
71+
72+
if (recording.is_open())
73+
{
74+
recording << getTimestamp() << "|" << "#|logrotate on: " << recfile << std::endl;
75+
}
76+
}
77+
}
4278

4379
void startRecording()
4480
{

lib/src/sai_redis_switch.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,22 @@ sai_status_t sai_redis_notify_syncd(
361361
sai_status_t redis_set_switch_attribute(
362362
_In_ const sai_attribute_t *attr)
363363
{
364+
if (attr != NULL && attr->id == SAI_REDIS_SWITCH_ATTR_PERFORM_LOG_ROTATE)
365+
{
366+
/*
367+
* Let's avoid using mutexes, since this attribute could be used in
368+
* signal handler, so check it's value here. If set this attribute will
369+
* be performed from multiple threads there is possibility for race
370+
* condition here, but this doesn't matter since we only set logrotate
371+
* flag, and if that happens we will just reopen file less times then
372+
* actual set operation was called.
373+
*/
374+
375+
g_logrotate = true;
376+
377+
return SAI_STATUS_SUCCESS;
378+
}
379+
364380
std::lock_guard<std::mutex> lock(g_apimutex);
365381

366382
SWSS_LOG_ENTER();

0 commit comments

Comments
 (0)