#はじめに
仕事中に少し困ったことがあったので何とかできないかなーと思い今回の記事を書きました。
背景
ある案件で調査依頼が来た際にアクセスログを追う機会がありました。
サーバーが複数あったのでアクセスログもそれだけ存在していました。。。。
その時は急ぎだったので複数のファイルからログを取り出して手作業で時系列順に並べて調査をしました。
もう二度とやりたくないので何とか楽にします。
かといって、大掛かりなことはやりたくなく、手軽に何とかできそうにないかなーと探してたところVSCodeの拡張機能が簡単に自作できそうなのでこれで何とかしてみます。
#やりたいこと
ゴールを決めます
- 時系列がごちゃごちゃでも順番に並べる
- 少しでもログを見やすく
- プライベートでパッケージ化
この辺をとりあえず実現させてみます
ちなみにtypescriptではなく、javascriptで作ります
#実際に作る
ログのフォーマット
123.456.789.10 test.com - [23/Jun/2019:17:17:24 +0900] 0 "GET /info/wp-content/themes/demo/js/scroll.js HTTP/1.1" 200 570 "https://test.com/info/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" -
これが基本のフォーマットです
また、日付がある行をソート対象とし、日付がない行は無視します
1. 時系列がごちゃごちゃでも順番に並べる
1-1 とりあえず、サンプル
公式ドキュメント
上の通りやってとりあえずサンプルを動かします
1-2 エディタ上のテキスト取得
// editor 取得
let editor = vscode.window.activeTextEditor;
let doc = editor.document;
// 全文を対象とする
let startPos = new vscode.Position(0, 0)
let endPos = new vscode.Position(doc.lineCount - 1, 5000)
let selection = new vscode.Selection(startPos, endPos);
// 全文取得
let allDoc = doc.getText();
// 改行をもとに配列化
let docs = allDoc.split('\n');
開いてるエディタのテキストをすべて取得します
取得したら行ごとに配列で管理します
1-3 日付を取得し、ソート用に整える
let obj = [];
let count = 0;
docs.forEach(function (value) {
// value から日付を取得(正規表現とか)
let date = getDate(value);
// 日付がなければ、ソート対象外とする
if (date === '') return false
// 日付とvalueを用いて新しく配列を作成
let tmpObj = {};
tmpObj['date'] = date;
tmpObj['value'] = value;
tmpObj['line'] = count;
++count;
obj.push(tmpObj);
});
今回は日付をもとに昇順でソートします
ソート用に新しい配列を作成する
function getDate(value) {
// 日付を取得
let date = value.match(/\[.+\]/);
// 日付として正しいか
let isValid = moment(date).isValid()
let m = {};
let retDate = ''
if (date && date[0].length > 0 && !isValid) {
m = moment(date[0], 'DD/MMM/YYYY:H:m:s Z');
retDate = m.format('YYYY/MM/DD H:m:s');
}
return retDate;
}
日付は、moment.jsを使って処理します
// 日付をもとに昇順ソートする
obj.sort(compare)
// 新しい順番で表示するテキストを作成
let newText = createText(obj)
editor.edit(edit => {
// ソート後で置き換え
edit.replace(selection, newText);
});
// 日付昇順ソート
function compare(a, b) {
let isBefore = moment(a.date).isBefore(b.date);
if (isBefore) {
return -1
} else if (a.date === b.date) {
return 0
}
return 1
}
// ソート後のテキスト作成
function createText(sortedObj) {
let retText = ''
sortedObj.forEach(obj => {
retText += obj.value + '\n'
});
return retText
}
日付の昇順でソートし、新しく表示するテキストを作成する
最後に、今のテキストと新しく作成されたテキストを置き換える
2. 少しでもログを見やすく
今回は、
- GET
- POST
この二つの文字列の色を変えて見やすくしてみようと思います
2-1 検索して色を変える範囲を返し、適用させる
// 色変え
// GET用設定
let decorator = vscode.window.createTextEditorDecorationType({
'color': 'red'
});
let rangeGet = getRange(obj, 'GET');
editor.setDecorations(decorator, rangeGet)
// POST用設定
let decorator2 = vscode.window.createTextEditorDecorationType({
'color': 'blue'
});
let rangePost = getRange(obj, 'POST')
editor.setDecorations(decorator2, rangePost)
// targetの箇所を検索し、Rangeを返す
function getRange(soutedObj, target) {
let retRange = [];
soutedObj.forEach(obj => {
let startPos = obj.value.indexOf(target)
if (startPos < 0) return false
let endPos = startPos + target.length
let range = new vscode.Range(obj.line, startPos, obj.line, endPos)
retRange.push(range);
});
return retRange
}
色を変えたいテキストを引数にRangeメソッドを用いて適用範囲を返す
setDecorationsで色を変える設定をし、GET を赤文字に、POST を青文字に変える
3. プライベートでパッケージ化
まあ、せっかくなのでパッケージ化します
npm install -g vsce
vsceがなければ、インストールします
vsce package
"publisher": "sakura"
package.jsonにpublisherを追加します
再度、vsce package コマンドを実行!
(んんんんん????)
This is the README for your extension "ms-plugin-sample". After writing up a brief description, we recommend including the following sections.
README.mdがデフォルトのままだとダメみたいなので上記を削除
再度、vsce package コマンドを実行!!!
パッケージ化完了!
VSCodeでvsixからインストールから、コマンドを実行して生成されたvsixファイルを選択すれば、使用可能になります
実行すると以下のように時系列でソートされ、GET, POSTの色が変わる
#まとめ
具体的な処理は、基本的なJavaScriptなので詳しい説明は省きました
今回は簡単なソートと装飾しかしていませんが、まだまだ不要な個所を削除したり、改良の余地はたくさんあるので色々追加していこうと思います