質問
ずっと疑問に思っていたのですが、詰まりって何の意味があるのでしょうか?私の知る限り、clog は cerr と同じですが、バッファリングがあるため、より効率的です。通常、stderr は stdout と同じであるため、clog は cout と同じです。これは私にとってかなり不自然に思えるので、私がそれを誤解しているに違いないと思います。エラー メッセージが出力されるのと同じ場所 (おそらく /var/log/messages のどこか) にログ メッセージが出力される場合、おそらくあまり多くのことを書き込んでいないでしょう (したがって、 -バッファリングされたエラー)。私の経験では、クラッシュを見つけやすくするために、ログ メッセージを最新の状態 (バッファリングしない) にしたいと考えています (そのため、バッファリングされた詰まりを使用したくありません)。どうやら私は常にcerrを使用する必要があるようです。
プログラム内で詰まりをリダイレクトできるようにしたいと考えています。cerr をリダイレクトすると、ライブラリ ルーチンを呼び出すときに cerr と clog の行き先を制御できるようになると便利です。一部のコンパイラはこれをサポートできますか?DJGPP を確認したところ、stdout は FILE 構造体のアドレスとして定義されているため、「stdout = freopen(...)」のようなことは違法です。
- clog、cerr、cout、stdin、stdout、stderr をリダイレクトすることはできますか?
- clog と cerr の唯一の違いはバッファリングですか?
- より堅牢なロギング機能 (リンクを参照してください) を実装 (または見つけ) するにはどうすればよいですか?
解決
clog、cerr、cout、stdin、stdout、stderr をリダイレクトすることはできますか?
はい。あなたが欲しいのは、 rdbuf
関数。
ofstream ofs("logfile");
cout.rdbuf(ofs.rdbuf());
cout << "Goes to file." << endl;
clog と cerr の唯一の違いはバッファリングですか?
私の知る限り、そうです。
他のヒント
POSIXシェル環境にいる場合(私は本当にBASHを考えています)、ファイル記述子を他のファイル記述子にリダイレクトできます。
$ myprogram 2>&5
stderr を fd=5 で表されるファイルにリダイレクトします。
編集:よく考えてみると、リダイレクトに関する @Konrad Rudolph の回答の方が好きです。rdbuf() は、より一貫性があり、移植性の高い方法です。
ロギングに関しては、そうですね...std ライブラリにないすべての C++ については Boost ライブラリから始めます。見よ: ブースト ロギング v2
編集:ブーストロギングは ない Boost ライブラリの一部。検討されましたが、受け入れられませんでした。
編集:2 年後の 2010 年 5 月に、Boost は現在、次のように呼ばれるログ ライブラリを受け入れました。 ブーストログ.
もちろん、代替手段もあります。
- Log4Cpp (C++ 用の log4j スタイル API)
- Log4Cxx (Apache スポンサーの log4j スタイル API)
- パンテオス (なくなった?前回試したときは、最近のコンパイラでビルドできませんでした)
- GoogleのGLog (感謝 @SuperElectric)
Windows イベント ロガーもあります。
役に立つかもしれない記事をいくつか紹介します。
基本ロガー
#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 を解析するだけです
これは目的ではないことを認めます 非常に パフォーマンスが重要なコード。しかし、とにかく誰がそれを書いていますか。
リダイレクトについてはここにいくつかの回答があるため、追加します この素敵な宝石 最近、リダイレクトについて偶然見つけました。
#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;
}
これは基本的に、任意の 2 つのストリームをリダイレクトし、終了時に復元できるようにするリダイレクト クラスです。