62

私は疑問に思っていました、詰まりのポイントは何ですか?私が知る限り、clog は cerr と同じですが、バッファリングがあるため、より効率的です。通常、stderr は stdout と同じなので、clog は cout と同じです。これは私にはかなり不自由に思えるので、誤解しているに違いないと思います。エラーメッセージが出力されているのと同じ場所にログメッセージが出力されている場合 (おそらく /var/log/messages 内の何か)、おそらくあまり多くを書き出していません (したがって、non を使用してもあまり失われません)。 -buffered cerr)。私の経験では、クラッシュを見つけるのに役立つように (バッファリングされていない) ログメッセージを最新の状態にしたい (そのため、バッファリングされた clog を使用したくない)。どうやら私は常に cerr を使用する必要があります。

プログラム内で clog をリダイレクトできるようにしたいと考えています。ライブラリ ルーチンを呼び出すときに、cerr と clog の移動先を制御できるように、cerr をリダイレクトすると便利です。一部のコンパイラはこれをサポートできますか? DJGPP を確認したところ、stdout は FILE 構造体のアドレスとして定義されているため、「stdout = freopen(...)」のようなことを行うのは違法です。

  • clog、cerr、cout、stdin、stdout、および/または stderr をリダイレクトすることは可能ですか?
  • clog と cerr の唯一の違いはバッファリングですか?
  • より堅牢なログ機能を実装 (または検索) するにはどうすればよいですか (リンクをお願いします)。
4

6 に答える 6

42

clog、cerr、cout、stdin、stdout、および/または stderr をリダイレクトすることは可能ですか?

はい。あなたはそのrdbuf機能が欲しいです。

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

clog と cerr の唯一の違いはバッファリングですか?

私の知る限り、はい。

于 2008-09-09T17:13:03.497 に答える
15

あなたがposixシェル環境にいる場合(私は本当にbashを考えています)、任意のファイル記述子を他のファイル記述子にリダイレクトできるため、リダイレクトするには、次のことができます:

$ myprogram 2>&5 

stderr を fd=5 で表されるファイルにリダイレクトします。

編集:考え直して、リダイレクトに関する@Konrad Rudolphの回答の方が好きです。rdbuf() は、より一貫性があり移植可能な方法です。

ロギングに関しては、そうですね... std ライブラリにないすべての C++ 用の Boost ライブラリから始めます。見よ: Boost Logging v2

編集: Boost Logging はBoost Libraries の一部ではありません。レビューされましたが、受け入れられませんでした。

編集: 2 年後の 2010 年 5 月に、Boost は現在Boost.Logと呼ばれるログ ライブラリを受け入れました。

もちろん、代替手段があります。

  • Log4Cpp (C++ 用の log4j スタイルの API)
  • Log4Cxx (Apache が支援する log4j スタイルの API)
  • Pantheios (廃止されましたか? 前回試したときは、最近のコンパイラでビルドできませんでした)
  • Google の GLog (ハットチップ @SuperElectric)

Windows イベント ロガーもあります。

そして、役に立つかもしれないいくつかの記事:

于 2008-09-09T17:16:52.350 に答える
2

リダイレクタ クラスに関する 1 つの小さなポイント。適切に破棄する必要があり、一度だけです。デストラクタは、宣言されている関数が実際に戻り、オブジェクト自体がコピーされない場合にこれが発生することを保証します。

コピーできないようにするには、プライベート コピーおよび代入演算子を指定します。

class redirecter
{
public:
    redirecter(std::ostream & src, std::ostream & dst)
        : src_(src), sbuf(src.rdbuf(dst.rdbuf())) {}
    ~redirecter() { src.rdbuf(sbuf); }
private:
    std::ostream & src_;
    std::streambuf * const sbuf_;
    // Prevent copying.                        
    redirecter( const redirecter& );
    redirecter& operator=( const redirecter& );
};

std::clog を main() のログ ファイルにリダイレクトすることで、この手法を使用しています。main() が実際に返されるようにするために、main() の中身を try/catch ブロックに配置します。次に、プログラムのどこかで exit() を呼び出す可能性がある場所で、代わりに例外をスローします。これにより、制御が main() に返され、main() は return ステートメントを実行できます。

于 2020-07-02T05:02:03.183 に答える
1

基本ロガー

#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 を解析するだけです

これは非常にパフォーマンスが重要なコードではないことを認めます。しかし、とにかく誰がそれを書いています。

于 2010-12-18T01:39:02.320 に答える