rsyslog 写入同步文件不会阻塞
rsyslog writing to synchronous file does not block
我在 ubuntu 16.04 上,rsyslog 版本为 8.16.0。我正在为 C++ 系统日志包装器编写一些测试。
在包装器中,我只调用 syslog(3).
配置文件中只有一个规则。
user.* /var/log/user.log
我关闭了过滤重复消息的功能,我可以在日志文件中看到所有消息。
在测试期间,我注意到系统日志调用没有阻塞。
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);
}
我认为使用上面的配置它会阻止每个系统日志调用,直到它被写入文件。但是我需要一个小的超时,否则我会出现未定义的行为(有时会通过,有时会失败)。
我是否需要其他设置或任何可以更清楚地解释此行为的人?
编辑:系统不会在用户级别执行任何其他日志记录。 user.log 文件仅包含测试中的条目。所以它不是未定义的,因为随机的其他日志。
编辑:我已经确认没有包装代码的相同行为。
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;
}
}
}
syslog 系统调用未写入文件。它写入 /dev/log unix 域套接字。 syslog 守护进程 (rsyslog) 侦听 /dev/log 并从那里执行配置的任何操作。 /dev/log 套接字是一个数据报套接字,所以不可能有任何阻塞。
我在 ubuntu 16.04 上,rsyslog 版本为 8.16.0。我正在为 C++ 系统日志包装器编写一些测试。 在包装器中,我只调用 syslog(3).
配置文件中只有一个规则。
user.* /var/log/user.log
我关闭了过滤重复消息的功能,我可以在日志文件中看到所有消息。
在测试期间,我注意到系统日志调用没有阻塞。
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);
}
我认为使用上面的配置它会阻止每个系统日志调用,直到它被写入文件。但是我需要一个小的超时,否则我会出现未定义的行为(有时会通过,有时会失败)。
我是否需要其他设置或任何可以更清楚地解释此行为的人?
编辑:系统不会在用户级别执行任何其他日志记录。 user.log 文件仅包含测试中的条目。所以它不是未定义的,因为随机的其他日志。
编辑:我已经确认没有包装代码的相同行为。
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;
}
}
}
syslog 系统调用未写入文件。它写入 /dev/log unix 域套接字。 syslog 守护进程 (rsyslog) 侦听 /dev/log 并从那里执行配置的任何操作。 /dev/log 套接字是一个数据报套接字,所以不可能有任何阻塞。