iregexpの正規表現にマッチしないログを検出してトリガー発報する

いつもお世話になっております。

構築したZabbix環境で、掲題の事象が発生しており、原因がわからず困っている状態です。
お手数ですが対策等ご存じでしたら、教示いただきたく存じます。
以下に詳細を記載します。

◆環境
・Zabbix-Server
Version : 3.0.16-1.el6
OS : Amazon Linux AMI(2017.09)

・Zabbix-Agent
Version : 3.0.16-1+xenial_i386.deb
OS : Ubntu16.04.3 LTS (Xenial Xerus)
※Agentは毎日06:00頃起動し、16:00頃にシャットダウンする

◆アイテム
・ログ監視用アイテム
logrt[/var/log/dir/^system\.(log|log\.1)$,@LogLevel_error]
更新間隔:5秒

・ZabbixServerの現在時刻とログのタイムスタンプの差を計算するアイテム
difftime[](計算式:last("getTime.sh[]")-last("logrt[/var/log/dir/^system\.(log|log\.1)$,\"([0-9]+):([0-9]+):([0-9]+)(.*)(ERROR)\",,,skip,\1\2\3]"))
更新間隔:1秒

◆トリガー
・条件1:直近5分間のログから特定の正規表現にマッチする、かつ
・条件2:ZabbixServerの現在時刻とログのタイムスタンプの差が0より多く600以内、かつ
・条件3:5分の間にログが出力される
{Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR].iregexp(".*Serial read Error:errno.*",300)}<>0 and
{Template Template:difftime[].last()}>0 and
{Template Template:difftime[].last()}<=600 and
{Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR].nodata(300)}=0
障害イベントを継続して生成:しない

◆発生事象
・06:10頃から07:20までイベントが障害⇄復旧を繰り返す。(障害イベント発生後、0~1秒で復旧し、約1分後に障害を繰り返す)
・障害発報したイベントの内容を確認すると、検知したログの内容がトリガーのiregexpの条件にマッチしないものだった。

◆確認内容
・同じテンプレートを使用した検証環境にて、検知対象ではないログを出力してもトリガー発報されなかった。また検知対象のログは検知する。
・ログ監視アイテムのヒストリを確認すると、1分間に300件ほどの大量のエラーログが出ている状態だった。
・検知対象のログは期間中3回のみ検知(実際は100回以上出力されている)
・ZabbixServer側でトリガー発報、およびログにエラーはなかった。

◆補足
検知対象のログと、誤検知したログは以下の通り
・検知ログ(一部伏せて記載)
mm dd hh:mm:ss samplehost01 App[ID]: [ERROR ]: [function01] Serial read Error:errno=xx
・誤検知ログ(一部伏せて記載)
mm dd hh:mm:ss samplehost01 App[ID]: [ERROR ]: [function01] Address already in use : errno=xx : Address already in use
mm dd hh:mm:ss samplehost01 App[ID]: [ERROR ]: [function01] Socket Connect Error
mm dd hh:mm:ss samplehost01 App[ID]: [ERROR ]: [function01] Read Error Try Reconnect.

以上です。よろしくお願いいたします。

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー yk_taiko の写真

そもそもの実現したいことと、今回の設定の仕組みと意図が掴めていませんが,,,

トリガー条件2で 0<値<=600 ってことは 0 の時は対象外で復旧しますが、
そのアイテムは 0 を返さないのでしょうか。

ユーザー jusco0103 の写真

yk_taiko様
ご指摘ありがとうございます。
0を返す値でした。こちらの設定が間違っていたので、0<=値<=600に変更します。

本件のログ監視トリガーの意図として、以下3つになります。
・特定文言にマッチするログをトリガーとして発報する
・過去分のログを検知しないようにする
・一定時間が経った場合、復旧する

クライアント様側の要望として、発生するエラーログに対し、エラーの内容ごとに異なるトリガーを発報させたい
というのがございます。
そのため、アイテムに対し、同様の設定(条件1のregexp内文言が異なる)が約200ほどある状態です。

ユーザー yk_taiko の写真

「マッチしないログを検出」ですが、
実際にログが出ていないのにトリガーが動いたのか、
それともログは出ていたが、通知された内容が別のログだったのか
どちらでしょうか。

後者の場合、「ITEM.LASTVALUE」をトリガーやアクションで使用しているようでしたら、「ITEM.VALUE」にすることで直るかもしれません。

