<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>PatentBureau Lab.</title>
	<atom:link href="http://labo.patentbureau.co.jp/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://labo.patentbureau.co.jp/blog</link>
	<description>株式会社 パテントビューロが運営するエンジニアによる、エンジニアの為のエンジニアブログ</description>
	<pubDate>Tue, 15 Nov 2011 10:20:43 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>lift 1.0系で作成したプロジェクトを lift2.3へ更新する際の留意点</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=470</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=470#comments</comments>
		<pubDate>Tue, 15 Nov 2011 10:14:47 +0000</pubDate>
		<dc:creator>h-mizuhara</dc:creator>
		
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=470</guid>
		<description><![CDATA[弊社が提供しているWEBサービスの中で、
lift 1.0.3 で構築・運用していたプロジェクトを、lift 2.3 にアップデートしました。
その中で、留意すべき点がありましたので紹介します。
※lift 1.0系全般に適用可能な情報だと思います。

　
lift 1.0系 と lift 2.3 系では、内部で使用されるcookieクラスが異なっています。
S.addCookie(cookie) メソッド等で扱われるcookieの型が
lift 1.0系では、
javax.servlet.http.Cookie.HttpCookie 
となっていました。
これが、lift 2.3では
net.liftweb.http.provider.HTTPCookie
に変更されています。
２つのclassにインタフェース上の差異はありませんが、
javax.servlet.http.Cookie.HttpCookie は mutable なのに対し、
net.liftweb.http.provider.HTTPCookie は immutableです。
この結果、たとえば、
cookie.setValue, cookie.setDomain, cookie.setPath 等のメソッドにて
javax.servlet.http.Cookie.HttpCookie では、左辺のオブジェクトが変更されますが、
net.liftweb.http.provider.HTTPCookie では変更後のオブジェクトは戻り値として返されます。
したがって、たとえばlift1.0系向けに書かれた以下のようなコードは
cookie.setValue(&#8221;value&#8221;)
lift 2.3系では以下のように書き換える必要があります。
cookie = cookie.setValue(&#8221;value&#8221;)
この変更を忘れると、コンパイルは通り、起動もしますが、cookie の値が更新されないという問題が発生します。
]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=470</wfw:commentRss>
		</item>
		<item>
		<title>QCon Tokyo 2010 にて講演を行ないました。Scala＋Liftによる超実用開発</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=329</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=329#comments</comments>
		<pubDate>Fri, 23 Apr 2010 08:39:39 +0000</pubDate>
		<dc:creator>t-miki</dc:creator>
		
		<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=329</guid>
		<description><![CDATA[本日、
■Scala＋Liftによる超実用開発 ■ と題して、
InfoQ主催のテクニカルカンファレンス、QCon Tokyo 2010にてScala＋Liftの講演を行なってきました。
「Scala（＋Lift）は、実務で使えるの言語（＋フレームワーク）だ！」という事を伝えたかったのですが、
いかがでしたでしょうか？
この講演をきっかけに、1社でもScalaを業務で使うようになって頂ければと思っております。
以下、講演の大まかな内容と、講演資料です。
皆様のご参考になれば、と思います。
■講演資料
10-04-20-qcon-tokyo-2010

■講演の大まかな流れ

世界Scala化の流れ（世界中でのScala採用事例の紹介

採用事例紹介
採用動機紹介


パテントビューロがScalaを採用するに至った経緯

当時の状況説明
採用動機紹介


パテントビューロでの採用事例

JavaをScalaにリプレース
Scalaで転職サイトを新規作成
その他、活用事例


Lift概要
Liftの便利機能紹介

View First
Liftのテンプレート紹介
Ajax対応


Scala（＋Lift）を実務で使ってみた感想
Scala（＋Lift）に関する不安を解消

不具合
開発環境
教育コスト


Liftと一緒に歩むScala中級者への道
開発者とデザイナによる、Scala（＋Lift）に関するインタビュー

中国、千葉、大阪、静岡の各県代表者より


おまけ（JavaとScalaコードの比較）

]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=329</wfw:commentRss>
		</item>
		<item>
		<title>Scala 2.8 - 改善された対話型コマンドインターフェイス</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=291</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=291#comments</comments>
		<pubDate>Tue, 20 Apr 2010 01:16:34 +0000</pubDate>
		<dc:creator>y-ishii</dc:creator>
		
		<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=291</guid>
		<description><![CDATA[Scala 2.8では対話型コマンドインターフェイス(REPL)がかなりいい感じになっています。
タブでコード補完
REPL上で下記のように入力してから
scala&#62; &#8220;a&#8221;.
タブを入力すると、Stringメソッドが持つメソッドが一覧でみられます。
また、下記のようにメソッドが一意に決められる場合は
scala&#62; &#8220;a&#8221;.to
一覧ではなく、メソッドがそのまま補完されます。
scala&#62;&#8221;a&#8221;.toString
上記はStringリテラルに対してコード補完を行っていますが、他にもコード補完ができるものがあるので確認していきます。
インスタンスのメソッド、フィールド
scala&#62;class Person(val firstName:String, val lastName:String) { def fullName = firstName + &#8221; &#8221; + lastName }
scala&#62;val person = new Person(&#8221;yoshinori&#8221;, &#8220;ishii&#8221;)
scala&#62;person.l
scala.person.lastName
→lastNameが保管される
scala&#62;person.f
→firstNameとfullNameが一覧で出る。
privateメソッドは補完されませんが、protectedメソッドは補完されます。
パッケージ
scala&#62;import scala.collection.
→scala.collectionパッケージ以下のパッケージ名とクラス名の一覧
型エイリアス
scala&#62;type StrList = List[String]
scala&#62;val strList:StrList = List(&#8221;a&#8221;,&#8221;b&#8221;,&#8221;c&#8221;)
scala&#62;strList.sor
→sort、sortBy、sortWith、sorted の一覧
シェル上のパス
カレントディレクトリに script.scalaというファイルがある場合
scala&#62;:load scr
以下のように保管されます。
scala&#62;:load ./script.scala
もちろん :load がなくても、普通のシェルと同じ様にパスが補完できます。
追加されたコマンド
scala&#62;:help
を実行すると、:cp、:history、:power、:sh、:silent というコマンドが追加されているのが確認できます。
:cp コマンド
クラスパスにJarまたはディレクトリを追加することができます。
scala&#62;:cp myFantasticProgram.jar
コード補完も効くのでこの機能はうれしいですね。
環境変数の展開とかをやってくれるかと思いましたができませんでした。。
:history コマンド
実行したコマンドの履歴が一覧で表示されます。
scala&#62;:history
&#8230;
498 :cp myFantasticProgram.jar
499 import jp.co.patentbureau.util._
500 :history
さらに履歴番号を入力することで、コマンドを再実行できます。
scala&#62;:history 499
:h? コマンド
実行したコマンド履歴を検索出来ます。
scala&#62;:h? List
161 val ls = List(&#8221;a&#8221;,&#8221;b&#8221;,&#8221;c&#8221;)
171 val l [...]]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=291</wfw:commentRss>
		</item>
		<item>
		<title>Scalaでデザインパターン 【Chain of Responsibility】</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=265</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=265#comments</comments>
		<pubDate>Sat, 17 Apr 2010 11:15:45 +0000</pubDate>
		<dc:creator>y-ishii</dc:creator>
		
		<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=265</guid>
		<description><![CDATA[Scalaでデザインパターンを再現するコーナー。
今回は 【Chain of Responsibility】パターンです。
Chain of Responsibility っぽいことを trait を利用して実装してみる
Scalaでデザインパターン（Chain of Responsibility)
上記のサイトなどでは、traitによる実装をしているので、PartialFunctionを使ってやってみました。
SingletonのLoggerを使っているのは新しくクラスを作るのが面倒だったからです。
元のChain of Responsibility の例に合わせるために、上記のような書き方をしましたが、PartialFunctionのリテラルをうまく使えば、もうちょっとクールな感じになる気がします。
]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=265</wfw:commentRss>
		</item>
		<item>
		<title>Maven Shell</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=221</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=221#comments</comments>
		<pubDate>Mon, 12 Apr 2010 14:02:48 +0000</pubDate>
		<dc:creator>y-ishii</dc:creator>
		
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=221</guid>
		<description><![CDATA[Sonatype が Maven Shell というツールをリリースしました。
Introduction to Maven Shell
Maven Shell とは Maven専用のシェル環境を提供して、より対話的にMavenを利用するためのツールです。Maven Shellを起動するとJVMとMavenがずっとロードされたままになるので、ビルド時間をいくらか短縮することができます。
Intro to Maven Shell
上記の記事によると、７秒かかっていたビルドが３秒ほどになるそうです。スクリプト言語に慣れている人などは4秒ほど速くなるというのはかなり大きな差だと感じるかもしれませんが、Scalaのコンパイル時間を考えると取るに足らない時間なので、その他の機能をみてみます。
インストール
こちらからmvnsh-assembly-0.10-runtime.zipをダウンロードしてきて、適当な場所で解凍し、binをパスに通します。パスを通したらターミナルでmvnsh とタイプするとMaven Shell が起動しプロンプトが表示されます。
mvnsh(/):~&#62;
MacBook Pro の環境では、コマンドを打つとエラーが表示されますが特に問題はないようです。
プロンプト上で exit とタイプするとMaven Shell を終了します。
mvnsh(/):~&#62; exit
コマンド
プロンプト上で help とタイプすると利用できるコマンド一覧が表示されます。(? とタイプしてもOK)
mvnsh(/):~&#62; help
また、
mvnsh(/):~&#62; help exit
のようにhelpコマンドの後ろにコマンド名を入れると、そのコマンドの詳細が見られます。
基本コマンド
Maven Shellでは一般的なシェルで利用できるコマンドが用意されていて、ある程度のことはMaven Shell上でできます。しかしシェルと全く同じ挙動というわけにはいかないようで、パイプやリダイレクトは使えないみたいですし、コマンドのオプションなども多少違うので注意が必要です。
alias　unalias 　cd 　ls　dir　pwd　echo　history 　hostname　mkdir　rm　rmdir　wget　recall　info
などは、特に説明は必要ないと思います。
sourceコマンド
一般的なシェルにもsourceコマンドがあり、シェルの設定を読み込むことができますが、Maven Shellでも同じことができます
alias ll &#8216;ls -la&#8217;
と書かれたファイルをsourceコマンドで読み込むことで、ファイルに書かれたaliasの設定を反映することができます。
bashは起動時に$HOME/.bashrc などを読み込みますが、Maven Shell は 起動時に$HOME/.m2/mvnsh.rc を読み込みます。
set、unsetコマンド
set、unsetコマンドでは、Maven Shell 内の変数と、システムプロパティを設定または無効にできます。mvnで-D をつけて指定するパラメタなどを指定します。
コマンドグループ
Maven Shell ではコマンドグループという機能があり、グループごとに実行できるコマンドがまとめられています。helpコマンドを実行すると、どのようなグループがあるかが確認できます。
logging      [...]]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=221</wfw:commentRss>
		</item>
		<item>
		<title>Mavenでコマンドラインから指定したjarをローカルレポジトリにダウンロードする方法</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=214</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=214#comments</comments>
		<pubDate>Mon, 28 Sep 2009 14:57:32 +0000</pubDate>
		<dc:creator>y-ishii</dc:creator>
		
		<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=214</guid>
		<description><![CDATA[maven-dependency-pluginのバージョン2.1からgetというゴールが追加されていてこのコマンドでgroupId、artifactId、version、レポジトリのURL(Centralにない場合)を指定してローカルレポジトリにjarファイルをダウンロードすることができます。
現状の最新であるmaven-2.2.1だとdependencyプラグインのデフォルトバージョンが2.0なので、バージョンを指定してあげる必要があります。以下は net.liftweb:lift-util:1.0.2をダウンロードする例です。

mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:get \
-DgroupId=net.liftweb \
-DartifactId=lift-util \
-Dversion=1.0.2 \
-DrepoUrl=http://scala-tools.org/repo-releases

若干冗長ですが、バージョンを指定しなくてよくなったら最初の部分は dependency:get で大丈夫です。
たまーに役にたつかも。
]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=214</wfw:commentRss>
		</item>
		<item>
		<title>LiftのStringHelpersを使う</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=192</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=192#comments</comments>
		<pubDate>Sat, 26 Sep 2009 11:27:26 +0000</pubDate>
		<dc:creator>y-ishii</dc:creator>
		
		<category><![CDATA[未分類]]></category>

		<category><![CDATA[Lift]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=192</guid>
		<description><![CDATA[といってもSuperStringというクラスしかないし、メソッドも少ないし、汎用的に使えるものもない。ただ暗黙的型変換初心者は感動する。
↑ Version 0.11-SNAPSHOTのソースを読んでました。。
以下Version 1.0.2での説明です。
StringHelpersを継承すると次の2つの暗黙型変換が行われます。
では、どんなメソッドが用意されているのか見てみます。
以上。
]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=192</wfw:commentRss>
		</item>
		<item>
		<title>Webアプリケーションのログレベルについて考える</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=162</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=162#comments</comments>
		<pubDate>Wed, 23 Sep 2009 18:57:28 +0000</pubDate>
		<dc:creator>y-ishii</dc:creator>
		
		<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=162</guid>
		<description><![CDATA[様々なログライブラリがあり、それらのAPIが割と統一されているにも関わらず、どのログレベルで出力するかは人によって差があるような気がします。そこで今回はWebアプリケーションのログレベルについて考えてみました。
まずJava開発の次のデファクトになると思われるSLF4Jのログレベルの説明を見てみます。

FATAL - アプリケーションを異常終了させるような非常に深刻なイベントを指定します。
ERROR - アプリケーションの稼働が継続できる程度のエラーを指定します。
WARN - 潜在的に害を及ぼすような状況を指定します。
INFO - アプリケーションの進捗の概要が分かるメッセージを指定します。
DEBUG - アプリケーションをデバッグすのに役立つ詳細なイベント情報を指定します。
TRACE - DEBUGより詳細なイベント情報を指定します。

訳が割と適当ですが、どのログライブラリも大体こんな感じじゃないでしょうか。ものによってはFATAL(最も重大)、TRACE(最も軽微)という説明だけのものもあります。対象となるアプリケーションの種類が広範囲なのでこういう説明になるのは仕方のないことですが、もう少し使い分けが分かる分類ができるのではないでしょうか。
まず、エラーに関するログレベルとそれ以外で分けてみます。

エラーに関するログレベル - FATAL、ERROR、WARN
それ以外 - INFO、DEBUG、TRACE

次に、トランザクションごと、WEBアプリケーションでいうとアクセスごとに出力させるログレベルとそれ以外に分けてみます。

アクセスごと - DEBUG、TRACE
それ以外 - FATAL、ERROR、WARN、INFO

何故アクセスごとに出力させるログレベルとそうでないログレベルを分けるのかというと、ログ出力にはそれなりにコストがかかるのでアプリケーションを本番環境へでデプロイした際はアクセスごとのログ出力をさせないためです。またアクセスごとにDEBUGレベル以上のログを出力していると、アプリケーションに問題が起こった際に本当に見たいFATAL〜WARNレベルのログが発見しづらいというのも理由のひとつです。
上記2つの分類から本番稼働時のWEBアプリケーションに最適なログレベルを考えてみると、アクセスごとのログ出力を抑えるためDEBUG、TRACEは外され、エラー以外のログを出力するためにINFOを入れることになるので、INFOが最適であると考えられます。
ここで本当にINFOレベルが最適なのかという疑問をもつ人もいるでしょう。例えば本番環境でのみ発生する問題に直面した時、少なくともDEBUGレベルのログは見たくなるのではないでしょうか。しかし、この例外的なケースを想定して本番環境にDEBUGレベルでデプロイするのはあまり良い判断とは言えません。アプリケーション実行時ににログレベルを切り替える機能を持たせておけば良いのです。いくつかのログライブラリにはJMXを利用してアプリケーションの再起動なしにログレベルを変更する機能を持っているものがあります。これに関してはまた別のエントリで書きたいと思います。
話が少しそれましたが、次にWEBアプリケーション開発においてどのようなログをどのログレベルに出力するべきかを具体的な例を挙げて見ていきます。
DEBUGとTRACE
上記に書いたように、アクセスごとのログを出力するのはDEBUGとTRACEですが、この２つの使い分けはどのようにすればいいのでしょうか。
この２つのログレベルを分ける基準は単純に出力するログの粒度でいいと思います。StrutsやLiftなどのフレームワークを使っているならば、ユーザからのリクエストをフレームワークが提供する構造のどの経路を通っているか分かる程度の粒度のログをDEBUGに、単なる変数のダンプログをTRACEにという具合です。質の良いフレームワークならばデフォルトでその経路をDEBUBレベルで出力してくれるので、フレームワーク使用者が自分で出力しなくてはいけない情報はあまりないと思います。Liftはまだ発展途上ということもあり、フレームワークが出力してくれるログが少ないので、RewriteRequestした際や、Snippetのメソッドがコールされたときなどに適宜ログを出力するようにすれば良いでしょう。
TRACEレベルのログについては、SLF4JのFAQに興味深い記述があります。
ここでは、何故SLF4Jのバージョン1.4.0にしかTRACEレベルのログが紹介されていないのか？という質問に対して、様々な議論があるもののいくつかの理由でTRACEレベルを推奨しないと解答しています。詳細は記事を読んでもらうとして、内容を意訳するならば、TRACEログに出力するあまりに詳細なログはその利点よりも欠点が上回るということです。私もその意見に同意しますし、FAQの解答にTRACEログを推奨しない理由を付け加えるならば、あまりにも多いログ出力の記述はコードの可読性を著しく下げることになるからです。またFAQの解答ではTRACEレベルのログ出力と同等のことはDEBUGレベルの設定を適宜することで代替できるとも書いてあります。
INFO
INFOレベルのログは本番環境下で唯一エラー以外のログを出力します。ここにはアクセスごとのログを記述するのではなく、アプリケーションの状態を表すようなログを出力します。具体的には、

アプリケーションのモード。アプリケーションによってはモードを切り替える事で、本番環境と開発環境など環境ごとの設定をしているものも少なくないと思うので、どのモードで起動されているかどうかを出力します。
現在のログレベル。ログレベルが実行時に変更されたときにも変更後のログレベルを出力します。
接続しているDBの情報。どのDBに接続しているかどうかをURLとして出力します。コネクションプーリングをしている場合などは、プールしているコネクション数なども適宜出力します。コネクションの生成、破棄のサイクルが速いのアプリケーションの場合は出力しない方がいいでしょう。
生存期間の長いキャッシュの生成情報。半日以上キャッシュされるようなデータが生成された際に出力します。ユーザごとにキャッシュされるようなデータは含みません。

などです。
考えれば他にもありそうなのですが、重要なのは大量のログが生成されそうな情報は出力しないというこです。また、これらの情報はJMXを使用することで、JConsoleから確認できるようにしたりすることができるので、もしそのような方法をとっているならば、出力しなければいけない情報はかなり少なくなると思います。
WARN、ERROR、FATAL
これらのログの使い分けは一般にエラーの深刻度を基準とするというような説明が多いですが、深刻度というのはかなりあいまいです。WEBアプリケーションに限るならばもう少し詳細な説明ができると思います。また、ERROR、WARNはアプリケーションの稼働が継続できるが、FATALエラーはアプリケーションの稼働が継続できないといった分類がされることがあります、WEBアプリケーションでいうならば、特定のユーザやユーザのリクエストに対するエラーに関することはERROR、WARNレベルで、FATALレベルにはすべてのユーザがエラーとなってしまう事象について出力すればいいのではないでしょうか。またWARNレベルに出力するログは実際にはエラーが起こっていないもの、つまり「潜在的にエラーを引き起こす」ようなものを出力します。この基準でERRORレベルとWARNレベルを使い分けます。
それではそれぞれのログレベルについて具体的にみていきます。
FATAL
FATALレベルにはユーザ全体に影響を与えるようなログを出力します。たとえばDB接続エラーなどのネットーワークに関するエラーや、ファイルの書き込みエラーなどのIOに関するエラーです。
しかし、すべてのネットワークエラーやIOエラーをFATALレベルにすればいいというわけではありません。ネットワークエラーは一時的なものである場合も多いからです。エラーが一時的である場合にはERRORレベルで出力するのが適当でしょう。
ERROR
ERRORレベルには簡単に言ってしまうと、FATALレベル以外のエラーをすべて出力します。前述した通り使い分ける基準はユーザ全体に影響を与えるかそうでないか、エラーが一時的なのか継続的なのかです。
ここで、エラーの出力をERRORとFATALに分ける事に疑問を持つ人もいるかもしれません。本番環境ではINFOレベルでログを出力するのでERRORとFATALを分けただけではログにERRORと出力されるかFATALと出力されるかだけの違いしかありません。頻繁にエラーを発生させるようなアプリケーションを本番環境にデプロイするとは考えにくいので、ERRORかFATALかは内容を見ればすぐに分かりそうです。
何故ERRORとFATALにログ出力を分けるのかというと、エラーの深刻度を明確にするためです。エラーがユーザ全体に影響を与えるかどうかと、エラーが一時的か継続的かという基準は、「深刻度」をより分かりやすくしたに過ぎません。実際の場面ではエラーの深刻度によってその対応がかわってくる事が多いと思います。エラーがFATALレベルのものであれば即座に対応しなくてはいけませんし、ERRORレベルのものであれば次の日に対応しても良い場合があります。
したがって、エラーが一時的であっても問題が深刻であるならば、FATALレベルで出力するといった場面もあると思います。
WARN
WARNレベルには「潜在的に害を及ぼすような状況を指定します」とありますが、この潜在的に害を及ぼすような状況とはどういうものでしょうか？
たとえば、あるメソッドの入力値として想定しないデータが来た場合にも適当な処理がなされるようにコードを書くことは多いと思います。処理は適切になされるのでエラーは発生しませんが、想定していないデータが入力値としてある時点で、アプリケーション内で整合性が取れていない箇所があるのかもしれません。そういった場合にWARNレベルのログとして出力しておけば、後でその問題をつきとめる事ができます。しかし、想定していないデータがくる事があらかじめ分かっている場合、たとえばそのデータがユーザからのリクエストに乗せられてくるようなデータの場合は、出力しない方が良いでしょう。
他にも具体的な例があるのかもしれませんが、これに関しては個々のアプリケーションによって様々なので一般的な例を挙げるは難しいです。しかし忘れてはいけないのは、あまりに大量のログを出力させるようなものは出力しないということです。というよりもWARNレベルのログを大量に出力しなければいけない場合があったとしても、それはアプリケーションのロジックに大きな問題があると考えられるので、まずそちらを対処した方が良いでしょう。
おわりに
これまで、それぞれのログレベルについて具体例を挙げながら説明してきましが、これらの基準が絶対的というわけではありません。しかし、ログレベルに関して詳細な考察がされているサイトもあまりないので、ログレベルを使い分ける際のたたき台になるものになればうれしいです。
]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=162</wfw:commentRss>
		</item>
		<item>
		<title>再帰関数に慣れる</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=141</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=141#comments</comments>
		<pubDate>Sun, 20 Sep 2009 18:37:49 +0000</pubDate>
		<dc:creator>y-ishii</dc:creator>
		
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=141</guid>
		<description><![CDATA[関数型言語っぽく書きたいなーと思ってると、最初は高階関数とかカリー化とかに目が行く。
名前がなんやら難しそうで、単純に説明だけ読んでも「だから何？」って感じなのだがLiftのAPIとか使ってるとわりとすぐに使いどころが分かってくる。
ただ再帰関数はなかなか使う機会がない、というか他のやり方でコーディングしてしまうのでそろそろ慣れようと思う。お題は「商標の発音表記をWEBで公開するために分かりやすい形に変換する」というもの。
簡単に書くと次のような文字列変換を行いたい。
パテントビ+ユーロ → パテントビューロ
左側が商標の発音表記で、右側のように分かりやすく表示したい。見れば分かるように「+」は次の文字が小文字であることを表している。
すぐに思いつく処理は正規表現で「+ユ」を抜き出して、「ュ」に置換する方法だが、今回は文字列をCharのリストに分解して一文字ずつ見ていく方法をとる。
まずはいつもやりそうな処理から
まぁ普通ですね。。次に再帰バージョン
まぁ普通ですね(^_^;
]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=141</wfw:commentRss>
		</item>
		<item>
		<title>LiftでSQLベースのクエリ</title>
		<link>http://labo.patentbureau.co.jp/blog/?p=119</link>
		<comments>http://labo.patentbureau.co.jp/blog/?p=119#comments</comments>
		<pubDate>Wed, 09 Sep 2009 14:38:37 +0000</pubDate>
		<dc:creator>y-ishii</dc:creator>
		
		<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://labo.patentbureau.co.jp/blog/?p=119</guid>
		<description><![CDATA[LiftでSQLベースのクエリをする際に使えるメソッドは

MetaMapper#findAllByInsecureSqlDb
MetaMapper#findMapByInsecureSql[T]
MetaMapper#findMapByInsecureSqlDb[T]

あたりで内部ではDB#useやDB#execやDB#runQueryなどを使っているみたい。
MetaMapper#findAllByPreparedStatementなんてのもあるがパラメタを渡せないようになっているので意味なし・・・・。この辺はなんか全体的にAPIが足りてない気がするが、InsequreSql系を押えとけばいろいろできる。
まず、findAllByInsecureSqlDbはこんな感じで使う(PersonっていうMapperがあった場合)
コネクションアイデンティファイアとSQLを指定して実行でき、戻り値はList[Person]になる。IHaveValidatedThisSQLは何のためにあるのかわからないが、セキュアなSQLであることを示すために名前と日付をいれる。
次にfindMapByInsecureSql
重要なのは、カリー化されている戻り値をPerson以外の型に変換できるところ。上記の例ではList[String]が返る。
findMapByInsecureSqlDb は findMapByInsecureSql にコネクションアイデンティファイアの指定ができるようになっているだけなので省略。ちなみにコネクションアイデンティファイアが指定されないと、Mapperに関連付けられているデフォルトのものが使われる。
メソッド名には規則性があって、メソッド名の最後がDbで終わっているとコネクションアイデンティファが指定でき、メソッドがカリー化されているものは、戻り値を他の型に変換できるようになっている。
上記でAPIが足りてないと書いたのはこの規則性で行くと当然あるべきメソッドがないから。
他にもプリペアドステイトメントが簡単に使えるDB#runQueryがある。
コネクションアイデンティファイアを指定するrunQueryDbがあっても良さそうなのにない。
戻り値は (List[String],List[List[String]] )でTupleの1つ目がカラム名のリストで（上記の場合はList(&#8221;firstName&#8221;, &#8220;lastName&#8221;)になる）、2つ目がクエリ結果のリスト。上記のクエリは20歳以上のIshiiさんをSelectしている。
]]></description>
		<wfw:commentRss>http://labo.patentbureau.co.jp/blog/?feed=rss2&amp;p=119</wfw:commentRss>
		</item>
	</channel>
</rss>

