2013年03月07日

Java grepスタック - Grep4jで簡単ローカル/リモート・ログ管理

Java grepライブラリ・・・。これまで考えたことも無かったかもしれませんが、Grep4Jを使えばローカル、リモートに関わらずファイルの中身をgrepライクに操作・プログラミングすることが可能です。

text-x-generic

コード・デザインもメソッド・チェーン、ジェネリクスの多用など特徴的で面白いですよ。
 

Grep4jライブラリのダウンロードと設定


プロジェクト・ページはこちら。

ここからgrep4j-x.x.x.jarをダウンロード。

さらにgrep4jは次に示すライブラリにも外部依存しているので、こちらも最新版をダウロードします。


全てのライブラリをクラスパスに追加したら準備はおしまい。

grep4j01


Grep4jでローカル・ファイルを g/re/p


ローカルにあるログ・ファイルをgrepするコードがこちら。

 public void fromLocal() {
  Profile profile = ProfileBuilder.newBuilder().name("Ubuntu Laptop-1")
    .filePath("/var/log/syslog").onLocalhost().build();
GrepResults results = grep(constantExpression("error"), on(profile));
System.out.println("Total: " + results.totalLines());
for (GrepResult singleResult : results) { System.out.println(singleResult.getProfileName() + "(" + singleResult.getFileName() + "): " + singleResult.getText()); } }

grep4jではまず、対象ファイル毎にProfileオブジェクトを作成し、これとキーワードでgrepメソッドを呼び出します。
 
grep、onメソッドを見ると、あれ、何か別のクラスを継承してるのかな?、と思うかもしれません。実はこれらのメソッドをimport staticしておくことでシンプル(?)にコーディングできるよう工夫されているんです。

import static org.grep4j.core.Grep4j.grep;
import static org.grep4j.core.Grep4j.constantExpression;
import static org.grep4j.core.Grep4j.regularExpression;
import static org.grep4j.core.fluent.Dictionary.on;

GrepResultsオブジェクトには行単位ではなくgrep単位、つまり複数行がセットされることにも注意して下さい。

このコードを実行すると次のような結果になります。

Total: 1
Ubuntu Laptop-1(/var/log/syslog): Mar 6 21:35:35 sputnik pptp[x]: nm-pptp-service ... short read (-1): Input/output error

GrepResultsのフィルターも簡単。次のコードでは”DHCP”でgrepした結果を”eth0”をキーワードにしてフィルタリングしています。

 public void filterResult() {
  Profile profile = ProfileBuilder.newBuilder().name("Ubuntu Laptop-1")
    .filePath("/var/log/syslog").onLocalhost().build();
  GrepResults results = grep(constantExpression("DHCP"), on(profile));
  GrepResults filterResults = results.filterBy(regularExpression("eth0"));
  for (GrepResult singleResult : filterResults) {
   System.out.println(singleResult.getText());
  }
 }


Grep4Jでリモート・ファイルを g/re/p


Grep4JではSSHプロトコルを使ってリモートホスト上のファイルをgrepすることも可能です。

  String hostDHCPD = "172.16.0.10";

  Profile profile = ProfileBuilder.newBuilder()
    .name("dhcp-server-01 DHCPACK").filePath("/var/log/dhcpd.log")
    .onRemotehost(hostDHCPD).credentials("root", "your-password")
    .build();

  GrepResults results = grep(constantExpression("DHCPACK"), on(profile));

  // processing the single grep result for each profile
  for (GrepResult singleResult : results) {
   System.out.println(singleResult.getText());
  }

Profileの生成方法以外はローカルの場合と同じですね。


複数ホスト/ファイルのコンビネーション、grepオプションの利用


複数のホスト、ファイルを組み合わせる場合には、onメッソドにProfileオブジェクトの配列を渡します。

 public void fromCombo() {
  String hostDHCPD = "172.16.0.10";
  Profile proRemote = ProfileBuilder.newBuilder()
    .name("dhcp-server-01").filePath("/var/log/messages")
    .onRemotehost(hostDHCPD).credentials("root", "your password")
    .build();
  
  Profile proLocal = ProfileBuilder.newBuilder().name("Ubuntu Laptop-1")
    .filePath("/var/log/syslog").onLocalhost().build();
  
  GrepResults results = grep(constantExpression("error"), on(proLocal,proRemote));
  //GrepResults filteredResults.filterOnProfile(proRemote);
  
  for (GrepResult singleResult : results) {
   System.out.println(singleResult.getText());
  }
 }

filterOnProfile()メソッドを使えば、複数のターゲットを組み合わせたGrepResultsオブジェクトから特定のプロファイルだけを抜き出す事もできますよ。

最後にgrepオプション。grepスタックというならオプション実装も欲しい。Grep4jでは幾つかのgrepオプションを実装しています。

GrepOptions - grep4j - Java grep made easy - Google Project Hosting

オプションはwith()メッソドで指定し、例えば大文字・小文字を無視して”KERNEL”でgrepする場合は次のようなコードになります。

  GrepResults results = grep(constantExpression("KERNEL"),
    on(profile),
    with(ignoreCase())
    );


Grep4Jの使いどころ


一見すると、ログ・ベースのネットワーク機器監視、ログ集計・マイニングを行うアプリケーションなどでサウスバウンド側収集エンジンの部品として使えそうですよね。

以外(?)な使い方としてはGrep4J作者/marcocastさんのブログでメッセージ送信サービスにおけるSLA(サービス品質保証)計測・テストへの利用が提案されています。


それでは!


rsyslog 実践ログ管理入門
鶴長 鎮一
技術評論社
売り上げランキング: 43,284


Posted by netbuffalo at 20:30│Comments(0)TrackBack(0)Java | プログラミング


この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/netbuffalo/4395612

コメントする

名前
URL
 
  絵文字