ユーザー jusco0103 の写真

ご連絡いただきありがとうございます。

「ログは出ていたが、通知された内容が別のログだった」が正しいです。

当方がログがマッチしていないと判断したのが、イベント>イベント詳細>メッセージアクションに記載されている
送信メールの本文からだったのですが、現在のメール本文の設定は{ITEM.VALUE1}となっておりました。
Agent側も大量にログを出していたため、以下と同じ事象が出ているということでしょうか。
http://www.zabbix.jp/node/3545

ユーザー yk_taiko の写真

前回発生時は恐らく以下動作な気がします。

ex.1
==============================================
1) 対象文字のログ出力。ただし、トリガー条件2により0秒となるためイベント出力無し
2) 1の直後に対象文字以外のログ出力。この時点で{ITEM.VALUE1}は他の文字列となる
3) ログ出力が1秒以上停止し、イベント出力。
・トリガー条件1:600秒以内に出力されているため合致
・トリガー条件2:0より大きい (1) になったため合致
・トリガー条件3:300秒以内にデータがあるため合致
このとき、2の出力により、{ITEM.VALUE1} は別の文字列になっている
==============================================

トリガー条件2を変更して0も含めているようでしたら正常に動作する可能性は増えますが、
それぞれのアイテムは独立して動いていることから、log監視とdifftime監視で微妙なラグが発生し、
以下のようななことが起こる可能性も考えられます。

ex.2
==============================================
1) 対象文字のログ出力。ただし、difftimeが更新されていないためトリガー条件2で601以上となりイベント出力無し
2) 1の直後に対象文字以外のログ出力。この時点で{ITEM.VALUE1}は他の文字列となる
3) difftimeが更新されてイベント出力。
==============================================

複数アイテムを使用している場合、なかなか難しいですね...

あと、トリガー条件3ですが、いらないかもしれないです。
トリガー条件2 でアイテムを1秒間隔で更新し、かつ特定時間内の出力有無も見てますよね。
役割的に被ってるかと。

ユーザー jusco0103 の写真

そうですね。おそらく検知しているログと表示するログの間にラグがあるからなのかと思います。
過去ログを取らないようにするための他手段があればぜひ試してみたいのですが、
ひとまずdifftimeの条件を0<=値<=600に設定し、翌日のイベントの様子を見たいと思います。
条件3は確かにnodataと同じ役割になっているので削除します。

ユーザー Yasumi の写真

これはまた難儀なログ監視をしていますね。。。
求めている監視条件定義をもっと詳しく知りたいですが、内容を推測した上でいくつか施策を考えてみました。
考慮すべきポイントが幾つかありますので、参考になればと思います。

■トリガー定義
下記のように番号を振らせていただきます。またトリガーの発動条件を明確にするためトリガーの発動条件を記載します。

①{Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR].iregexp(".*Serial read Error:errno.*",300)}<>0
⇒「ERROR」が含まれる「/var/log/dir/^system\.(log|log\.1)$」に、300秒間(※)文字列「.*Serial read Error:errno.*」がマッチしたら検知。
※どこ基準に300秒間? iregexpに時間指定しているものを見たことがないので挙動が分からない。。。

②{Template Template:difftime[].last()}>0
⇒difftime[]の最新値が0より大きい場合に検知。

③{Template Template:difftime[].last()}<=600
⇒difftime[]の最新値が600以下の場合に検知。

④{Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR].nodata(300)}=0
⇒「ERROR」が含まれる「/var/log/dir/^system\.(log|log\.1)$」に300秒間データが無い場合は「正常」(※)
※逆に言えば、「/var/log/dir/^system\.(log|log\.1)$」に300秒間以内の間隔で継続的に「ERROR」がログ出力され続けると、
 トリガーが「障害」状態のまま復旧しなくなる。復旧していないので、再度障害が発生してもアラート検知せず障害に気づけない危険性がある。

■①と④の修正(nodataの発動条件の整理したい)
提示されている監視トリガーですが、①と④で「障害」フラグの発動条件が被っている?ようにも思えます。
大量検知を予防するためのnodataだと思いますが、nodataはログ監視では不規則な動作を取ることが多いので、
発動条件をもっと限定的に整理したほうが良いと思います。少し大幅な変更点がありますが、私なりの修正案を提示しようかと思います。
※考え方が思っているような方向とズレている場合はすみません。。。
===========================================================================================
【修正案】
①{Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,@ERROR_Serial].count(300,"Serial")}>0
「@ERROR_Serial」が含まれる「/var/log/dir/^system\.(log|log\.1)$」に、300秒間で「Serial」が0件より多く出力されたら検知。

