はじめに
swatchのthreshold track_byには、正規表現で文字列を指定する解説ページが多いですが、manのtrack_by="$2:$4"がどう使うのかわからなかったので挙動を確認しました。
環境
CentOS6.9
Linux 2.6.32-696.20.1.el6.x86_64 GNU/Linux
Swatch 3.2.3
まとめ
thresholdの設定に対しtrack_byは以下のように動作しました。
カウントの対象は1つだけではなく、track_byによりグループに分割されるようです。(概念なのでグループでなくても良いです)
thresholdを設定すると、watchforにヒットしtrack_byにヒットしないものもグループとみなされ、ヒットするものとは別にカウントするようです。
watchfor/(a)|(b)|(c)|(d)/i
threshold track_by=????,type=limit,count=3,seconds=20
| track_byの内容 | カウントのグループ | カウントのグループ数 | 挙動 |
|---|---|---|---|
| $_ | a|A|b|B|c|C|d|D | 無限 | 対象の行をまるごとユニークなものとしてカウントします。時刻を含むログの場合は、同時刻のエラーでない限り、内容が同一でも別にカウントされます。*1 |
| $1 | a|A|b or B or c or C or d or D | 3 | $1(aとA)以外のグループにも、thresholdの設定が適用されます。 |
| $2 | b|B|a or A or c or C or d or D | 3 | $2(bとB)以外のグループにも、thresholdの設定が適用されます。 |
| /$1|$2/ | a|A|b|B|c or C or d or D | 5 | $1(aとA)と$2(bとB)以外のグループにも、thresholdの設定が適用されます。 |
| /a/ | a or A or b or B or c or C or d or D | 1 | watchforにヒットすればtrack_byの内容に関係なくカウントします(track_by=,のように設定無しでも同様) |
- *1
trace_by=/$_/iでiオプションを設定しても、対象行内の大文字小文字は区別されます。e.g.error was detectedとError was detectedとError was Detectedはそれぞれ別にカウント。 - 監視対象に複数のキーワードが書かれたときは、行頭に近いキーワードのみがカウントされます。
検証
0.インストールのつまずき
Bit-Vector-7.1のmakeで以下のようなエラーが出ましたが、
Vector.xsファイルの中間にある#include "BitVector.h"を先頭に持ってくればmakeが通るようになりました。
ToolBox.h:96:24: エラー: expected identifier before numeric constant bit-vector
make: *** [Vector.o] Error 1
参考資料
Re: [perl #99408] Bleadperl v5.15.2-436-gbd31be4 breaksSTBEY/Bit-Vector-7.1.tar.gz(perl.org)
1.事前の情報収集と調査
thresholdで指定する値
| 変数 | 値 |
|---|---|
| track_by | 今回の調査対象 |
| type | limit / threshold / both |
| count | watchforに合致するキーワードを検出した回数 |
| secounds | threshold機能で使用する秒数 |
typeの挙動
| 文字列 | type |
|---|---|
| limit | 検出からsecoundsで指定された間、limitで指定された回数だけアクションする。*1 |
| threshold | 初回検出からsecondsで指定された間、countの回数に達したときアクションする。アクションするとcountは0に戻る。*1 *2 |
| both | thresholdと同じ条件で1度アクションしたら、secondsで指定された間はアクションしない。 |
- *1 count=0のときはアクションしません
- *2 count=1のときは常時アクションします
参考資料
swatch threshold設定のtypeパラメータ(wiki.bit-hive.com/tomizoo)
2.track_byの挙動確認
テストパターン
-
書き込み文字列は4パターン
error occurred,error detected,ERROR ocurred,warn occurred -
watchforは2パターン
/(error|warn)/,/(error|warn)/i -
track_byは4パターン
$_,$1,/error/./error/i
変数の内容
exec echoで確認すると以下の結果になりました。
| 変数 | 内容 |
|---|---|
| $_ | 検出した一行すべて |
| $0 |
/.swatch_script.10000 数字はPIDが入る |
| $1 | watchforに合致した、検出対象行の文字列。(watchforが/error/iでERRORが検出されたときERRORが格納される) |
結果
書き込み文字列4パターンが、track_byの設定によりどのように判別されるか確認しました。
| track_byの内容 | watchfor/(error|warn)/ | watchfor/(error|warn)i/ |
|---|---|---|
| $_ | すべて別にカウント | すべて別にカウント |
| $1 | すべて別にカウント |
error occurredとerror detectedは一緒にカウント、他は別にカウント*1 |
| /error/ | 検索対象がヒットすれば区別なくカウント | 検索対象がヒットすれば区別なくカウント |
| /error/i | 検索対象がヒットすれば区別なくカウント | 検索対象がヒットすれば区別なくカウント |
- *1
type=limitのとき、countの回数を超えてアクションする場合がありました。threshold、bothではそういったことは起こりませんでした。
結局、$2、$4は何が格納されるのかわかりませんでした。
watchfor /(a|b|c|d)/でabcdをヒットさせても、$2や$4に検索の文字列は格納されませんでした。
追加検証(2018/2/16追記)
$2の検証
良くmanを読むとwatchforで囲まれたカッコが、$の数ににあたるようです。
watchfor/(error)|(panic)|(fatal)|(down)/i に変更して確認しました。
type=limit、count=3、seconds=20で試しています。
| track_byの内容 | watchfor/(error)|(panic)|(fatal)|(down)/i |
|---|---|
| $_ | すべて別にカウント *1 |
| $1 | error1、panic/fatal/down2 *3のグループでそれぞれカウントし、それぞれアクションする。 |
| $2 | panic1、error/fatal/down2 *3のグループでそれぞれカウントし、それぞれアクションする。 |
| /$1|$2/ | error1、panic1、fatal/down*2 *3のグループでそれぞれカウントし、それぞれアクションする。 |
- *1 大文字と小文字は区別され、別のグループとしてカウントされる。
- *2 大文字と小文字は区別されない
- *3 trace_byにiオプションを付けても区別されない
- typeがthreshold、bothのときも同様でした。
- watchforやtrack_byのキーワードを
/$1|$2/gのように設定し、1行に複数のキーワードが含まれる場合でも、カウントは先頭に近いキーワードのみで、$1/$2のグループのカウントがそれぞれ増える仕様ではありませんでした。
$_の追加検証
検出対象の文で、大文字小文字がどのように区別されるか確認しました。
watchfor /error/iとします。
検出の対象文はerror detected、ERROR detected、error DETECTED、ERROR DETECTEDとしました。
| track_byの内容 | 挙動 |
|---|---|
| $_ | 4つとも別パターンとしてアクション |
| /$_/i | 4つとも別パターンとしてアクション |
- track_byにiオプションは効果がないようです。