68

そのため、Linux システムで実行しているデーモンがあり、そのアクティビティの記録、つまりログを取得したいと考えています。問題は、これを達成するための「最良の」方法は何ですか?

私の最初のアイデアは、単純にファイルを開いて書き込むことです。

FILE* log = fopen("logfile.log", "w");
/* daemon works...needs to write to log */
fprintf(log, "foo%s\n", (char*)bar);
/* ...all done, close the file */
fclose(log);

この方法でログを記録することには、本質的に何か問題がありますか? Linuxに組み込まれたフレームワークなど、より良い方法はありますか?

4

10 に答える 10

104

Unix には長い間、syslogと呼ばれる特別なロギング フレームワークがありました。シェルを入力します

man 3 syslog

C インターフェイスのヘルプが表示されます。

いくつかの

#include <stdio.h>
#include <unistd.h>
#include <syslog.h>

int main(void) {

 openlog("slog", LOG_PID|LOG_CONS, LOG_USER);
 syslog(LOG_INFO, "A different kind of Hello world ... ");
 closelog();

 return 0;
}
于 2008-10-01T16:21:47.410 に答える
24

これはおそらく競馬になるでしょうが、そうです、すべてではないにしてもほとんどの Un*x 派生物に存在する syslog 機能が望ましい方法です。ファイルにログを記録することに問題はありませんが、多くのタスクが肩に残ります。

  • ログの場所にファイルを保存するためのファイル システムはありますか
  • バッファリング(パフォーマンスのため)とフラッシュ(システムクラッシュの前に書き込まれたログを取得するため)はどうですか
  • デーモンが長時間実行されている場合、増え続けるログ ファイルをどうしますか。

Syslog は、これらすべてを処理し、さらに多くのことを処理します。API は printf 一族に似ているため、コードの適応に問題はありません。

于 2008-10-01T16:27:18.707 に答える
12

大規模な (またはよりセキュリティ意識の高い) インストールでの syslog のもう 1 つの利点: syslog デーモンは、ログを別のサーバーに送信して、ローカル ファイルシステムの代わりに (またはそれに加えて)、そこに記録するように構成できます。

サーバー ファームのすべてのログを 1 か所にまとめておく方が、マシンごとにログを個別に読み取るよりもはるかに便利です。特に、あるサーバーのイベントを別のサーバーのイベントと関連付けようとしている場合に便利です。クラックが発生すると、そのログを信頼できなくなります... しかし、ログ サーバーが安全なままであれば、ログから何も削除されていないことがわかります。したがって、侵入の記録はそのまま残ります。

于 2008-10-01T17:30:28.947 に答える
8

単体テストを行っているときに、daemon.info と daemon.debug に大量のデーモン メッセージを吐き出します。syslog.conf の 1 行で、必要なファイルにこれらのメッセージを貼り付けることができます。

http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/040/4036/4036s1.htmlには、man ページの imo よりも C API についての詳しい説明があります。

于 2008-10-01T16:27:28.427 に答える
2

上で述べたように、syslogを調べる必要があります。ただし、独自のロギングコードを記述したい場合は、fopenの「a」(書き込み追加)モードを使用することをお勧めします。

独自のログコードを作成する場合のいくつかの欠点は、ログローテーション処理、ロック(複数のスレッドがある場合)、同期(ログがディスクに書き込まれるのを待ちますか?)です。syslogの欠点の1つは、ログがディスクに書き込まれたかどうかをアプリケーションが認識しないことです(ログが失われた可能性があります)。

于 2008-10-01T16:33:33.060 に答える
2

Syslogは良いオプションですが、log4cを検討することをお勧めします。log4 [something]フレームワークは、JavaおよびPerlの実装で適切に機能し、構成ファイルから、syslog、コンソール、フラットファイル、またはユーザー定義のログライターのいずれかにログを記録することを選択できます。モジュールごとに特定のログコンテキストを定義し、構成で定義されているように各コンテキストログを異なるレベルにすることができます。(トレース、デバッグ、情報、警告、エラー、クリティカル)、シグナルをトラップしてデーモンにその構成ファイルをその場で再読み取りさせ、実行中のサーバーのログレベルを操作できるようにします。

于 2008-10-01T16:41:43.603 に答える
2

スレッドを使用し、ロギングをデバッグ ツールとして使用する場合は、ある種のスレッド セーフでロックされていないリング バッファを使用するロギング ライブラリを探す必要があります。厳密に必要な場合にのみグローバル ロックを使用して、スレッドごとに 1 つのバッファー。

これにより、ロギングによってソフトウェアの深刻な速度低下が引き起こされるのを回避し、デバッグ ロギングを追加したときに変化する heisenbug の作成を回避できます。

ロギング中のフォーマット操作で時間を無駄にしない高速圧縮バイナリ ログ フォーマットと、優れたログ解析および表示ツールがあれば、それはおまけです。

このための良いコードへの参照を提供したいと思いますが、私自身は持っていません。1つだけ欲しい。:)

于 2008-10-01T17:32:20.330 に答える
1

私たちの組み込みシステムにはsyslogがないため、私が書いたデーモンは、あなたが説明したのと同様の「a」オープンモードを使用してファイルにデバッグを行います。ログファイルを開き、メッセージを吐き出してからファイルを閉じる機能があります(これは、予期しないことが起こった場合にのみ行います)。ただし、他のコメンターが言及しているように、「tail -c 65536 logfile > logfiletmp && mv logfiletmp logfile」で構成されるログ ローテーションを処理するコードも作成する必要がありました。これはかなり大雑把で、「ログの前頭切り捨て」と呼ぶべきかもしれませんが、小さな RAM ディスク ベースのファイル システムがログ ファイルでいっぱいになるのを防ぎます。

于 2008-10-02T00:41:06.587 に答える
0

多くの潜在的な問題があります。たとえば、ディスクがいっぱいになった場合、デーモンを失敗させますか? また、毎回ファイルを上書きします。多くの場合、ファイル用にマシンにスペースを割り当てるために循環ファイルが使用されますが、あまり多くのスペースを占有することなく、有用な十分な履歴を保持できます。あなたを助けることができるlog4cのようなツールがあります。コードが c++ の場合、Apache プロジェクト (ubuntu/debian に apt-get install liblog4cxx9-dev) の log4cxx を検討するかもしれませんが、C を使用しているようです。

于 2008-10-01T16:26:40.580 に答える
0

これまでのところ、ログ メッセージをファイルやsyslog シンク、さらには Windows イベント ログにリダイレクトするための便利で簡単な方法を備えたブースト ログ ライブラリについては誰も言及していません。

于 2013-09-25T22:23:13.703 に答える