④{Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,@ERROR_Serial].nodata(300)}=0
「@ERROR_Serial」が含まれる「/var/log/dir/^system\.(log|log\.1)$」に、300秒間データが無い場合は「正常」にする。

「@ERROR_Serial」を新規正規表現として定義、「ERROR」に追加で「.*Serial read Error:errno.*」が真を設定。
⇒「nodata」の挙動を「.*Serial read Error:errno.*」が出力されるパターンに限定させたい。
===========================================================================================

■並列and条件を修正
現状ですと、and条件が並列化されており、「A and B and C and D」となっているため障害フラグがどこで立つのかかなり怪しいと感じます。
下記のように()でand条件を縛って、障害フラグを管理したいと感じます。
===========================================================================================
【修正案】
({Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,@ERROR_Serial].count(300,"Serial")}>0 and
({Template Template:difftime[].last()}>0 and {Template Template:difftime[].last()}<=600)) and
{Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,@ERROR_Serial].nodata(300)}=0

⇒「(A and (B and C)) and D」にトリガー発動条件を変更。
===========================================================================================

■イベントが06:10頃から07:20まで障害⇄復旧を繰り返す原因
これは恐らくですが、下記が原因で発生しています。
①監視対象の「Agentは毎日06:00頃起動し、16:00頃にシャットダウンする」こと
②「difftime[].last()」が「0」で復旧判定している
③「nodata」&「障害イベントを継続して生成:しない」でトリガー判定が60秒スパンにされている
④「nodata」が「障害」判定フラグを維持しようとしている

Agentが6:00頃起動し、短時間に夜間中のログ読み込みが発生するため、
そこから「.*Serial read Error:errno.*」をトリガーでマッチ判定し「障害」フラグを立てるのに10分程度要しているのかも知れません。
その後は、恐らく「difftime[].last()」が「0」で復旧判定になるため即時復旧。
「nodata」&「障害イベントを継続して生成:しない」で見たことがある動作(バグ?)なのですが、
トリガー判定が60秒スパンになる挙動を取ることがあります。そのため「障害」判定フラグが約1分後に立つのだと思われます。

また「nodata」は「障害」判定フラグを維持しようとする挙動を取ります。それが災いし、7:20まで継続するのかもしれません。

■その他考慮点
「/var/log/dir/^system\.(log|log\.1)$」がかなり気になっています。これはもしかしてですが、
「system.log」と「system.log.1」などが併存しており、どちらのログにも、同日内にログ出力があるという認識で正しいでしょうか?

もしそうだとすると、「system.log」にログ出力された後、「system.log.1」にログが出力されて、
そしてまた「system.log」にログ出力されると、Zabbixは「system.log」を最初からすべて読み直してしまいますが大丈夫でしょうか。
そうなると過去ログを再取得し、アラートを無意味に検知してしまうことになるので、挙動的にとても良くないです。複数のログを1つのアイテムに格納するべきではないです。

以上なので、参考になればと思います。

ユーザー jusco0103 の写真

Yasumi-sha様

非常にご丁寧なご返信を頂き、誠にありがとうございます。
また、修正案までご教示くださり、本当に感謝しております。
ぜひ参考にさせて頂きます。

また、頂きました修正案、およびご質問について、回答させて頂きます。

まず、そもそもの要件から情報が不足しておりましたので、以下に記載します。
・エラーログの内容ごとに異なるトリガーを発報したい(例:ログ文言:AAA → トリガー名:AAAが検知されました ログ文言:BBB → トリガー名:BBBが検知されました)
・昨日分や、数時間前などの過去のログを検出しないようにしたい。

上記から、アイテムをエラー内容ごとに作ってしまうとログ監視だけで数100種類できてしまい、1秒あたりの監視項目数が膨大になりかねないため、
トリガー側で対応できないかという考えから現在トリガー作成をしております。(現時点で200項目ほど作成しており、今後も増えることが予測されます。)

