Reputation: 366
I am on ubuntu 16.04 with rsyslog version 8.16.0. I am writing some tests for an C++ syslog wrapper. In the wrapper I just call syslog(3).
There is only one rule in the config file.
user.* /var/log/user.log
I turned filter duplicate messages off and I can see all the messages in the log files.
During the test I noticed that the syslog call is not blocking.
TEST(BlockingTest, block)
{
ifstream file;
long oriPos=0;
long newPos=0;
int offset = strlen("Nov 28 13:07:01 4dac2c62ebe7 logTest: blockinglogger: blocking call")+1;
file.open("/var/log/user.log");
if(file.is_open())
{
file.seekg(0,ios::end);
oriPos = file.tellg();
}
file.close();
Syslogging::Logger logger("blockinglogger",Syslogging::Level::DEBUG);
logger.debug("blocking call");
// This needs to be here else undefined behavior.
this_thread::sleep_for(chrono::milliseconds(2));
file.open("/var/log/user.log");
if(file.is_open())
{
file.seekg(0,ios::end);
newPos = file.tellg();
}
file.close();
EXPECT_EQ(newPos, oriPos+offset);
}
I thought that using the above config it would block for each syslog call till it was written to the file. But I need a small timeout or I get undefined behavior (sometimes it passes, sometimes it fails).
Do I need another setting or anybody that can explain this behavior more clearly pls?
EDIT : The system does not do any other logging at user level. the user.log file only contains the entries from the test. So it is not undefined because of random other logs.
EDIT : i have confirmed the same behavior without the wrapping code.
int main()
{
for(int i=0;i<20;i++)
{
ifstream file;
long oriPos=0;
long newPos=0;
std::string s = "Nov 28 15:48:01 jova syslogTest: blocking call"+ std::to_string(i);
int offset = s.length()+1;
//cout << "off: " << offset << endl;
file.open("/var/log/user.log");
if(file.is_open())
{
file.seekg(0,ios::end);
oriPos = file.tellg();
//cout << "ori: " << oriPos << endl;
}
file.close();
std::string l = "blocking call" + std::to_string(i);
syslog(LOG_DEBUG, "%s", l.c_str());
// THIS IS NEEDED..
this_thread::sleep_for(chrono::milliseconds(5));
file.open("/var/log/user.log");
if(file.is_open())
{
file.seekg(0,ios::end);
newPos = file.tellg();
//cout << "new: " << newPos << endl;
}
file.close();
if(newPos == oriPos+offset)
{
cout << "SAME" << endl;
}
else
{
cout << "DIFFERENT" << endl;
}
}
}
Upvotes: 1
Views: 533
Reputation: 1642
The syslog system call does not write to a file. It writes to the /dev/log unix domain socket. The syslog daemon (rsyslog) listens on /dev/log and does whatever it was configured to do from there. The /dev/log socket is a datagram socket, so there is no way something would be blocking.
Upvotes: 1