Какой смысл засорять? - PullRequest
       31

Какой смысл засорять?

50 голосов
/ 09 сентября 2008

Мне было интересно, какой смысл засорять? Насколько я могу судить, clog такой же, как cerr, но с буферизацией, поэтому он более эффективен. Обычно stderr - это то же самое, что и stdout, поэтому засорение - это то же самое, что и cout. Это кажется мне довольно неубедительным, поэтому я полагаю, что я неправильно это понимаю. Если я отправляю сообщения журнала в то же место, куда отправляются сообщения об ошибках (возможно, что-то в / var / log / messages), то я, вероятно, не пишу слишком много (так что при использовании забуференный серр). По моему опыту, я хочу, чтобы мои сообщения журнала обновлялись (не буферизировались), чтобы я мог помочь найти сбой (поэтому я не хочу использовать буферизованную засоренность). Очевидно, я всегда должен использовать cerr.

Я бы хотел иметь возможность перенаправлять засорение внутри моей программы. Было бы полезно перенаправить cerr, чтобы при вызове библиотечной процедуры я мог контролировать, куда идут cerr и clog. Могут ли некоторые компиляторы это поддерживать? Я только что проверил DJGPP, и stdout определен как адрес структуры FILE, поэтому запрещается делать что-то вроде "stdout = freopen (...)".

  • Можно ли перенаправить засорение, cerr, cout, stdin, stdout и / или stderr?
  • Единственное различие между буферизацией и засорением в буферизации?
  • Как мне реализовать (или найти) более надежное средство ведения журнала (ссылки, пожалуйста)?

Ответы [ 4 ]

35 голосов
/ 09 сентября 2008

Можно ли перенаправить clog, cerr, cout, stdin, stdout и / или stderr?

Да. Вам нужна функция rdbuf.

ofstream ofs("logfile");
cout.rdbuf(ofs.rdbuf());
cout << "Goes to file." << endl;

Единственное различие между буферизацией и засорением в буферизации?

Насколько я знаю, да.

14 голосов
/ 09 сентября 2008

Если вы находитесь в оболочке posix (я действительно думаю о bash), вы можете перенаправить любой дескриптор файла к любому другому дескриптору файла, поэтому для перенаправления вы можете просто:

$ myprogram 2>&5 

для перенаправления stderr в файл, представленный как fd = 5.

Редактировать: если подумать, мне больше нравится ответ @Konrad Rudolph о перенаправлении. rdbuf () - более понятный и переносимый способ сделать это.

Что касается журналирования, хорошо ... Я начинаю с библиотеки Boost для всего, что есть в C ++, которого нет в библиотеке std. Вот: Boost Logging v2

Редактировать : регистрация буста не часть библиотек буста; оно было рассмотрено, но не принято.

Редактировать : 2 года спустя, в мае 2010 года, Boost принял библиотеку журналов, которая теперь называется Boost.Log .

Конечно, есть альтернативы:

  • Log4Cpp (API в стиле log4j для C ++)
  • Log4Cxx (API в стиле log4j, спонсируемый Apache)
  • Pantheios (не существовало? В прошлый раз, когда я пытался, я не мог заставить его основываться на недавнем компиляторе)
  • Google's GLog (шляпный наконечник @SuperElectric)

Также есть журнал событий Windows.

И пара статей, которые могут пригодиться:

0 голосов
/ 25 мая 2019

Поскольку здесь есть несколько ответов о перенаправлении, я добавлю этот замечательный самоцвет Я недавно наткнулся на перенаправление:

#include <fstream>
#include <iostream>

class redirecter
{
public:
    redirecter(std::ostream & dst, std::ostream & src)
        : src(src), sbuf(src.rdbuf(dst.rdbuf())) {}
    ~redirecter() { src.rdbuf(sbuf); }
private:
    std::ostream & src;
    std::streambuf * const sbuf;
};

void hello_world()
{
    std::cout << "Hello, world!\n";
}

int main()
{
    std::ofstream log("hello-world.log");
    redirecter redirect(log, std::cout);
    hello_world();
    return 0;
}

Это в основном класс перенаправления, который позволяет вам перенаправлять любые два потока и восстанавливать его, когда вы закончите.

0 голосов
/ 18 декабря 2010

Basic Logger

#define myerr(e) {CriticalSectionLocker crit; std::cerr << e << std::endl;}

Используется как myerr("ERR: " << message); или myerr("WARN: " << message << code << etc);

Очень эффективно.

Тогда сделайте:

./programname.exe 2> ./stderr.log
perl parsestderr.pl stderr.log

или просто разобрать stderr.log вручную

Я признаю, что это не для чрезвычайно кода, критичного для производительности Но кто все равно это пишет.

...