上記要件から、トリガー設定の意図として、以下のように設定いたしました。
・障害の条件としたいログの文言が、ログ1行の中に複数含まれているため、iregexpの正規表現を使用しています。
また、iregexpに時間指定を入れたのはエラーログが数種類、連続して出力すると、障害←→復旧を繰り返してしまうのを抑止するためです。
(時間指定について、アイテム検知した時点から指定した秒数分、過去のアイテムを収集・分析する動きだったかと記憶してますが、正確な記載はドキュメントにもありませんでした。)
・過去ログを検知しないようにする件は、条件②③にてZabbixの時間とログ内のタイムスタンプの差分が600以内である場合に障害とするようにしています。
・復旧条件がないため、nodataを使用して、300秒以内にログが出力されなければ復旧するようにしました。

ただ、ご教示頂きましたnodataの挙動や内容からすると、トリガーにてログの抽出を細分化するのではなく、アイテムから細分化させた方が本件のような動作が起きないと
理解しましたので、どのように対応するか検討したいと思います。
また、and条件の修正も合わせて行いたいと思います。
logrtについては、system.log.1がローテートされたファイルなので、ファイルローテート後はsystem.logが0バイトからスタートするため問題はないかと考えております。

ちなみにiregexpにて指定した条件とマッチしない文言が検出される件について、もしご見識ございましたら、お手数ですがご教示いただけますと幸いです。

以上です。宜しくお願い致します。

ユーザー Yasumi の写真

>jusco0103さん

こんばんは。環境について承知しました。幾つか返答いたします。

■アイテムの細分化について
アイテム数が増えることで、ログ管理とZabbixのリソース不足を懸念されていると理解します。
しかし、1つのアイテムにトリガーを集約しすぎると監視変更が発生した時のインパクトが大きくなり、
後々トリガーや正規表現の制御が困難になることが予想されます。

ある程度 共通化できる監視条件のものはアイテムを細分化し、計画的に分離することをおすすめします。
下記のようなかたちで、分離元のアイテムから分離先の条件を除外するようにすることで
分離元のアイテムに掛かる負荷を軽減することも可能です。

==========================================================================================
・全体
logrt[/var/log/dir/^system\.(log|log\.1)$,@ERROR]

「@ERROR」
①ERROR が含まれる
②「.*Serial read Error:errno.*」が偽
⇒『全体』から『ERROR_Serial』のログを除外することで
 分離元のログアイテム負荷を軽減。

・ERROR_Serial
logrt[/var/log/dir/^system\.(log|log\.1)$,@ERROR_Serial]

「@ERROR_Serial」
①ERROR が含まれる
②「.*Serial read Error:errno.*」が真
⇒アイテムを分離することで、トリガー管理を容易にする。
==========================================================================================

また、リソース面については、後半に『Zabbixキャッシュ使用率』について書きますので、
そちらを参考にしてみてください。

■過去ログ抑止手法
おそらく環境的に実現が難しいとは思いますが、手法的には
ログのローテート設定を1時間ごとにすることをおすすめします。
(例)system.YYYYMMDDHH.logなど

ローテート設定を短くするとログ管理が煩雑になるきらいもありますが
大量にログが出力される環境では過去ログ検知の被害を軽減させる手段として有効です。

■iregexpにて指定した条件とマッチしない文言が検出される件
これは先に記載しました『「nodata」が「障害」判定フラグを維持しようとしている』が原因と思われます。
例えば「nodata(300)」とすると、nodataは『300秒間「障害」判定フラグを維持する』という挙動を取ります。
※大量検知抑止にnodataを使うのは、「障害」判定フラグを維持させることで複数検知を防いでいる

「difftime[].last()」が「0」で復旧判定されるものの、nodata自体は「logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR]」に対して
「障害」判定フラグを維持しようとする動作を取っていると思われます。

logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR]にログは何時頃まで継続出力されているでしょうか?

もし7:20頃まで出力されている、あるいは読み込みに時間がかかっておりますと、nodataは「まだ300秒間ログ出力が停止していないから障害だ!」と判定し、
問答無用でトリガーのステータスを「障害」で維持しようとする動作を取ると思います。
※そして「障害イベントを継続して生成:しない」でトリガー判定が60秒スパンになっている。

そのため、「iregexpにて指定した条件とマッチしない文言が検出される」という考え方よりも
『logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR]にまだログが出力されているとnodataが判定している=障害フラグが継続する』という考え方がより適切です。
つまり、どんなログだろうが、一度トリガーが発動すればnodataが「300秒間ログ出力が停止した」と判定するまで何度別条件で復旧しても障害が継続すると考えてよいと思います。

