Enterprise 技術情報 Enterprise Technical information
Kompiraの機能 Kompiraでの文字列のパターンマッチング
Kompiraがチャネル、メールチャネル、API、kompira_sendevtモジュールなど、外部から受信したデータを解析して、ジョブフローの処理の起動を行ったり、処理条件を変える事があります。このような場合には受信した文字列を解析するために、文字列のパターンマッチングが必要となります。
動作確認環境
ソフトウェア | バージョン |
---|---|
Kompira | 1.4.10.post10 |
LinuxOS | CentOS6.10 |
または
ソフトウェア | バージョン |
---|---|
Kompira | 1.5.5.post7 |
LinuxOS | CentOS7.8.2003 |
Kompiraでパターンマッチングを行う場合には、パターン型オブジェクトを利用します。パターンの種別は、’r’ (正規表現パターン)、’g’ (glob パターン)、’e’ (完全一致パターン) の3種類があります。また、パターンマッチングを行う場合、大文字、小文字を区別しないモード (‘i’) を組み合わせることもできます。
パターン型オブジェクトを作成するには、組み込み関数”pattern()”を利用します。
ptn_obj = pattern (pattern, typ='r', mode='')
引数:
■ pattern は、マッチングを行うパターンを指定します。
■ typ はパターンの種別を表し、 “r” (正規表現パターン)、”g” (glob パターン)、”e” (完全一致パターン) のいずれかを指定することができます。
■ mode には、”i”を指定すると大小文字を区別しないパターン照合となります。指定しない場合は、大小文字を区別します。
戻り値:
■ パターン型オブジェクト(ptn_obj)を返します。
パターン型オブジェクトは、文字列 s とパターンとのマッチングを試みるmatch()メソッドを備えています。
ptn_obj.match(s)
引数:
■ sは、マッチング対象の文字列を指定します。
戻り値:
■ マッチした場合は true、もしくはパターンが正規表現パターンの場合はマッチした情報を格納した辞書を返します。
■ マッチしなかった場合は、false を返します。
続いて、ログファイルの行をサンプルにして、各マッチング種別の動きを見ていきましょう。
完全一致パターン
完全一致パターンは、対象の文字列とパターンで指定した文字列が一致するかを確認します。
対象の文字列とパターンで指定した文字列が一致する場合はtrue, 一致しない場合にはfalseを返します。
|sequence = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending a SIGTERM"| |ptn_1 = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending a SIGTERM"| |ptn_2 = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending"| print("ptn_1とのマッチング") -> [match_rst = pattern(ptn_1, typ="e").match(sequence)] => {if match_rst | then: print("マッチ") else: print("ミスマッチ") } -> print(match_rst) -> print("ptn_2とのマッチング") -> [match_rst = pattern(ptn_2, typ="e").match(sequence)] => {if match_rst | then: print("マッチ") else: print("ミスマッチ") } -> print(match_rst)
上記の場合、ptn_1とのマッチング結果は結果は、trueとなり、ptn_2とのマッチング結果は、falseとなります。
完全一致パターンは、以下のように単純な文字列比較として記述することもできます。
|sequence = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending a SIGTERM"| |ptn_1 = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending a SIGTERM"| |ptn_2 = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending"| print("ptn_1とのマッチング") -> {if sequence == ptn_1| then: print("マッチ") else: print("ミスマッチ") } -> print("ptn_2とのマッチング") -> {if sequence == ptn_2| then: print("マッチ") else: print("ミスマッチ") }
globパターン
globパターンでは、Unixのシェル形式のワイルドカードを用いることができ、以下の特別な文字に対応しています。
■ * すべての文字にマッチ
■ ? 任意の一文字にマッチ
■ [seq] seq にある任意の文字にマッチ
■ [!seq] seq にない任意の文字にマッチ
■ *、?、[などの特殊文字をエスケープしたい場合は、[*]、[?]、[[]のように[]で囲って記述する
ログに”[warn]”という文字列が含まれているかを判別する処理は、以下のよう(“*[[]warn[]]*”)に、globパターンを用いて記述することができます。
match()は一致する場合はtrue, 一致しない場合にはfalseを返します。以下の例では、ptn_1はtrueを返しますが、ptn_2はfalseを返します。
|sequence = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending a SIGTERM"| |ptn_1 = "*[[]warn[]]*" | |ptn_2 = "*[[]warn []]*" | print("ptn_1とのマッチング") -> [match_rst = pattern(ptn_1, typ="g").match(sequence)] => {if match_rst| then: print("マッチ") else: print("ミスマッチ") } -> print(match_rst) -> print("ptn_2とのマッチング") -> [match_rst = pattern(ptn_2, typ="g").match(sequence)] => {if match_rst| then: print("マッチ") else: print("ミスマッチ") } -> print(match_rst)
globパターンは、比較的単純なマッチングにおいて有効な方法です。
正規表現パターン
正規表現パターンは、プログラミング言語 Python の re モジュールの正規表現に準じています。
また、match()メソッドの応答は、完全一致やglob型と異なり、マッチした場合は、マッチした情報を格納した辞書を返します。( )でくくったグループごとに、マッチした文字列を返します。
(マッチしなかった場合は、”false”を返します)
以下の処理では、ログ取得の日時、ログレベル、メッセージの3つの情報にマッチさせて、それぞれ個別に表示します(ptn_1)。
マッチした文字列は応答中のgroupsに格納されます。マッチしない場合は、falseが返ります(ptn_2)。
特殊文字をエスケープしたい場合は、\をエスケープしたい文字の直前に記述します。
|sequence = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending a SIGTERM"| |ptn_1 = "\[(.+)\] \[(warn|error)\] (.+)" | |ptn_2 = "\[(.+)\] \[(warn_|eror)\] (.+)" | print("ptn_1とのマッチング") -> [match_rst = pattern(ptn_1, typ="r").match(sequence)] => # 正規表現によるマッチ {if match_rst | then: print("マッチ") -> print("timestamp: ", match_rst.groups[0]) -> print("level : ", match_rst.groups[1]) -> print("message : ", match_rst.groups[2]) else: print("ミスマッチ") } -> print(match_rst) -> print("ptn_2とのマッチング") -> [match_rst = pattern(ptn_2, typ="r").match(sequence)] => # 正規表現によるマッチ {if match_rst | then: print("マッチ") -> print("timestamp: ", match_rst.groups[0]) -> print("level : ", match_rst.groups[1]) -> print("message : ", match_rst.groups[2]) else: print("ミスマッチ") } -> print(match_rst)
正規表現でのマッチングは、glob型より複雑ですが、より細かい条件設定を行うことが出来ます。
パターンリテラル
これまではマッチングパターンのオブジェクトを作成するためにpattern()関数を利用してきました。
Kompiraでは、pattern()の代わりに、パターンリテラルを用いる事も出来ます。
パターンリテラルは、パターンの種別を表す ‘e’, ‘g’, ‘r’ のいずれかの文字に引き続き、一重引用符(‘)、もしくは、二重引用符(”)で囲まれた0個以上の文字(パターン文字列)で表現されます。
上記の「正規表現パターン」のジョブフローは、パターンリテラルを用いると以下のように既述することができます。
|sequence = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending a SIGTERM"| print("ptn_1とのマッチング") -> [match_rst = r"\[(.+)\] \[(warn|error)\] (.+)".match(sequence)] => # 正規表現のパターンリテラルによるマッチ {if match_rst| then: print("マッチ") -> print("timestamp: ", match_rst.groups[0]) -> print("level : ", match_rst.groups[1]) -> print("message : ", match_rst.groups[2]) else: print("ミスマッチ") } -> print(match_rst) -> print("ptn_2とのマッチング") -> [match_rst = r"\[(.+)\] \[(warn_|eror)\] (.+)".match(sequence)] => # 正規表現のパターンリテラルによるマッチ {if match_rst| then: print("マッチ") -> print("timestamp: ", match_rst.groups[0]) -> print("level : ", match_rst.groups[1]) -> print("message : ", match_rst.groups[2]) else: print("ミスマッチ") } -> print(match_rst)
実行結果はpattern()を使った場合と同様になります。正規表現以外にも完全一致、glob型の場合も同様に記述する事が出来ます。
正規表現パターンの名前付きグループ
正規表現を利用してパターンを使って値を参照しようとする場合、値はgroupsという配列に格納されているため、パターン中の順序を意識する必要があります。
Kompiraでは、各パターンのグループに明示的に名前をつけることで、名前を用いて値を参照することができます。
名前つきグループのための構文は、固有拡張の一つ: (?P…) を使います。
上記の「パターンリテラル」のジョブフローを以下のように書き換えることで、名前付きグループを用いることができます。
|sequence = "[Wed Aug 30 09:44:40 2017] [warn] child process 13408 still did not exit, sending a SIGTERM"| [match_rst = r"\[(?P<timestamp>.+)\] \[(?P<level>warn|error)\] (?P<message>.+)".match(sequence)] => # 正規表現によるマッチ {if match_rst| then: print("マッチ") -> print("timestamp:" , match_rst.groupdict.timestamp) -> print("level :" , match_rst.groupdict.level) -> print("message :" , match_rst.groupdict.message) else: print("ミスマッチ") } -> print(match_rst)
それぞれの要素に”timestamp”, “level”, “message”という名前を付けています。
出力は、以下のようになります。
マッチさせた文字列は、groupdictという辞書に指定した名前をキーにして格納されていますので、上記の例では”match_rst.groupdict.timestamp”のように参照できます。
このようにしてパターン型オブジェクトやパターンリテラルを用いることで、文字列のパターンマッチングを行うことができ、文字列から必要な情報を取得したりするなど、文字列の解析を行うことができます。
スタートガイド
Kompiraジョブフローの基礎
ジョブフローの簡単な例
Kompiraの機能
-
- フィールド修飾子でフィールドの入力内容に制約を設ける
- Kompiraでの文字列のパターンマッチング
- Kompira上でWikiページを作成する
- スケジューラを使って定期的にジョブを実行する
- ジョブフローを実行するフォームを作成する
- テーブル内の情報を選択して処理を実行する
- ジョブフローに権限設定をする
- ジョブフロー画面の各種設定
- Pythonで記述された処理をKompiraから呼び出す
- Kompiraオブジェクトのプロパティ,メソッド,フィールドを扱う
- Windowsでリモートスクリプトを実行する(その1)
- Windowsでリモートスクリプトを実行する(その2)
- Kompira上のデータをバックアップする(その1)
- Kompira上のデータをバックアップする(その2)
- Kompira上のデータをバックアップする(その3)
外部との連携
-
- Prometheusからの通知をKompiraで受信する
- Kompira cloud Pigeonを利用した通知電話の利用
- ネットワーク機器へのコマンド投入
- KompiraからWindowsGUIアプリケーションを操作する (1/2)
- メールを送信する
- メール受信をトリガーにしてジョブフローを実行する
- アラートメールをフィルタリングして転送する
- チャネルを利用して外部システムからデータを受信する
- Webページから内容を取得する
- Redmineへ新規チケットを登録する
- Redmineでのチケット作成をKompiraに通知する
- Kompira REST APIを利用して外部からジョブフローを実行する
- Kompira REST APIを利用して外部からオブジェクト情報を取得する
- KompiraからSlackに通知する
- Slackでの投稿をKompiraに通知する
- KompiraからTwilioで電話をかける
- Zabbixからの通知をKompiraで受信する
- syslogをKompiraで受信する
- snmptrapをKompiraで受信する
- KompiraでExcelファイルの読み書きをする
- KompiraでGoogle SpreadSheetの読み書きをする
- Active Directoryから情報を取得する
- Active Directoryにユーザーを登録する