JAva-grok正規表現によるログの解析
6846 ワード
プロジェクトの中で1つの新しい需要があって、ログを解析する必要があって、ログの中の部分のデータの分析をシステムのために取得して使用して、通俗的に言えばログの中の部分の役に立つ情報をつかむことで、例えば以下のapacheログの情報、私は各行のログを解析する必要があって、各行のログのIPアドレス、ユーザー、作成時間、要求方式を取得しますアドレス....javaを単純に使用すると、ファイルストリームを介してログ情報を読み取り、文字列を行単位で解析することが考えられるかもしれませんが、この方法は複雑すぎて効率が低く、ネット上で関連資料を検索し、logstashのgrokツールを使用することを決定し、ネット上でも対応するjava実装があり、その実現原理はカスタム正規表現であり、正規表現でログを解析するメリットは、mapやjsonなど、ログ内の不規則なデータをルールのデータに変換できることです.また、一度式を書いた後、複数の場所で実行できることです.何か違うところがあれば、正規表現を修正するだけでいいのではないでしょうか.
64.242.88.10 - - [07/Mar/2004:16:05:49 -0800] "GET/twiki/bin/edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables HTTP/1.1"401 12846 64.242.88.10 - - [07/Mar/2004:16:06:51 -0800] "GET/twiki/bin/rdiff/TWiki/NewUserTemplate?rev1=1.3&rev2=1.2 HTTP/1.1"200 4523 64.242.88.10 - - [07/Mar/2004:16:10:02 -0800] "GET/mailman/listinfo/hsdivision HTTP/1.1"200 6291 64.242.88.10 - - [07/Mar/2004:16:11:58 -0800] "GET/twiki/bin/view/TWiki/WikiSyntax HTTP/1.1"200 7352 64.242.88.10 - - [07/Mar/2004:16:20:55 -0800] "GET/twiki/bin/view/Main/DCCAndPostFix HTTP/1.1"200 5253
ネット上のgrokの定義は、GrokはLogstashの最も重要なプラグインです.grokで名前付き正規表現を事前に定義し、後で(grokパラメータまたは他の正規表現で)参照することができます.参考ブログ:http://udn.yyuap.com/doc/logstash-best-practice-cn/filter/grok.html
Java api方式でgrokを統合し、githubに関連するプロジェクトプロジェクトが実現され、githubでこのプロジェクトを取得することができます.https://github.com/thekrakken/java-grok、またはパッケージ化されたjarパッケージと関連する依存パッケージを直接使用して、私のリソースディレクトリでダウンロードできます.http://download.csdn.net/detail/harderxin/9923587
依存パッケージには、commons-beanutils-1.8.3.jar、commons-lang 3-3.1.jar、commons-logging-1.1.1.jar、gson-2.2.2.jar、slf 4 j-api-1.7.5.jarが含まれます.バージョン番号は上記と同じではありません.
mavenプロジェクトの場合はpom.xmlファイルに次の依存を追加できますが、他の依存パッケージは自分で導入する必要があります.
では、関連apiの操作を開始します.新しいプロジェクトを作成し、関連するjarパッケージを導入します.java-grokプロジェクトのデフォルトの正規表現ファイルを導入します.数字、テキスト、日付、IPアドレスなどの列の基礎データを定義した正規表現です.参考:https://github.com/thekrakken/java-grok/blob/master/patterns/patterns
Java-grokを使用するには、まず正規表現ファイルのパスを定義してGrokオブジェクトを作成する必要があります.単一列モードとして定義できます.
Grokオブジェクトを取得したら、解析するログの式名と変換するログメッセージを入力して、Matchオブジェクトを作成します.
Matchオブジェクトを取得すると、対応するMapまたはJsonデータにデータを変換できます.補助クラスを書きました.
テストクラスを作成します.注意:
上の各解析では、ログ内の1行のデータしか解析できません.ログ・ファイルを解析するには、そのファイルを行ごとに解析する必要があります.次の行のログを解析する必要があります.
64.242.88.10--[07/Mar/2004:16:45:56-0800]"GET/twiki/bin/attach/Main/PostfixCommands HTTP/1.1"401,846、プログラム解析後、clientip=64.242.88.10、timestamp= 07/Mar/2004:16:45:56-0800、verb=GET、httpversion=1.1などのフォーマットされたデータは、私たちの上のプログラムでできます.
patternsファイルで、解析ログの正規表現を定義します.
XINTEST %{IPORHOST:clientip} %{USER:ident;boolean} %{USER:auth}[%{HTTPDATE:timestamp;date;dd/MMM/yyyy:HH:mm:ss Z}\]\"(?:%{WORD:verb;string} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion;float})?|%{DATA:rawrequest})\"%{NUMBER:response;int} (?:%{NUMBER:bytes;long}|-)
IPORHOSTはpatternで定義されている正規表現です.以下に示すように、clientipは解析後のデータのKeyの別名です.別名がない場合、デフォルト名は正規表現の名前です.
IP (?:%{IPV6:UNWANTED}|%{IPV4:UNWANTED}) HOSTNAME\b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)
IPORHOST(?:%{HOSTNAME:UNWANTED}|%{IP:UNWANTED})私たちのpattern式が作成されました.名前はXINTESTです.次は私たちのコードを使ってテストすることができます.テストの時、pattern式は%{}を使って名前を入れる必要があります.これは規定です.
コード出力のjsonデータは以下の通りです.
ログに関連するデータは私たちのプログラムで解析されました!!実はその原理は私たちが正規表現をカスタマイズして、それから正規表現を通じて各行のデータをマッチングして、ユーザー定義のkey:valueデータに変換します!この機能があれば、私たちが解くことができるログはどんなに複雑で変化しても、その中のデータが一定の正規表現に従う限り式マッチングルールで、必要なデータに変換できます!
64.242.88.10 - - [07/Mar/2004:16:05:49 -0800] "GET/twiki/bin/edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables HTTP/1.1"401 12846 64.242.88.10 - - [07/Mar/2004:16:06:51 -0800] "GET/twiki/bin/rdiff/TWiki/NewUserTemplate?rev1=1.3&rev2=1.2 HTTP/1.1"200 4523 64.242.88.10 - - [07/Mar/2004:16:10:02 -0800] "GET/mailman/listinfo/hsdivision HTTP/1.1"200 6291 64.242.88.10 - - [07/Mar/2004:16:11:58 -0800] "GET/twiki/bin/view/TWiki/WikiSyntax HTTP/1.1"200 7352 64.242.88.10 - - [07/Mar/2004:16:20:55 -0800] "GET/twiki/bin/view/Main/DCCAndPostFix HTTP/1.1"200 5253
ネット上のgrokの定義は、GrokはLogstashの最も重要なプラグインです.grokで名前付き正規表現を事前に定義し、後で(grokパラメータまたは他の正規表現で)参照することができます.参考ブログ:http://udn.yyuap.com/doc/logstash-best-practice-cn/filter/grok.html
Java api方式でgrokを統合し、githubに関連するプロジェクトプロジェクトが実現され、githubでこのプロジェクトを取得することができます.https://github.com/thekrakken/java-grok、またはパッケージ化されたjarパッケージと関連する依存パッケージを直接使用して、私のリソースディレクトリでダウンロードできます.http://download.csdn.net/detail/harderxin/9923587
依存パッケージには、commons-beanutils-1.8.3.jar、commons-lang 3-3.1.jar、commons-logging-1.1.1.jar、gson-2.2.2.jar、slf 4 j-api-1.7.5.jarが含まれます.バージョン番号は上記と同じではありません.
mavenプロジェクトの場合はpom.xmlファイルに次の依存を追加できますが、他の依存パッケージは自分で導入する必要があります.
io.thekraken
grok
0.1.5
では、関連apiの操作を開始します.新しいプロジェクトを作成し、関連するjarパッケージを導入します.java-grokプロジェクトのデフォルトの正規表現ファイルを導入します.数字、テキスト、日付、IPアドレスなどの列の基礎データを定義した正規表現です.参考:https://github.com/thekrakken/java-grok/blob/master/patterns/patterns
Java-grokを使用するには、まず正規表現ファイルのパスを定義してGrokオブジェクトを作成する必要があります.単一列モードとして定義できます.
package com.harderxin.grok.core;
import io.thekraken.grok.api.Grok;
import io.thekraken.grok.api.exception.GrokException;
public class GrokInstance {
private static Grok grok;
private GrokInstance() {
}
public static Grok getGrokInstance(String grokPatternPath) {
if (grok == null) {
try {
grok = Grok.create(grokPatternPath);
} catch (GrokException e) {
e.printStackTrace();
}
}
return grok;
}
}
Grokオブジェクトを取得したら、解析するログの式名と変換するログメッセージを入力して、Matchオブジェクトを作成します.
public static Match getMatch(String pattern, String message) {
Match match = null;
try {
grok.compile(pattern);
match = grok.match(message);
match.captures();
} catch (GrokException e) {
e.printStackTrace();
match = null;
}
return match;
}
Matchオブジェクトを取得すると、対応するMapまたはJsonデータにデータを変換できます.補助クラスを書きました.
package com.harderxin.grok.core;
import java.util.Map;
import io.thekraken.grok.api.Grok;
import io.thekraken.grok.api.Match;
import io.thekraken.grok.api.exception.GrokException;
public class GrokUtils {
private static final String GROK_PATTERN_PATH = "conf/agent_patterns";
private static Grok grok = GrokInstance.getGrokInstance(GROK_PATTERN_PATH);
public static Map toMap(String pattern, String message) {
Match match = getMatch(pattern, message);
if (match != null) {
return match.toMap();
}
return null;
}
public static String toJson(String pattern, String message) {
Match match = getMatch(pattern, message);
if (match != null) {
return match.toJson();
}
return null;
}
private static Match getMatch(String pattern, String message) {
Match match = null;
try {
grok.compile(pattern);
match = grok.match(message);
match.captures();
} catch (GrokException e) {
e.printStackTrace();
match = null;
}
return match;
}
}
テストクラスを作成します.注意:
上の各解析では、ログ内の1行のデータしか解析できません.ログ・ファイルを解析するには、そのファイルを行ごとに解析する必要があります.次の行のログを解析する必要があります.
64.242.88.10--[07/Mar/2004:16:45:56-0800]"GET/twiki/bin/attach/Main/PostfixCommands HTTP/1.1"401,846、プログラム解析後、clientip=64.242.88.10、timestamp= 07/Mar/2004:16:45:56-0800、verb=GET、httpversion=1.1などのフォーマットされたデータは、私たちの上のプログラムでできます.
patternsファイルで、解析ログの正規表現を定義します.
XINTEST %{IPORHOST:clientip} %{USER:ident;boolean} %{USER:auth}[%{HTTPDATE:timestamp;date;dd/MMM/yyyy:HH:mm:ss Z}\]\"(?:%{WORD:verb;string} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion;float})?|%{DATA:rawrequest})\"%{NUMBER:response;int} (?:%{NUMBER:bytes;long}|-)
IPORHOSTはpatternで定義されている正規表現です.以下に示すように、clientipは解析後のデータのKeyの別名です.別名がない場合、デフォルト名は正規表現の名前です.
IP (?:%{IPV6:UNWANTED}|%{IPV4:UNWANTED}) HOSTNAME\b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)
IPORHOST(?:%{HOSTNAME:UNWANTED}|%{IP:UNWANTED})私たちのpattern式が作成されました.名前はXINTESTです.次は私たちのコードを使ってテストすることができます.テストの時、pattern式は%{}を使って名前を入れる必要があります.これは規定です.
package com.harderxin.grok.test;
import java.util.Map;
import com.harderxin.grok.core.GrokUtils;
public class GrokTest2 {
public static void main(String[] args) {
String pattern = "%{XINTEST}";
String message = "64.242.88.10 - - [07/Mar/2004:16:45:56 -0800] \"GET /twiki/bin/attach/Main/PostfixCommands HTTP/1.1\" 401 12846";
String json = GrokUtils.toJson(pattern, message);
System.out.println(json);
Map map = GrokUtils.toMap(pattern, message);
System.out.println(map.toString());
}
}
コード出力のjsonデータは以下の通りです.
{
"HOUR": "16",
"INT": "-0800",
"MINUTE": "45",
"MONTH": "Mar",
"MONTHDAY": "07",
"SECOND": "56",
"TIME": "16:45:56",
"XINTEST": "64.242.88.10 - - [07/Mar/2004:16:45:56 -0800] \"GET /twiki/bin/attach/Main/PostfixCommands HTTP/1.1\" 401 12846",
"YEAR": "2004",
"auth": "-",
"bytes": 12846,
"clientip": "64.242.88.10",
"httpversion": 1.1,
"ident": false,
"request": "/twiki/bin/attach/Main/PostfixCommands",
"response": 401,
"timestamp": "Mar 8, 2004 8:45:56 AM",
"verb": "GET"
}
ログに関連するデータは私たちのプログラムで解析されました!!実はその原理は私たちが正規表現をカスタマイズして、それから正規表現を通じて各行のデータをマッチングして、ユーザー定義のkey:valueデータに変換します!この機能があれば、私たちが解くことができるログはどんなに複雑で変化しても、その中のデータが一定の正規表現に従う限り式マッチングルールで、必要なデータに変換できます!