アクション設定にしている{ITEM.VALUE1}には、logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR]の最新アイテムが記録されるだけですので、
この場合には{ITEM.VALUE1}≠「トリガー判定したログ」となります。「iregexpにて指定した条件とマッチしない文言が検出される」というのは、
動作の見かけ上でそうなっているだけで誤解に近いと言えると思います。

※余談ですが、yk_taiko様がnodata不要と書かれておりますが、もし「.*Serial read Error:errno.*」を
大量に検知する恐れがある場合ですと、面倒くさい挙動(60秒?ごとに該当ログ出力数分トリガーが動く)をZabbixが取る可能性があるので、少し気になっております。

■リソース面について
Zabbix3.0環境とのことで、下記のZabbix内部データが存在する/あるいは取得可能だと思います。
下記を参考にリソース面での調整の参考にしてみてください。

・Zabbixプロセス負荷率【alerter】
 zabbix[process,alerter,avg,busy]
⇒通知レポートを送信するプロセス。100%になるとアクション動作に遅延が発生します(監視影響)。
 Zabbix 3.0ではalerterが1つしか稼働できないため、大量アラート検知時にalerterプロセス負荷率が上昇しやすい。
 20~30%あたりを基準にトリガーで監視してみるのも良いかもしれません。

・Zabbixキャッシュ使用率
 zabbix[vcache,buffer,pused]
⇒Zabbixに割り当てられるメモリの使用率。50%を超えると危険域、100%になるとZabbixがリソース不足でDownします。
 アイテム負荷率を気にする場合、この値を参考にしてください。
 30%以下が望ましく、それ以上の使用率の場合はzabbix_server.confのCacheSizeを増加することを推奨します。
※環境にもよりますが、最大OSのメモリの50%まで割り当てしても良い。

===================================================================
/etc/zabbix/zabbix_server.conf
CacheSize=XX
===================================================================

ユーザー jusco0103 の写真

Yasumi-sha様

先日に続き、丁寧なご回答、本当に感謝しております。

現状当方以外にZabbixに携わる者がおらず、また構築は未経験のため、
マニュアルに書いていないZabbixの挙動からチューニング、運用方法までご教示いただけることは何よりも救いです。
重ねて御礼申し上げます。ありがとうございます。

ご教示いただいた内容について、浅薄ながら恐れ入りますが、以下のように理解しました。
相違ございましたらご指摘いただけますと幸いです。

■アイテムの細分化について
アイテムの細分化はZabbixの正規表現を使ってある条件(本件では"ERRORを含む”)の中から
①特定の文言にマッチするもの
②①を含まないもの
に分け、①のアイテムが増えていくにつれて②の正規表現に偽とする文言を追加していき、それぞれのアイテムにトリガーを設定する。
(その際トリガーはcount、nodataを使った条件式を設定する?)
上記を行うことで、アイテムとトリガーがほぼ1対1となり、管理が容易となる。また、アイテムキー変更時のインパクトが現状より少なくなる。

■過去ログ抑止手法
トリガーで対応するのではなく、ログローテートで対応する。

■iregexpにて指定した条件とマッチしない文言が検出される件
.nodata()の挙動(指定秒数間"障害"状態を維持する)により、他条件で復旧となっても障害を継続する動きから復旧→60秒ごとに判定→障害を繰り返す動きとなる。
※ちなみにlogrt[/var/log/dir/^system\.(log|log\.1)$,ERROR]には確認できた限り08:00まで継続出力しており、おそらく以降も出力し続けていました。
{ITEM.VALUE}での判断はラグがあった場合ズレるので、条件にマッチしていないのを検出した訳ではない。

■リソース面について
alerterprocessとZabbixに割当されているキャッシュメモリを参考にConfのチューニング、アイテム・トリガー数の調整等を行う

ユーザー yk_taiko の写真

変更後に使用されていませんが、nodata の解釈について少し気になりましたので、以下記載します。

nodata() はトリガー判定時、
該当アイテムヒストリに()で指定した秒数以内にデータが存在するかどうかを確認し、
存在する場合は0、存在しない場合は1を返す判定式です。
「他の条件式の結果に関わらず障害状態を維持する」挙動ではありません。
(もちろん、条件式の組み方によっては似た挙動にすることもでると思います。)

ログ監視で nodata がよく使われる理由ですが、主にログ監視トリガーを復旧させるために使用されていると思います。
・regexp などの文字列条件のみを指定した場合、アイテムが更新(ログが出力)されないとトリガー判定が行われません。(復旧タイミングの制御が難しい)
・nodata を使用すると、アイテム更新時に加えて毎分0秒と30秒 にトリガー判定を行うようになります。(定期的に動作するようになるため、復旧させやすい)
- https://www.zabbix.com/documentation/3.0/manual/config/triggers

今回設定されている内容ですと、条件2のアイテムが1秒に1回動いていることからトリガー判定も1秒に1回されており、復旧の判定も行うことから、上記のnodataの役割と同じことを担っていると思います。
(前回のコメントで記載した内容です)

尚、障害イベントを継続して生成「する」ようにしていると、トリガー判定毎にイベントが作られるため、
nodataだと30秒おき、今回だと1秒おきに、条件に合致し続ける限り(=ログが出力されなくても) イベントが作成され続けます。
ご注意ください。(悩ましいところです...)

ユーザー jusco0103 の写真

yk_taiko様
Yasumi-sha様

本件について、ご見識をいただき誠にありがとうございます。
現在トリガーの条件を以下の設定にし概ね想定通りの動きとなりましたのでご報告します。
条件式:
{Template Template:logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR].iregexp(".*Serial read Error:errno.*",300)}<>0 (and
{Template Template:difftime[].last()}>=0 and
{Template Template:difftime[].last()}<=600)

