- PR -

syslog.confの設定でinsert,updateだけのログを取りたい

1
投稿者投稿内容
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-10-12 11:13
Red Hat Linux 3.2.3-20
Postgres SQL 7.4.5
という環境のサーバーで

postgres.conf
のsyslog_facilityを書き換え
/data/pgsql/log/postgres.log
にログを書き込んでいます。

postgres.conf
log_statement=true
として全てのSQLを記録するようにしていたのですが、
/data/pgsql/log/postgres.log
が1週間で2G以上になってしまう状態で、全く使えないログになっていました。

そこで一旦
log_statement=false
として運用してます。

なんとか軽量化させたログを残したいので幾つか方法を考えたのですが、
以下のように部分的にログを取る方法はあるのでしょうか?

1,指定した時間の指定したIP以外からのselect,insert,updateを記録
2,指定したIP以外からのselect,insert,updateを記録
3,insert,updateを記録

1,2,3とも上記の条件に加えてerror,接続記録は残すようにします。

本当に日々確認が必要なデータベースではトリガーを使いSQLのログはログテーブルに残しているのですが、こちらも肥大化していっており全てのデータベースというわけにはいきません。

そこで時々しかログを追わないものはsyslogに残せないかと思って今回の質問をさせて頂きました。
そもそもこの考えも間違っているのでしょうか?
ログの運用の仕方もアドバイス頂けると助かります。


[ メッセージ編集済み 編集者: koara 編集日時 2005-10-13 12:00 ]
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-10-13 11:58
自己レスです。

その後自分なりに調べてみてスレ違いだったことに気づきました。
まず、そのことをお詫びします。

少し進展しましたので、情報追加させてください。
postgres自体はただ/dev/logにログを流しているだけで
それをsyslogdが受け取り
/etc/syslog.confに従って処理していることが分かりました。

ということで、syslog.conf
の記述を確認したところ
#postgresSQL
LOCAL2.* /data/pgsql/log/postgres.log
となってました。

LOCAL2はpostgres.conf側で
syslog_facility = 'LOCAL2'
としているためです。

/etc/syslog.confの記述を
LOCAL2.* |grep insert >/data/pgsql/log/postgres.log
に変更して
kill -HUP `cat /var/run/syslogd.pid`
として設定を読み込みしましたがうまくいきません。
こういうことはできないのでしょうか?
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-10-13 13:02
こんにちは。

こういう分野であれば、djb daemontools付属の multilog が向いているような気もしますが ( ただ、導入には幾つか難点があるため、対処が必要です )、今回は syslog に絞って考えてみます。

やったことが無い所なので、推測になるのですが…、
引用:
/etc/syslog.confの記述を
LOCAL2.* |grep insert >/data/pgsql/log/postgres.log
に変更して
kill -HUP `cat /var/run/syslogd.pid`
として設定を読み込みしましたがうまくいきません。
こういうことはできないのでしょうか?


syslog.conf(5)によれば、“|”で始まる記述は、名前つきパイプへの出力を指定するもので、Apacheで指定できるような、プロセス起動&パイプによるデータ受け渡し、とは異なるようです。
かと言って、“|”と他ホストへの転送以外の指定では、他のプロセスにデータを受け渡すような真似はできなさそうです。

で、名前つきパイプとは、mkfifo(1)や、fifo(4)が参考になりますが、通常使うパイプとは異なります。

 ・通常のパイプ ( 一例 )
  1. プロセスA pipe によりパイプ生成
  2. プロセスA fork により プロセスB 複製 ( この時点で A,B パイプ共有 )
  3. プロセスA 出力先をパイプに、プロセスB 入力元をパイプに指定
  4. 「プロセスA → パイプ → プロセスB」というデータの流れが完成

 ・名前つきパイプ
  1. mkfifo により、ファイルシステム上に名前つきパイプ生成
  2. プロセスB 入力元を、名前つきパイプに指定
  3. プロセスA 出力先を、名前つきパイプに指定
  4. 「プロセスA → 名前つきパイプ → プロセスB」というデータの流れが完成

