はじめに
Jenkinsの管理コンソール、、、見づらくないですか?
ビルド履歴番号で成功とか言われても、それは誰がどのパラメータで実行したジョブ?ってなりますよね。
そこで、Jenkinsのビルド情報をwebスクレイピングで取得し、一覧表示したいと思います!
WebスクレイピングといえばPythonとBeautiful Soupの組み合わせが主流のようですが、
前回の記事同様に、Javascriptと基本的なライブラリのみを使用して解決できないか試した所、
なんとかなったので、メモを残したいと思います。
(webスクレイピングの注意事項 https://qiita.com/nezuq/items/c5e827e1827e7cb29011)
取得先とリクエスト頻度は計画的に、、、、
課題整理
まず、Jenkinsから情報を取得出来なければ話になりません。
そこで調査したところ、APIが用意されている事がわかりました。
使い方もシンプルで、httpリクエストメソッドオンリーで取得可能でした。
今回はジョブの実行結果を取得したいだけなので、getメソッドで対応します。
とりあえず実行
どのようなデータが取れるのか確認する為、
google chromeにて、自身が立てたjenkinsへ以下のリクエストを投げてみました。
http://localhost:9090/api/json?
※xml形式で取得したい場合は、jsonの部分をxmlにするだけで可能
{
"assignedLabels": [
{ }
],
"mode": "NORMAL",
"nodeDescription": "ノード",
"nodeName": "",
"numExecutors": 2,
"description": null,
"jobs":[
{
"name": "testJob",
"url": "http://<jenkins host>/job/testJob/",
"color": "blue"
},
{
"name": "hoge",
"url": "http://<jenkins host>/job/hoge/",
"color": "blue"
}
],
"overallLoad": { },
"primaryView":
{
"name": "All",
"url": "http://<jenkins host>/"
},
"quietingDown": false,
"slaveAgentPort": 0,
"unlabeledLoad": { },
"useCrumbs": false,
"useSecurity": false,
"views":[
{
"name": "All",
"url": "http://<jenkins host>/"
}
]
}
え?この程度の情報しか取得できないの、、、?
うーん、、、
情報収集、、
更に調査を進めた所、
クエリパラメータで情報量を操作できることがわかりました。
・depth
値を増やす事で、より深い階層情報を取得できるようになります。
例えば「1」と指定すると、job配下のdisplayName(ジョブ名称が入ってる)などが取得できるようになります。
あまり大きな値を入力すると、情報量が増えますが、それに比例して時間が、、、
・tree
指定する事で、取得する要素名でフィルタリングをかける事ができます。
depthを指定する際は情報量が増加するので、こちらも指定する事をお勧めします
ちなみにですが、同一要素名称が複数存在する場合、末に「s」をつける仕様のようです。
jobが複数ある→jobs
jobの中のdisplayNameを取りたい→jobs[displayName]
※カンマで区切ると複数指定が可能になります。
・xpath
指定した要素の内容でフィルタリングをかける事ができます。
色々ありましたが、自身の求める情報を取得する為のリクエストは以下になりました。
http://localhost:9090/api/xml?depth=2&tree=jobs[displayName,builds[number,result,actions[parameters[name,value]],timestamp]]&xpath=//job[displayName='testJob']
ただ、取得して分かったのですが、JenkinsのタイムスタンプってUNIXタイムスタンプなんですね、、
取得した値に以下の関数を通して、馴染みやすい形式(yyyy/MM/dd)に変換しちゃいましょう!
function convTimestamp(intTime) {
var date = new Date(intTime);
var year = date.getFullYear();
var month = ('0'+(date.getMonth()+1)).slice(-2);
var day = ('O'+date.getDate()).slice(-2);
var hour = ('0'+date.getHours()).slice(-2);
var min = ('O'+date.getMinutes()).slice(-2);
return(year + '/' + month + '/' day + ' ' + hour + ':' + min);
}
ちなみにですが、無効なリクエストを投げると、、、、
紳士的なイメージのjenkinsマスコットキャラ(名前不明)がメッチャ怒ります!
真面目なツールだと思っていたのですが、エンジニアの遊び心が伺えました!
やっぱり仕事は楽しくしたいですよね!
webスクレイピング一覧化
必要な情報の取得方法が確認できたので、ajaxによるwebスクレイピングを行い、
取得・加工して一覧表示用のhtni文字列を作成しましょう!
今回は、画像の読み込み等がない、そして、ビルド毎で一覧をしたかったので、以下のコードになりました。
// html読み込み完了後に呼び出すよう設定
$(document).ready(function(){
// 一覧表示
getList();
});
// 一覧表示
function getList(){
// 一覧取得
$.ajax({
type: "GET",
dataType: "xml",
url: "http://localhost:9090/api/xml?depth=2&tree=jobs[displayName,builds[number,result,actions[parameters[name,value]],timestamp]]&xpath=//job[displayNane='testJob']"
]).done(function (getData){
// build要素数分繰り返し処理を実施
$(getData).find("build").each(function(){
// 実行日時の変換・取得
convTimestamp(Number($(this).find("timestamp").text()));
// パラメータは深い階層に格納されているので、
// findを繰り返して取得する
$(this).find("action").each(function(){
$(this).find("parameter").each(function(){
if($.inArray($(this).find("name").text(), Unnecessary) == -1){
// naneとvalueの関係になっているので、以下のように取得し、
// 配列かhtml文字列作成用変数に格納していく
$(this).find("name").text(); //要素名
$(this).find("value").text(); //要素値
}
});
});
});
});
// html書き換え
// 挿入先のhtmlタグは、idを設定して記載しておく
$("#挿入先のid").html("先ほど作成したhtml文字列");
};
// 個人的にリフレッシュ処理を行いたくなったので
// 一定間隔で繰り返し処理を行う「setIntervalメソッド」を組み込み、
// そこからも呼び出すようにする
$(function(){
setInterval(function(){
getList();
}, 5000);
});
最後に
とりあえず、基本的なライブラリでもなんとかなる事がわかりました。
次は新しいツールも試してみたいと思います。