Запись rsyslog в синхронный файл не блокируется

У меня Ubuntu 16.04 с rsyslog версии 8.16.0. Я пишу несколько тестов для оболочки системного журнала С++. В обертке я просто вызываю 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;
    }
  }
}

person rinn2883    schedule 28.11.2017    source источник


Ответы (1)


Системный вызов syslog не записывает в файл. Он пишет в сокет домена unix /dev/log. Демон системного журнала (rsyslog) прослушивает /dev/log и делает оттуда все, что было настроено. Сокет /dev/log является сокетом дейтаграммы, поэтому нет никакой возможности что-то заблокировать.

person Stephane Martin    schedule 28.12.2017