Skip to content

Commit

Permalink
Add support for logrotate in sairedis (sonic-net#192)
Browse files Browse the repository at this point in the history
* Add support for logrotate in sairedis

* Fix attribute id access

* Fix logrotate variable name

* Address comments
  • Loading branch information
kcudnik authored Jun 17, 2017
1 parent e98ea8f commit b865912
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
1 change: 1 addition & 0 deletions lib/inc/sai_redis.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern std::string joinFieldValues(
_In_ const std::vector<swss::FieldValueTuple> &values);

extern volatile bool g_useTempView;
extern volatile bool g_logrotate;

// other global declarations

Expand Down
19 changes: 19 additions & 0 deletions lib/inc/sairedis.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,25 @@ typedef enum _sai_redis_switch_attr_t
*/
SAI_REDIS_SWITCH_ATTR_RECORDING_OUTPUT_DIR,

/**
* @brief Log rotate.
*
* This is action attribute. When set to true then at the next log line
* write it will close recording file and open it again. This is desired
* when doing log rotate, since sairedis holds handle to recording file for
* performance reasons. We are assuming logrotate will move recording file
* to ".n" suffix, and when we reopen file, we will actually create new
* one.
*
* This attribute is only setting variable in memroy, it's safe to call
* this from signal handler.
*
* @type bool
* @flags CREATE_AND_SET
* @default false
*/
SAI_REDIS_SWITCH_ATTR_PERFORM_LOG_ROTATE,

} sai_redis_switch_attr_t;

/*
Expand Down
40 changes: 38 additions & 2 deletions lib/src/sai_redis_record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,34 @@ std::string getTimestamp()

// recording needs to be enabled explicitly
volatile bool g_record = false;
volatile bool g_logrotate = false;

std::ofstream recording;
std::mutex g_recordMutex;

std::string recfile = "dummy.rec";

void logfileReopen()
{
SWSS_LOG_ENTER();

recording.close();

/*
* On log rotate we will use the same file name, we are assuming that
* logrotate deamon move filename to filename.1 and we will create new
* empty file here.
*/

recording.open(recfile);

if (!recording.is_open())
{
SWSS_LOG_ERROR("failed to open recording file %s: %s", recfile.c_str(), strerror(errno));
return;
}
}

void recordLine(std::string s)
{
std::lock_guard<std::mutex> lock(g_recordMutex);
Expand All @@ -36,9 +60,21 @@ void recordLine(std::string s)
{
recording << getTimestamp() << "|" << s << std::endl;
}
}

std::string recfile = "dummy.rec";
if (g_logrotate)
{
g_logrotate = false;

logfileReopen();

/* double check since reopen could fail */

if (recording.is_open())
{
recording << getTimestamp() << "|" << "#|logrotate on: " << recfile << std::endl;
}
}
}

void startRecording()
{
Expand Down
16 changes: 16 additions & 0 deletions lib/src/sai_redis_switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,22 @@ sai_status_t sai_redis_notify_syncd(
sai_status_t redis_set_switch_attribute(
_In_ const sai_attribute_t *attr)
{
if (attr != NULL && attr->id == SAI_REDIS_SWITCH_ATTR_PERFORM_LOG_ROTATE)
{
/*
* Let's avoid using mutexes, since this attribute could be used in
* signal handler, so check it's value here. If set this attribute will
* be performed from multiple threads there is possibility for race
* condition here, but this doesn't matter since we only set logrotate
* flag, and if that happens we will just reopen file less times then
* actual set operation was called.
*/

g_logrotate = true;

return SAI_STATUS_SUCCESS;
}

std::lock_guard<std::mutex> lock(g_apimutex);

SWSS_LOG_ENTER();
Expand Down

0 comments on commit b865912

Please sign in to comment.