blog/content/post/2010/11/13/2010-11-13-00001420.md

182 lines
15 KiB
Markdown

---
title: ログファイルへの出力
author: kazu634
date: 2010-11-13
url: /2010/11/13/_1620/
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:5379;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- gauche
- Lisp
---
<div class="section">
<p>
さくらVPSを借りて思うことは、「自分の手元にサーバーがないから何が起きているのか把握できない」ということ。だからログって大事なんだと気づかされた。
</p>
<p>
初歩的なことで申し訳ないが、運用系ミドルウェアの構築などが普段のお仕事なので、自分で作成したスクリプトなりなんなりが、どのように動くのかを把握したいというニーズにはあんまり大した意識を払ったことがなかったのですよ。えぇ。もちろん、ミドルウェアのログはいつも確認しているわけですが、自分がログを出力するという意識はなく、ログは出力されているものだと思っていたわけです。えぇ。
</p>
<p>
というわけで、ログファイルを出力するための関数を作成してみました。スクリプトファイルが存在するディレクトリ配下のlogディレクトリに、ログファイルを出力します:
</p>
<pre class="syntax-highlight">
#!/usr/bin/env gosh
<span class="synComment">;;; =========</span>
<span class="synComment">;;; Variables</span>
<span class="synComment">;;; =========</span>
<span class="synComment">;;; ログファイルの名前をここで指定するよ</span>
<span class="synSpecial">(</span>define <span class="synType">*logfile*</span> <span class="synConstant">&#34;test.log&#34;</span><span class="synSpecial">)</span>
<span class="synComment">;;; =========</span>
<span class="synComment">;;; Libraries</span>
<span class="synComment">;;; =========</span>
<span class="synSpecial">(</span>use srfi-19<span class="synSpecial">)</span>
<span class="synSpecial">(</span>use file.util<span class="synSpecial">)</span>
<span class="synComment">;;; =========</span>
<span class="synComment">;;; Functions</span>
<span class="synComment">;;; =========</span>
<span class="synComment">;;; ログに書き込むための日時文字列を生成</span>
<span class="synComment">;;; フォーマットは「[YYYY-MM-DD HH:MM:SS]」</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>date-string<span class="synSpecial">)</span>
<span class="synSpecial">(</span>date-&#62;string <span class="synSpecial">(</span>current-date<span class="synSpecial">)</span>
<span class="synConstant">&#34;[~1 ~3] &#34;</span><span class="synSpecial">))</span>
<span class="synComment">;;; ログ出力用関数を生成するための関数</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>logger-make filename<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>msg<span class="synSpecial">)</span>
<span class="synSpecial">(</span>call-with-output-file filename
<span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>port<span class="synSpecial">)</span>
<span class="synSpecial">(</span>display
<span class="synSpecial">(</span>string-append <span class="synSpecial">(</span>date-string<span class="synSpecial">)</span>
msg
<span class="synConstant">&#34;\n&#34;</span><span class="synSpecial">)</span>
port<span class="synSpecial">))</span>
<span class="synType">:if-exists</span> <span class="synType">:append</span><span class="synSpecial">)))</span>
<span class="synComment">;;; スクリプトが存在するディレクトリ配下に</span>
<span class="synComment">;;; logディレクトリが存在するかを確認する</span>
<span class="synComment">;;; 引数はスクリプトが存在するディレクトリ</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>is-log-directory-exists? script-directory<span class="synSpecial">)</span>
<span class="synSpecial">(</span>file-is-directory? <span class="synSpecial">(</span>string-append
script-directory
<span class="synConstant">&#34;/log/&#34;</span><span class="synSpecial">)))</span>
<span class="synComment">;;; ログファイルの名前を返す関数</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>logname script-directory<span class="synSpecial">)</span>
<span class="synSpecial">(</span>string-append script-directory
<span class="synConstant">&#34;/log/&#34;</span>
<span class="synType">*logfile*</span><span class="synSpecial">))</span>
<span class="synComment">;;; 引数としてスクリプトファイル名(つまり(car *argv*)です)</span>
<span class="synComment">;;; を受け取り、スクリプトファイルが存在するディレクトリを</span>
<span class="synComment">;;; 返す関数</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>script-directory script-name<span class="synSpecial">)</span>
<span class="synSpecial">(</span>receive <span class="synSpecial">(</span>path<span class="synStatement"> . rest</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>decompose-path script-name<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span>absolute-path? path<span class="synSpecial">)</span>
path
<span class="synSpecial">(</span>string-append <span class="synSpecial">(</span>current-directory<span class="synSpecial">)</span>
<span class="synConstant">&#34;/&#34;</span>
path<span class="synSpecial">))))</span>
<span class="synComment">;;; ====</span>
<span class="synComment">;;; Main</span>
<span class="synComment">;;; ====</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>main <span class="synType">*argv*</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">let*</span> <span class="synSpecial">((</span>filename <span class="synSpecial">(</span><span class="synStatement">car</span> <span class="synType">*argv*</span><span class="synSpecial">))</span>
<span class="synSpecial">(</span><span class="synStatement">directory</span> <span class="synSpecial">(</span>script-directory filename<span class="synSpecial">)))</span>
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span>is-log-directory-exists? <span class="synStatement">directory</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">((</span>logger <span class="synSpecial">(</span>logger-make <span class="synSpecial">(</span>logname <span class="synStatement">directory</span><span class="synSpecial">))))</span>
<span class="synSpecial">(</span>logger <span class="synConstant">&#34;test&#34;</span><span class="synSpecial">))</span>
<span class="synSpecial">(</span>display <span class="synConstant">&#34;Log directory does not exist.&#34;</span><span class="synSpecial">)))</span>
<span class="synConstant"></span><span class="synSpecial">)</span>
</pre>
<h4>
実行例
</h4>
<pre class="syntax-highlight">
kazu634@kazu634% cat <span class="synConstant">2010-11-01-225103</span>.scm ~/junk <span class="synStatement">[</span><span class="synConstant">3624</span><span class="synStatement">]</span>
<span class="synComment">#!/usr/bin/env gosh</span>
<span class="synStatement">;;;</span> <span class="synStatement">=========</span>
<span class="synStatement">;;;</span> Variables
<span class="synStatement">;;;</span> <span class="synStatement">=========</span>
<span class="synStatement">(</span>define *logfile* <span class="synStatement">&#34;</span><span class="synConstant">test.log</span><span class="synStatement">&#34;)</span>
<span class="synStatement">;;;</span> <span class="synStatement">=========</span>
<span class="synStatement">;;;</span> Libraries
<span class="synStatement">;;;</span> <span class="synStatement">=========</span>
<span class="synStatement">(</span>use srfi<span class="synConstant">-19</span><span class="synStatement">)</span>
<span class="synStatement">(</span>use file.util<span class="synStatement">)</span>
<span class="synStatement">;;;</span> <span class="synStatement">=========</span>
<span class="synStatement">;;;</span> Functions
<span class="synStatement">;;;</span> <span class="synStatement">=========</span>
<span class="synStatement">;;;</span> ログに書き込むための日時文字列を生成
<span class="synStatement">;;;</span> フォーマットは「<span class="synStatement">[</span>YYYY-MM-DD HH:MM:SS」
(define (date-string)
(date-<span class="synStatement">&#62;</span>string (current-date)
<span class="synStatement">&#34;</span><span class="synConstant">[~1 ~3] </span><span class="synStatement">&#34;</span>))
<span class="synStatement">;;;</span> ログ出力用関数を生成するための関数
(define (logger-make filename)
(lambda (msg)
(call-with-output-file filename
(lambda (port)
(display
(string-append (date-string)
msg
<span class="synStatement">&#34;</span><span class="synSpecial">\n</span><span class="synStatement">&#34;</span>)
port))
:if-exists :append)))
<span class="synStatement">;;;</span> スクリプトが存在するディレクトリ配下に
<span class="synStatement">;;;</span> logディレクトリが存在するかを確認する
<span class="synStatement">;;;</span> 引数はスクリプトが存在するディレクトリ
(define (is-log-directory-exists? script-directory)
(file-is-directory? (string-append
script-directory
<span class="synStatement">&#34;</span><span class="synConstant">/log/</span><span class="synStatement">&#34;</span>)))
<span class="synStatement">;;;</span> ログファイルの名前を返す関数
(define (logname script-directory)
(string-append script-directory
<span class="synStatement">&#34;</span><span class="synConstant">/log/</span><span class="synStatement">&#34;</span>
*logfile*))
<span class="synStatement">;;;</span> 引数としてスクリプトファイル名(つまり(car *argv*)です)
<span class="synStatement">;;;</span> を受け取り、スクリプトファイルが存在するディレクトリを
<span class="synStatement">;;;</span> 返す関数
(define (script-directory script-name)
(receive (path . rest)
(decompose-path script-name)
(if (absolute-path? path)
path
(string-append (current-directory)
<span class="synStatement">&#34;</span><span class="synConstant">/</span><span class="synStatement">&#34;</span>
path))))
<span class="synStatement">;;;</span> <span class="synStatement">====</span>
<span class="synStatement">;;;</span> Main
<span class="synStatement">;;;</span> <span class="synStatement">====</span>
(define (main *argv*)
(let* ((filename (car *argv*))
(directory (script-directory filename)))
(if (is-log-directory-exists? directory)
(let ((logger (logger-make (logname directory))))
(logger <span class="synStatement">&#34;</span><span class="synConstant">test</span><span class="synStatement">&#34;</span>))
(display <span class="synStatement">&#34;</span><span class="synConstant">Log directory does not exist.</span><span class="synStatement">&#34;</span>)))
<span class="synConstant"></span>)
kazu634@kazu634% gosh <span class="synConstant">2010-11-01-225103</span>.scm ~/junk <span class="synStatement">[</span><span class="synConstant">3625</span><span class="synStatement">]</span>
kazu634@kazu634% ll log/ ~/junk <span class="synStatement">[</span><span class="synConstant">3626</span><span class="synStatement">]</span>
total <span class="synConstant">8</span>
-rw<span class="synStatement">-r</span>-<span class="synStatement">-r</span>-- <span class="synConstant">1</span> kazu634 staff 172B <span class="synConstant">11</span> <span class="synConstant">13</span> <span class="synConstant">22</span>:<span class="synConstant">52</span> <span class="synStatement">test</span>.log
kazu634@kazu634% cat log/<span class="synStatement">test</span>.log ~/junk <span class="synStatement">[</span><span class="synConstant">3627</span><span class="synStatement">]</span>
<span class="synStatement">test</span>
<span class="synStatement">test</span>
<span class="synStatement">[</span><span class="synConstant">2010-11-13</span> <span class="synConstant">15</span>:<span class="synConstant">30</span>:<span class="synConstant">38</span><span class="synStatement">]</span> <span class="synStatement">test</span>
<span class="synStatement">[</span><span class="synConstant">2010-11-13</span> <span class="synConstant">15</span>:<span class="synConstant">31</span>:<span class="synConstant">05</span><span class="synStatement">]</span> <span class="synStatement">test</span>
<span class="synStatement">[</span><span class="synConstant">2010-11-13</span> <span class="synConstant">22</span>:<span class="synConstant">28</span>:<span class="synConstant">17</span><span class="synStatement">]</span> <span class="synStatement">test</span>
<span class="synStatement">[</span><span class="synConstant">2010-11-13</span> <span class="synConstant">22</span>:<span class="synConstant">28</span>:<span class="synConstant">31</span><span class="synStatement">]</span> <span class="synStatement">test</span>
<span class="synStatement">[</span><span class="synConstant">2010-11-13</span> <span class="synConstant">22</span>:<span class="synConstant">49</span>:<span class="synConstant">29</span><span class="synStatement">]</span> <span class="synStatement">test</span>
<span class="synStatement">[</span><span class="synConstant">2010-11-13</span> <span class="synConstant">22</span>:<span class="synConstant">52</span>:<span class="synConstant">38</span><span class="synStatement">]</span> <span class="synStatement">test</span>
kazu634@kazu634% date ~/junk <span class="synStatement">[</span><span class="synConstant">3628</span><span class="synStatement">]</span>
<span class="synConstant">2010</span><span class="synConstant">11</span><span class="synConstant">13</span>日 土曜日 <span class="synConstant">22</span><span class="synConstant">52</span><span class="synConstant">50</span>秒 JST
</pre>
<p>
うまく動いているようです。gaucheでログを書き込むときって、皆さんどうしているんですかね。自分で作るんでしょうね。たぶん。
</p>
</div>