Linuxにはtailというファイルの末尾10行程度を表示する、
ログファイルのチェックなどに便利なコマンドがあります。
オプションで一定間隔で常に末尾10行の表示を
更新し続けることもでき、ログの監視などに使えます。

ただ、とっても便利でサーバー管理者御用達のこのコマンド、
当然ながらシェルでログインできなくては使えません。。
レンタルサーバーなどでシェル権限がない場合も多いですし、
何よりもっとカンタンにブラウザから見たい!と思いませんか?
業務上の都合もありとっても欲しくなってので、作っちゃいました。
jQueryとPHPを使えば、思った以上にサクッと作れてしまったので、
技術ブログでソースコードや解説も含めて公開します。
(jQuery、メチャクチャ便利!です)
jQuery + PHPでtailを作る!
まずは今回の完成品です。

シンプルですね。
「TAIL」ボタンを押すとtail実行、
「STOP」ボタンを押すと更新が止まります。
実際に実行するとこうなります。
※サンプルとしてこのプログラム自体をtailしました

Ajaxで実装されており、2秒ごとに表示が更新されます。
では、ソースコードです。
-
<?php
-
-
//対象のファイルパス
-
$logpath = 'logfile.log';
-
//表示する末尾の行数
-
$lines = 30;
-
//更新インターバル (ミリ秒)
-
$interval = 2000;
-
-
-
}
-
-
foreach (read_tail($logpath,$lines) as $i => $line){
-
if ($i <($lines - 1)){
-
echo '<br />';
-
}
-
}
-
-
exit;
-
}
-
-
/**
-
* ログをファイルから指定行数読み出す
-
*
-
* tail function by flash tekkie
-
* http://tekkie.flashbit.net/php/tail-functionality-in-php
-
*
-
* @param string $file ファイルパス
-
* @param int $lines 行数
-
* @return array 行ごとの配列
-
*/
-
function read_tail($file, $lines) {
-
//global $fsize;
-
$linecounter = $lines;
-
$pos = -2;
-
$beginning = false;
-
$text = array();
-
while ($linecounter> 0) {
-
$t = " ";
-
while ($t != "\n") {
-
$beginning = true;
-
break;
-
}
-
$pos --;
-
}
-
$linecounter --;
-
if ($beginning) {
-
}
-
if ($beginning) break;
-
}
-
}
-
?>
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
-
<head>
-
<meta name="robots" content="noindex,nofollow" />
-
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
-
<script type="text/javascript">
-
var timer = null;
-
function start_tail(){
-
if (timer){
-
clearInterval(timer);
-
}
-
$('#status').html('running...');
-
timer = setInterval(run,<?php echo $interval ?>);
-
}
-
-
function run(){
-
}
-
-
function stop(){
-
clearInterval(timer);
-
}
-
</script>
-
<style type="text/css">
-
#console {
-
width:800px;
-
height:500px;
-
overflow:scroll;
-
border:1px solid #999999;
-
font-size:12px;
-
font-family:consolas;
-
}
-
</style>
-
</head>
-
<body>
-
<input type="button" onclick="start_tail()" value="TAIL"> <input type="button" onclick="stop()" value="STOP"> <span id="status"></span><br />
-
<pre id="console"></pre>
-
</body>
-
</html>
これだけ!です。
外部ファイルも不要なので、このコードを
phptail.phpなどで保存して、実行すればokです。(文字コードはUTF-8で)
たった100行ぐらいでAjaxを使ったtailを実装できちゃうところが、
jQueryとPHPの素晴らしいところですね。
では、ソースコードの解説をしてみます。
PHPの処理を作る
今回のキモはなんといってもtail部分。
ファイルを末尾から読み出すのは結構難しいです。
こういった処理を自分で作ってもいいですが、
海外サイトに良さそうなコードがあったのでお借りしましょう。
「php tail」でGoogle検索すればすぐ見つかりました。
flash tekkie » Blog Archive » tail functionality in PHP
今回はここのread_file関数を使うことにします。
read_fileだと少々わかりにくいのでread_tailに変更しました。
-
function read_tail($file, $lines) {
-
//global $fsize;
-
$linecounter = $lines;
-
$pos = -2;
-
$beginning = false;
-
$text = array();
-
while ($linecounter> 0) {
-
$t = " ";
-
while ($t != "\n") {
-
$beginning = true;
-
break;
-
}
-
$pos --;
-
}
-
$linecounter --;
-
if ($beginning) {
-
}
-
if ($beginning) break;
-
}
-
}
この関数に読み出したいファイルパスを渡して、
それを一定秒数ごとに表示してやればokですね。
Ajaxで定期的に読み込む
Ajaxというと難しいイメージがありますが、
jQueryを使えばほんとにカンタンに実装できてしまいます。
今回は
「TAIL」ボタンにstart_tail()を、
「STOP」ボタンにstop()を、
onclick属性でそれぞれ割り当てました。
JavaScriptの関数コードは
-
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
-
<script type="text/javascript">
-
var timer = null;
-
function start_tail(){
-
if (timer){
-
clearInterval(timer);
-
}
-
$('#status').html('running...');
-
timer = setInterval(run,<?php echo $interval ?>);
-
}
-
-
function run(){
-
$('#console').load('?load=1&m=' + new Date().getTime());
-
}
-
-
function stop(){
-
clearInterval(timer);
-
$('#status').empty();
-
}
-
</script>
これだけです。
はじめにajax.googleapis.comからjQueryのライブラリを読み込みます。
これはGoogleが無償で提供しているGoogle AJAX Libraries APIというもので、
Googleがホストしてくれている様々なJavaScriptライブラリを
自由に使ってかまわないというものです。
http://code.google.com/intl/ja/apis/ajaxlibs/
これのおかげで、jquery.jsなどを別途用意する必要がありません。
(Googleに感謝!)
次に、start_tailを見てみると、
setIntervalでrunという関数を定期的に実行しています。
このrunという関数が実行される度に、Ajaxで先ほどの
PHPで作ったtailの処理が実行されます。
-
$('#console').load('?load=1&m=' + new Date().getTime());
ここが、Ajaxです。なんと1行!
これは、id="console"のタグの中身に対して、
'?load=1&m=タイムスタンプ' のURLの実行結果を読み込みます。
?より前が省略されているのは、自分自身(php)を実行するためです。
?でload=1というパラメータをつけることにより、
PHP側で、
-
-
}
-
-
foreach (read_tail($logpath,$lines) as $i => $line){
-
if ($i <($lines - 1)){
-
echo '<br />';
-
}
-
}
-
-
exit;
-
}
このように、Ajaxから呼ばれた場合のみに
tail処理を行わせてexitさせる ということをしています。
Ajax用に別のphpを用意してもいいのですが、
簡単な処理であれば自分自身を呼び出す方が
ソースコードもまとまり便利です。
"m=タイムスタンプ"の部分は、IEの場合
Ajaxで同じURLを連続して読み出した場合に
キャッシュされてしまうため、URLを毎回変化させています。
PHP側ではこのmの値は全く使用しません。
今回のtailではブラウザ互換の都合上、
タブはスペース4つに置換されるという仕様にしています。
(まあ、問題児はもちろんIEなんですが、、)
IE8,FireFox3.5,Chrome3 で動作確認しています。
問題がある場合はソースを修正してください。
PHPで作ることの意味、応用アイデア
以上でソースコードの説明は終わりです。
とても短いソースコードなので、業務の用途にあわせて
改変していただければなと思います。
今回はとてもシンプルにただ1つのファイルを監視するだけですが、
PHPを改造すればローテートされる複数のログファイルを横断したり、
正規表現で抜き出したり、自由自在にファイルを
監視するスクリプトを作れるのではないかと思います。
ただ注意しなければいけないのが、監視対象のファイルを
GET値などで指定できるようにすると、セキュリティ上
非常に危ないのでそういった改造をする場合は
注意するようにしてください。
このソースコードは自由に使用していただいて構いませんが、
各自の自己責任での使用をお願いします!
関連した記事:
■ 「日本でいちばん社員満足度が高い会社の非常識な働き方」


















ページの先頭に戻る
PHP側で実行できるjqueryライクなオープンソースの紹介 phpQuery
PHP側でJQueryのような書き方でHTMLを簡単に加工できます。
http://code.google.com/p/phpquery/
$doc = phpQuery::newDocumentHTML(“http://www.yahoo.co.jp/”);
$html = $doc['div'] -> html();
このような簡単な書き方でHTMLを操作できる。
jQueryで実行できる関数がPHP側で実現できます。
正規表現も使わないで簡単にHTMLを加工できる。
指定したサイトのある部分だけ(CSSクラスやIDだけで)簡単に取って来れそう
jQueyrリファレンス
http://semooh.jp/jquery/
ステキ。
いい記事でした
ありがとうございます!
とても分かりやすい記事ありがとうありがとうございます!
こんなのを探してました!