A Day In The Boy's Life -39ページ目

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

404(Not Found)や500(Internal Server Error)などページが無かったり内部エラーが発生した場合や、処理の過程で発生した例外エラーなど、何か問題があったときに表示するエラーページをカスタマイズしたいという要件はよくあります。


CakePHPでは、そういったカスタムエラーページを所定の手続きにそって行えば簡単に作ることができます。



404や500エラーが発生したページのカスタマイズ


CakePHPではデフォルトでHTTPステータスコードが404や500が発生した場合に出力するテンプレートを持っています。


/path/to/cakephp/app/View/Errors

この中にあるerror400.ctpがHTTPステータスコード404が発生した場合のエラーページ、error500.ctpが500用のエラーページです。

これを好きにカスタマイズすることでオリジナルのエラーページを作ることができます。


エラーページもLayoutの影響を受けるため、エラーページ独自でのレイアウトを適用したい場合は、上記のエラーページ内で


<?php $this->layout = "error"; ?>

として、独自のLayoutを準備して適用するか、または


<?php $this->layout = FALSE; ?>

のようにして、レイアウトを適用しないようにしておきましょう。


また、エラーページは開発環境(設定ファイル(Config/core.php)でdebugを1以上に設定)の場合、これ以外に細かなエラー画面が用意されています。

例えば、存在しないコントローラーにアクセスした場合にMissing Controllerという例外が発生するのですが、その例外エラー用に下記のようなエラーページが用意されています。


A Day In The Boy&#39;s Life-cakephp-missing_controller


これをカスタマイズしたい場合、メッセージにあるようにErrorsディレクトリ内に独自のmissing_controller.ctpを用意しておきます。


ただし、本番環境(debugを0に設定)の場合は、これらの例外エラーは全てerror400.ctpまたはerror500.ctpにまとめられます

ですので、開発環境で細かくエラー内容をトレースしたいという場合は個別にエラー画面を用意しておけばよいですが、本番環境の場合はこの2つのエラーページを準備しておくだけでよいわけです。



例外をコントロールする


このようにエラーページはCakePHPの内部で例外が発生したときに呼び出されるわけですが、その例外はCakePHP任せでなく、独自にコントロールすることも可能です。


if (!empty($fuga)) {
// 通常の処理
} else {
// 404用の例外処理を投げる
    throw new NotFoundException();
}

上記のように必要なパラメータが無ければ404用の例外を投げ、それを受けてerror400.ctpが呼び出されて出力させるということができます。

500エラーの例外を投げたければ


throw new InternalErrorException();

と書けば例外を受けてerror500.ctpが呼び出されます。


最後に、独自の例外処理を作る方法ですが、例えば変数が見つからなかった場合に呼び出すMissingVarExceptionという例外を作ってみます。

例外クラスは、CakeExceptionのサブクラスとして以下のような内容のものを用意します。


<?php
class MissingVarException extends CakeException {
    protected $_messageTemplate = '%s が見つかりません。';
}

これを、app/Libディレクトリ以下にMissingVarException.phpとして保存します。

後は、Controller側でこの例外クラスをロードするのと、利用する処理のところで適宜呼び出します。


<?php
App::uses('MissingVarException', 'Lib');

class FugaController extends AppController {
    public function index() {
        if (!empty($fuga)) {
// 通常の処理
        } else {
            throw new MissingVarException(array('var' => 'fugafuga'));
        }
    }
}

実際に例外を発生させて見るとログファイルには


2013-07-28 01:55:15 Error: [MissingVarException] fugafuga が見つかりません。

のようなエラーメッセージが出力されます。


例外のコントロール方法の詳細は、マニュアル の方も参照してみてください。





情報システム部門またはそれに類する部門というのはどこの企業にも存在するかと思いますが、その存在意義については各所で危機感を煽る記事が掲載されています。

旧態依然のままの情報システム部門というのは、これまでの社内で募った不満もあいまってクラウドなど変化が早い外部サービスなどに取って変わられるのではないかという懸念です。

ただ、変わらない存在というものが企業内に存在するというのは、サービスの運営面ではよい場合というのもあるのではないかと感じることがあります。



抜け殻となったサービスとその衰退


私は、社内で多くのシステム開発を担当してきましたが、最初は意気揚々と要件を売り込んでくる担当者の熱にほだされ大々的にサービスインしたシステムが、その担当者がいなくなった途端に一気に衰退するという様を何度も見てきました。