変更点は以下3点です。
・条件2の不等号を変更(0<=n<=600)
・条件2を()でくくる
・条件3を削除

Yasumi-sha様が懸念されていたマッチする文言のログを大量検知した場合については、複数障害イベントが複数出るような挙動はありませんでした。
ログローテートについても開発者側に確認したところ、1時間ごとにローテートされており、昨日分のログが監視対象のログに書かれた状態のままシャットダウン→翌日起動→Zabbix検知の流れになっておりました。
起動時にきちんとローテートするようできないか、確認しているところでございます。
ただ、アイテム・トリガーの運用方法、チューニングについてはぜひ今後の課題として取り組みたいと思います。

取り急ぎ、ご連絡致します。

ユーザー Yasumi の写真

>jusco0103さん

こんばんは。お役に立てましたら幸いです。

返信に記載いただいております内容ですが、おおよそ認識齟齬ございません。

アイテム細分化については、やはり数が増えすぎると負荷になる部分はありますので
必要に応じてトリガー条件で共通化している部分を切り出すのがベターと思います。

「①のアイテムが増えていくにつれて②の正規表現に偽とする文言を追加していき、
それぞれのアイテムにトリガーを設定する」も負荷軽減を想定に入れての運用になります。

また、countは件数監視(1時間に2件発生で検知、など)に利用するのが本来ですので、
1件でトリガー発報させる場合はiregexpで問題ありません。
nodataに関しましても、ログ監視では基本的にアラートの大量検知を予防するためのものですので、
大量検知の恐れがない場合は使わなくても問題ありません。

下記はおおよその切り出しする場合のイメージです。

==========================================================-
①トリガー条件で共通しているものをピックアップする

・アイテム
logrt[/var/log/dir/^system\.(log|log\.1)$,ERROR]

・トリガー
ログ監視【ERRORとAAAを検知】
ログ監視【ERRORとBBBを検知】
ログ監視【ERRORとSerialとAAAを検知】
ログ監視【ERRORとSerialとBBBを検知】...etc

上記のように「Serial」で共通しているトリガー条件があるので、必要な場合は
「Serial」が含まれるトリガーパターン用にアイテムを分離する計画を立てる。
※共通項を抜き出すことで、トリガーパターンに合わせて
 アイテム数が無秩序に増えてしまうことを抑制できます。

②正規表現を利用してアイテムを分離
・アイテム
logrt[/var/log/dir/^system\.(log|log\.1)$,@ERROR_Serial]

・正規表現
「@ERROR_Serial」
①ERROR が含まれる
②「.*Serial read Error:errno.*」が真

※この際に負荷軽減を考慮に入れる場合は、分離元の正規表現に
「.*Serial read Error:errno.*」が偽などを入れると実現可能となります
 ただし、分離元のアイテムに分離先の内容が取得されなくなることで
 影響があるかどうかを確認するのが良いかもしれません。
==========================================================-

Zabbix運用が良くなるといいですね。以上となります。