似ているように見えますが…
通常のパイプは、親子・兄弟関係のあるプロセス内のプライベートなものですが、名前つきパイプの場合、どのプロセスが使用するか全く分からない…、すなわち、
通常のパイプは、関連するプロセスが一蓮托生のため、プロセス起動・停止が制御し易いが、名前つきパイプの場合、本質的に無関係なプロセス群を協調させるのが難しい
という性格があり、経験上一筋縄では行かないように思います。

こんな実験をしてみれば、少しは分かり易いでしょうか

 $ cat /etc/services | grep -v '^#' > out1

 $ mkfifo tmpfifo
 $ grep -v '^#' tmpfifo > out2 &
 $ cat /etc/services > tmpfifo

今回の例だと、次のようなイメージになりそうです。

 ・mkfifo により名前つきパイプ作成、syslog.conf でそれを指定
 ・「grep パターン 名前つきパイプ > 出力先」というようなコマンドを走らせておく
 ・syslog起動
 ・「syslog → 名前つきパイプ → grep → 出力先」という流れが完成

…長文申し訳ないですが、以上、ご参考まで。
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-10-13 13:47
angel様のアドバイスはほんとに勉強になります、ありがとうございます。

まだ何となくの理解しかできていませんので結果のご報告に少し時間がかかりそうです。
まずはレスのお礼だけですいません。

syslogdはファイルと名前付きパイプ(FIFO)の出力しか出来ないという事ですね。
ちょうど名前付きパイプというものを調べていたところです。

イメージとしては
引用:

grep insert >/data/pgsql/log/postgres.log


を名前付きパイプとしてプロセスを走らせておき、
syslogdの出力をそこに流すというわけですね。


ひとつ質問させて下さい。
引用:

$ cat /etc/services | grep -v '^#' > out1



/etc/services
のコメント以外の行を
out1
として出力するということだと思うのですが、どういう意味がなのでしょうか?
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-10-13 14:20
こんにちは。
引用:
ひとつ質問させて下さい。
引用:
$ cat /etc/services | grep -v '^#' > out1


/etc/services
のコメント以外の行を
out1
として出力するということだと思うのですが、どういう意味がなのでしょうか?


はい、処理の内容は koaraさんの書いた通りです。
で、意味としては…、特にありません。通常のパイプと名前つきパイプの挙動比較の例 ( 実験 ) として載せてみたものです。
混乱させてしまったようでしたら申し訳ないです。

名前つきパイプを使用した運用は、私も興味がある所なので、是非頑張ってください。( 他力本願モード )

それでは。
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-11-30 19:07
ご無沙汰しております。

その後いろいろアドバイスを頂いて試したのですが、
名前つきパイプでのログ出力はできませんでした。

先日この件で使用していたサーバーが故障しdisk容量の多いサーバーになりました。
logも存分に残せるということで今回は断念します。

angel様ありがとうございました。
koara
ベテラン
会議室デビュー日: 2005/09/16
投稿数: 96
投稿日時: 2005-12-28 13:39
自己レスです。

今回の件で満足いく解決方法が見つかりましたので
参考になればと思い書き込みします。

postgresに接続するプログラム側で接続処理が成功した後に
set log_statement to true;
という1文を発行しておくと、
そのセッションの間に発行したSQL文だけがログに残ります。

これをログを残したいプログラムの任意の箇所に書くことで
必要なsql文のログを残しつつ、ログのサイズを減量する事が出来ました。

またサーバーに直接ログインして発行したSQL文をログに残したい場合は
~/.psqlrc
というファイルを作り
set log_statement to true
とだけ書いておけばokです。

以上参考になれば幸いです。


1

スキルアップ/キャリアアップ(JOB@IT)