2016-09-05 2 views
1

私は考えていたことを、リモートデータベースを定期的にポーリングし、ログファイルに次の要素を記録する単純なbashスクリプトを作成しようとしています。このスクリプトの目的は、積極的に監視し、応答時間をログに記録するsqlplusでポーリングし、結果をファイルに書き込む行シフトを強制的に実行する

Mon Sep 5 13:28:30 CEST 2016,1473074940127,text content, 4 
Mon Sep 5 13:28:40 CEST 2016,1473074940127,text content, 3 
Mon Sep 5 13:28:50 CEST 2016,1473074940127,text content, 2 

です:

Readable timestamp, timestamp, string, Request Duration 

例の結果は次のようになります。最後の2つの要素は、SQLクエリからの行の要素があります私たちのローカル環境からリモートデータベースへ、私たちはテスト中のローカルアプリケーションのエラー、最終的なデータベース接続の問題などがあります。このため、スクリプトは最終的なエラーメッセージも出力します。これらの書式設定は重要ではありませんが、標準出力が「快適な」1ライナーになるようにしたいと考えています。

私は機会のために、以下の非常に簡単なスクリプトを書かれているが、それは私がどんなに私の曲、それを取り除くように見えることはできませんいくつかの奇行があります

sleep_duration=10 
while true; do 

SECONDS=0 
timestamp="$(date)," 
echo -n $timestamp >> $LOG_PATH 


sqlplus -s $database <<EOF>> $LOG_PATH 
    whenever sqlerror exit sql.sqlcode 

    set echo off 
    set heading off 
    set linesize 1000 
    set pagesize 0 
    set numformat 9999999999999 
    set colsep , 
    set null null 

    SELECT COLUMN1, COLUMN2 FROM TABLE1; 
    exit; 
EOF 

echo ', '$SECONDS >> $LOG_PATH 

sleep $sleep_duration 
done 

我々はに送るクエリデータベースは常に2つの要素を持つ1つの行を返し、2つの要素(INTEGER、VARCHAR2)は常に同じ固定幅になります。私たちのアプリケーション内の何かがローカルで壊れてしまうと、両方ともnullになる可能性があります。

私はSPOOLコマンドとTIMINGコマンドが存在することを認識していますが、両方をテストして使用を中止しました。クエリをスプールしても、少なくともエラー端末の出力で騙されることなく、最終的な驚きエラーがログファイルに出力されるわけではないので、最初はパイプソリューションを使いました。よりシンプルに見えました。データベースのダウンタイムの場合、TIMINGはクエリの経過時間を正しく表示していないように見えるので、SECONDSアプローチを使用しました。私はこれが含まれているすべてのsqlplusオーバーヘッドに関して正確ではないことを知っていますが、正確なメトリックには関心がありません。一般に、プロセスが1秒未満か数分かかりますか?ミリ秒は本質的に無関係です。

これは、ログはこのように見える終わると、しかし一つの大きな問題があります。

Mon Sep 5 14:50:47 CEST 2016, 1473079873483,text output 

, 0 
Mon Sep 5 14:50:57 CEST 2016, 1473079883483,text output 

, 0 
Mon Sep 5 14:51:07 CEST 2016, 1473079893489,text output 

, 0 

が、私は結果から、このようなすべての末尾lineshiftsを削除するset pagesize 0を期待するだろうが、後2 lineshiftsがあるように思われます各質問に関係なく、私は何を試してもそれを取り除くことはできません。クエリをスプールすると同じ結果が得られます。

代わりにsqlplus-session内でループを考慮しましたが、スクリプトは多少永続的に実行する必要があるため、機能的に無意味な目的のために永続的に接続スロットを予約することが懸念されます。必要に応じて開閉する方がより合理的です。私は、主にその理由から、このアプローチを全くテストしていません。

どのような種類のエラーエントリがそこにポップアップするのかわからないので、ログの後処理を避けることを望んでいます。そのため、後で不必要なregex-nightmareのように感じます。

最終的なエラーが失われないようにしながら、不必要なラインシフトと空白なしで出力をきれいに1行に整列させる方法についての提案はありますか?

+0

文字列のデータ型は何ですか - あなたはvarchar2と言っていますが、それは本当にcharやclobではありません。それはどれくらいの大きさですか。文字列の値にはスペースや埋め込み改行がありますか? –

+0

文字列値はプレーンURLであり、フィールドはvarchar2(250)として宣言されており、コンテンツの実際の長さはnullまたは約60文字分の長さです。空白や改行は埋め込まれていません。先頭にも後ろにも - 私は3重チェックしますが、検証するだけの改行はありません。存在してはいけませんが、URLが部分的に生成されているので、チェックせずに100%確実ではありません。 –

+0

テキストフィールドにスペースや改行が全くないことを確認できます。文字列は常に正確に36文字幅です。 –

答えて

1

これは、私がまだ説明できなかったラインシフトを実際には解決していないため、回避策がありますが、これに対する非常に単純な解決策は、単にsqlplusの出力を直接sqlplusから直接ログに出力しようとする代わりにbash変数を使用し、他の変数としてエコーします。基本的に

、私は上記のスクリプトで変更しなければならなかったすべて、変数QUERY_OUTPUT = $(にSQLPLUSコマンドをラップ)し、出力の配管を取り外した:

自分でこのソリューションに出くわし
while true; do 

SECONDS=0 
timestamp=$(date) 
echo -n "$timestamp, " >> $LOG_PATH 

QUERY_RESULT=$(sqlplus -s $database << EOF 
    whenever sqlerror exit sql.sqlcode 

    set echo off 
    set heading off 
    set linesize 1000 
    set pagesize 0 
    set numformat 9999999999999 
    set colsep ', ' 
    set null null 

    SELECT TIME, BROKER_NAME FROM ACTIVEMQ_LOCK; 
    exit; 
EOF 
) 

echo $QUERY_RESULT, $SECONDS seconds elapsed >> $LOG_PATH 

sleep $sleep_duration 
done 

上記の質問で最初に試してみたことを文書化して検証しようと数時間を費やしていましたが、いくつかのテストの後ではうまくいっているようです。すべてがきれいに制御可能に1行に印刷され、最終的なエラーはその1行にもきれいに印刷されているようです。私が探していたものを正確に見つけ出す。

私は解決策を見つけてから最初に疑問を呈していないと考えていましたが、他の人がこれに何らかの価値を見出すかもしれないと私は思ったが、少なくとも明白な重複は見つけられませんでした。一緒に共有するかもしれない!

+1

私はあなたのシステムをテストするつもりはありませんが、これを1行に圧縮することができます、つまり 'echo $ QUERY_RESULT"、$ SECONDS秒が経過した ">> $ LOG_PATH'のようです。 SQL処理で余分な新しい行を取り除く方法があるかもしれませんが、これはあなたの目的にとっては十分に良いようです(しかし、 '$ SECONDS 'をなぜ持っているのか分かりません。 ) がんばろう。 – shellter

+0

ああ、もちろんそうです。基本的に私は2つの "問題"と思っていたので、2行で終わった。それで編集します! –

+0

ティックインされたSECONDSビットについては、ティックは秒をラップしませんが、先頭と末尾のテキストはラップしません。私はネイティブbashに精通したベテランではないので、私は彼らが不必要であることを理解していない、hehe。それを素早くテストし、両方の修正プログラムで編集します! 誰かが後で改行を取り除くことに直ちに気が付いてもうまくいくでしょうが、私の回避策はこの特定の状況で私を完全に適合させていますが、必ずしもそうであるとは限りません。 –

関連する問題