Я на 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;
}
}
}
Системный вызов системного журнала не записывает в файл. Он записывает в сокет домена / dev / log unix. Демон syslog (rsyslog) прослушивает / dev / log и делает все, что от него было настроено. Сокет / dev / log является сокетом дейтаграммы, поэтому блокирование чего-либо невозможно.
Других решений пока нет …