運営という立場をしっかり担う人がいなくなっては、如何に軌道にのりまくっているサービスであっても辿る道は下降線でしかありません


軌道に乗ったんだから誰にでも運営できるだろうと考える人が多く、その担当者の能力も買われたりして引き剥がされると、その人の力によって維持していた揚力が失われて失速することになります。

立案した人はある程度、そのサービスに対しての熱意を持っているので維持するように努めますが、引き継いだ人は海のものとも山のものともわからないそのサービスに対してそこまで思い入れがありません。

適当に仕事をしているわけではありませんし、そのサービスの品質を落としている意識もないわけですが、徐々にそのサービスは下降の一途を辿るのはよく見てきた光景です。


これは担当者だけの問題でもなく、その運営を担うチームであったり組織であったりもするわけで、どちらかというと会社の中ではこの問題の方が大きかったりします。

というのも、組織は毎年のようにその役割によって変化していくわけで、その度にサービスを維持していた運営チームは解体の危機にさらされます

こういった企業としての変化の波に比較的影響を受けにくいのが人事であったり総務であったり広報であったり、そして情報システム部門であったりもします。

中の人は変わるにしろ、役割というのは維持されるわけです。


こういったことを逆手に取られてか、運用を維持できないサービス部門のお荷物が情報システム部門にまわされるというのはよくあることではありますが・・・。



変化に取り残されるシステム


サービス部門は、その企業としての方向性など経営指示によって体制がどんどん変化していきます。

その変化に伴って生み出される課題を解決するための仕組みづくりを情報システム部門として協力するわけですが、その変化のために取り残されていくシステムというのが多々あります


先ほど書いたように、それを運営する組織がなくなることで衰退し、また数年後に同じ課題を解決するための仕組みづくりのPJが立ち上がるという具合に。

まぁ、良いか悪いかはおいといてそういったスクラップ&ビルドを繰り返すのに割り切ってしまっているところもあるので、課題は次に持ち越すとしてその場を解決できればいいやというのもありなのかもしれませんが、やはり全体最適化を目指したいという情報システム部門の立場から見るとコストがかかるやり方であったり、数年後とに同じ要件をヒアリングして「その課題前にも聞いたんだけどな」とか「また業務改革とかいってるよ」とか「えー何度目のSFAなんでしょうか?」とかいう心の声を押し殺して対応していっているわけです。


確かに現場手動で、現在巷に溢れるクラウドなど外部サービスを使えば、手軽に課題解決をするソリューションは見つかりそうです。

しかし、それを運営する組織がなくなり維持できなくなった場合に屍となって累々と積み重なるサービスを見て果たしてそれでよかったのか?という疑問も出てきます。

一時の課題の解決にはなったでしょうが、組織は変われどそこに人とその課題は残ったままでしょう。
結局、解決した課題が新しい組織の元で新しい課題として作り直す作業を何度となく繰り返す必要がでてきます。



サービスを動かすも止めるも人の力


ということで、何も情報システム部門が変わらないことが正義というわけではなく、その役割を担い続けることができる組織があるというのは結構重要で貴重なんだな、といいたかっただけです。


こういった視点はエンドユーザーとなるその他の組織の人間にはなかなか見えない観点ではあります。

自分たちが困っているからどうにかしたいという思いはあり、それを解決する方法も知っているんだけど、それって部分最適になりがちで作っては捨てての繰り返しになるという課題を組織として変わらない情報システム部門がうまくサポートしてあげれば全体最適化されてよい方向にむけることができるのではないかということです。


きっと、その課題の渦中にいる人たちも「なんであのシステムが終わるんだろう」とか「なんでもっと改善できないんだろうか?」というような疑問や苛立ちはたくさん持っているのでしょう。

ただ、やはり重要なのはそれを支える中の人の存在で、その人がいない・いなくなったではサービスを支え続けるのは難しいことになります。

こういった人は、特にシステムに詳しいという人が必要なのではなく、どっちかというとその業務を支える役割にある人を巻き込んだ方が活気が出ます

営業管理部門や営業支援部門などその業務を支える役割の部門とかもあったりしますから、そういった人たちが現場での課題を取りまとめてこういった対策を取りたい、そしてそれを維持するための運用というのも自分たちが見るのはかまわないという意気込みがないと長続きはしません。


