読者です 読者をやめる 読者になる 読者になる

Jenkinsでmavenコンパイル失敗時にログを取得してホニャホニャする方法

Rubyとかのスクリプト言語ではなく、Javaとかのコンパイルが必要な言語で困ったこと。

 

困った内容

Jenkinsでコンパイルを行っていて、コンパイル失敗の時に、失敗したファイルを特定して、そのファイルをコミットした人宛に向けてメールが飛ばせない!

 

前提条件

1. 「コミット頻度<コンパイル時間」となるような大きな(肥大化した)プロジェクト
→不等号が逆向きならば、コンパイル失敗=コミット者になるため、同じ状況になっても困らないはず
2. mavenコンパイル実施(antの人はごめんなさい)


解決する必要があること

今回困った内容を解決するには、以下の2つが必要なはず

  1. エラーとなったファイル名(Javaクラス)を抽出したい
  2. コンパイルが失敗した時だけ実行したい


エラーとなったファイル名を抽出したい

以前に、Consoleに表示した[ERROR]文面を抜き取る方法について記事を書きました。 

JenkinsでMavenのERRORのみを記載したメールを飛ばそう - ブロッコリーのブログ

 

ただ、今回はその文字列からさらにファイル名を抽出したい。
ということで、ログをファイル出力して、そのファイルの中身を別プログラムで操作する方法を考えました。

その際に「コマンド 2> ファイル名」とかの方法も考えましたが、そうするとmavenプロジェクトのビルドの恩恵が受けられなくなってしまう…。 

 

f:id:nihonbuson:20150301181027p:plain

 コマンドラインmavenオプションとかも入力する必要があるため、設定内容が分かりにくい)

 

 

f:id:nihonbuson:20150225232122p:plain

mavenプロジェクト

 

※実際は%WORKSPACE%とかの環境変数を使えばもっと短くできるし、コマンドをファイル化して、そのファイル自身もバージョン管理した方が良いのかもしれません。

 

mavenコンパイルのログをファイルに残したい

そんな時にはmavenオプション!

今回の場合は
-q -l <ファイルパス>

-q オプションは、「エラーログのみ出力」
-l <ファイルパス> は、「<ファイルパス>にログを出力」

ということで、これを使えば
「ログをファイル出力して、そのファイルの中身を別プログラムで操作する」
が達成できる!

 

コンパイルが失敗した時だけ実行したい

これは今回に限ったことではないですが、よく陥る問題。
Jenkinsは成功したJobに対して後ろに渡す仕組みになっています。
しかし、失敗時だけというのはなかなかできない。

そういう悩みを解決するのが
「Trigger parameterized build on other projects」プラグイン

これを使えば、失敗時のみ下流のJobを動かすことができます。

 

今回の解決方法

下の画像の通り。

 f:id:nihonbuson:20150225232216p:plain

ポイントは2つ。
1. -q -l オプションで得られたログファイルのパスを下流のJobへ
渡していること(赤囲み部分)
2. Trigger when build is をFailedにしていること(青囲み部分)

この2つのポイントを行えば、下流のJob(この画像では01_view_log_file)に
エラーログの入ったファイルを渡すことができます。

あとは、その下流Jobの中で、渡されたファイルの中身を解析すれば
やりたいことができるはず。

 

注意点

それぞれで環境変数の表記方法が異なります。

 

自分の場合はこんな感じ。

1. コンパイル実行
2. 失敗した場合は、そのエラーログを渡して別のJobへ
3. エラーログの中身を見て、以下の方法からエラー発生ファイルを抽出
3-1. "[ERROR] "で始まる行を検索
3-2. ".java"の文字列部分まで抽出
4. コミットログからエラー発生ファイルを最近コミットした人物を特定
5. その人物のメールアドレスにメールを飛ばす

 

まとめ

1. -q -l でエラーログを保存する
2. 「Trigger parameterized build on other projects」プラグイン
失敗時の操作を行う

 

さいごに

それにしても、この方法だと面倒っす。

誰かもっと良い方法あったら教えて下さい!