Я работаю на сервере, и я хочу иметь возможность регистрировать сообщения, используя log4cplus. До здесь ничего сложного.
Тем не менее, я использую fork()
создать дочерний процесс каждый раз, когда я получаю запрос на подключение. fork()
чтобы убедиться, что дочерние процессы имеют свой собственный экземпляр подключения к базе данных.
Теперь я хотел бы также использовать Logger у ребенка. Он отлично работает на сервере (то есть я вижу вывод журнала в консоли и файл, когда я его настраиваю). Но после fork()
похоже, что он теряется.
Существует упрощенный краткий обзор, который используется сейчас:
log4cplus::PropertyConfigurator::doConfigure(filename);
log4cplus::Logger l(log4cplus::Logger::getInstance("snap"));
l.log(ll, "Server Started", f_file, f_line); // <<-- works great!
...
listen();
accept();
...
fork();
// if child:
log4cplus::Logger l(log4cplus::Logger::getInstance("snap"));
l.log(ll, msg, f_file, f_line); // <<-- does not work?!
Я думаю, что регистратор может блокировать файл на сервере, и поэтому дети не могут сами открыть этот же файл. Это тот случай? Если это так, то log4cplus не может быть использован в моей среде …
Как уже упоминалось в комментариях, чтобы все снова заработало, нужно закрыть все и перенастроить.
Однако, если вы используете более новую версию и loggingserver у вас получится хотя бы одна нить. В этой ситуации fork()
не будет дублировать поток так называющий log4cplus::Logger::shutdown
блокируется, если только что вызван в дочернем процессе (он ожидает в этом потоке вечно в дочернем процессе.)
Таким образом, правильный способ сделать это — выключить родительский узел, разветвиться, а затем перенастроить родительский и дочерний. Следующая функция показывает, как мы можем справиться с ситуацией.
pid_t fork_child()
{
// shutdown
log4cplus::Logger::shutdown();
pid_t p(fork());
// reconfigure
log4cplus::PropertyConfigurator::doConfigure("snap.properties");
return p;
}
Других решений пока нет …