当然、サービスというのはその時のニーズに沿って変化していくべきでしょうし、社内の状況も刻一刻と変わっていくわけですから、情報システム部門もそれに応える柔軟な体制とサービス維持が必要でしょう。

結局はサービスとはいえ、それを支えるのは人であり、それを良くするにも悪くするにも、それを運営する人の想いであったり、熱意であるということは事実だと思います。




前回「Apache Solrのデモ環境を作ってみる 」にてApache Solrへのデータの取り込みをしてみましたが、Apache Solrはマルチコアに対応しており、複数のデータベースを作ることが可能です。

例えば、本番用とテスト用のコアを作って別々に管理したり、検索対象のアイテムによってコアを分けて検索結果を別々にするということが可能になります。



Apache Solrにコアを追加する


コアの追加方法は管理サイトから簡単に可能そうなのですが、この機能だけではどうもうまく動作してくれません。

下図のように「Core Admin」メニューの「Add Core」から追加しようとすると


Error CREATEing SolrCore 'new_core': Unable to create core: new_core

とエラーがでて作成できません。


A Day In The Boy&#39;s Life-ApacheSolrのコアの追加


そもそもの仕様ではありそうなのですが、一部の操作をサーバー上で手動で行う必要があります。

まず、Solrのコア用のディレクトリに移動し、既存でうまく動作しているコアディレクトリをコピーします。


$ cd /path/to/solr/example/solr/
$ cp -r collection1 new_core/

次に、追加したコアディレクトリ(new_core)の設定ファイル(conf/schema.xml)や辞書ファイル(conf/lang/userdict_ja.txtやconf/synonyms.txtなど)を編集します(これはコアの動作確認が取れた後でも問題ありませんが)


次に、コピーしたコアディレクトリにデータが入っている場合は、データをクリアしておきます。

Apache Solrのデータの削除(クリア)方法は、dataディレクトリの中身を削除するだけです。


$ cd /path/to/solr/example/solr/new_core/data
$ rm -rf ./*

これで再度Apache Solr管理画面から「Add Core」でコアを追加すればうまく登録できます。

登録後は、Apache Solrを再起動させます。


実は、ここまでやったらApache Solr管理サイトを使わずとも全て手動で作業もできたりもします。

コアディレクトリをコピーした後(データファイルの削除後でもいいですが)、solr.xmlを編集して新しいコアの情報を追加することでもコアの登録が行えます。


# cd /path/to/solr/example/solr
# vi solr.xml

以下のように新しいコアの情報(new_coreの箇所)を追加します。


<?xml version="1.0" encoding="UTF-8" ?>
<solr persistent="true">
  <cores defaultCoreName="collection1" adminPath="/admin/cores" zkClientTimeout="${zkClientTimeout:15000}" hostPort="8983" hostContext="solr">
    <core schema="schema.xml" loadOnStartup="true" instanceDir="collection1/" transient="false" name="collection1" config="solrconfig.xml" dataDir="data"/>
    <core schema="schema.xml" loadOnStartup="true" instanceDir="new_core/" transient="false" name="new_core" config="solrconfig.xml" dataDir="data"/>
  </cores>
</solr>

solr.xmlファイルの編集後にApache Solrを再起動させCore Adminメニューを見てみると新しいコアが追加されているはずです。



Apache Solrのコアを削除する


コアの追加をするんだったら、コアの削除方法も覚えておかなくてはなりません。

コアの削除は、追加手順を逆順で実施するだけで問題ありません。


まず、管理サイト上のCore Adminメニューから該当のコア名を選択し、Unloadボタンをクリックします。
そのまま「OK」ボタンをクリックすると該当のコア情報が削除されます。

ただし、これもsolr.xmlファイルからこのコアの情報が削られるだけなのでデータファイルなどのコアディレクトリは残ったままです。

あとは、サーバー上でコアディレクトリを削除します。


$ cd /path/to/solr/example/solr/
$ rm -rf ./new_core

順番を間違えて先にコアディレクトリを削除してしまうと、下記のように管理サイト上でエラーが出てしまいます。


new_core: org.apache.solr.common.SolrException:org.apache.solr.common.SolrException: Could not load config for solrconfig.xml

この回避方法は、solr.xmlファイル上に残っている該当のコア情報を手動で削除するか、または再度追加してSolrに正しく認識させることです。

あとは、手順を正しくリトライしましょう。