watermint.org - Takayuki Okazaki's note

Play 2.2/ScalaでLogbackの設定をLTSVにする

趣味のプログラムをPlay Framework 2.2とScalaで書いています。趣味のプログラムなので、ログを監視したりするような事はまず無いのですが、あとからプログラムで読みやすいようにLTSV (Labeled Tab-separated Values)形式で出力する事にしてみました。

ログの設定は、conf/application-logger.xmlというファイルを作っておけば読み込んで適用してくれます。いろいろ試行錯誤した結果次のような設定で落ち着きました。

<configuration>
    <conversionRule conversionWord="coloredLevel" converterClass="play.api.Logger$ColoredLevel" />
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${application.home}/logs/application.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${application.home}/logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>14</maxHistory>
        </rollingPolicy>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>time:%date{ISO8601}&#x9;level:%level&#x9;logger:%logger&#x9;thread:%thread&#x9;msg:%replace(%replace(%message){'\n','\\n'}){'\t',' '}&#x9;exception:%replace(%replace(%xException{5}){'\n','\\n'}){'\t',' '}%n%nopex</pattern>
            <immediateFlush>true</immediateFlush>
        </encoder>
    </appender>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%coloredLevel %logger{15} - %message%n%xException{5}</pattern>
        </encoder>
    </appender>
    <logger name="play" level="INFO" />
    <logger name="application" level="INFO" />
    <root level="ERROR">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

STDOUTへの出力はデフォルトのままとしています。ファイル${application.home}/logs/application.logへの書き込みのみLTSVとしています。

最初からログローテーションまでは設定しなくても良いのですが、ちょっと作ってみた。というレベルのプログラムでも意外と長期間動かしっぱなしになってしまった。という事もあるので、あらかじめ設定しておく事にしています。

ログに含める事ができる情報はLogbackのマニュアルによるとConversion Wordで定義されているものが使えるようです。呼び出しもとメソッド名や行番号もとれるようですが、動作速度が犠牲になるようなのでここでは有効にしませんでした。

Play framework側のプロパティでapplication.home以外に使えるものはないのか情報を探してみましたが、ソースを見たところ(Logger.scala) application.home以外は特に定義されていませんでした。

WordPressからTumblrへ移行した話

WordPressからtumblrへ、日記から文章へでも触れた通り、約7.8年さくらのレンタルサーバでWordPressを使ってブログを配信していました。今回はこの移行についての経験をもう少し詳細に記録しておこうと思います。

WordPressからTumblrへ移行した理由はいくつかあります。

パフォーマンス

表示速度が遅い。CloudFlareのようなCDNも利用していましたが、それでも読み込み開始から描画終了までは8〜11秒程度かかっていました。これはWordPressだけが原因ではなくWordPressのWidgetなど多数のプラグイン、複数のドメインから配信される画像、アフィリエイト・分析のためのビーコン、サーバがレンタル共有型ゆえのCPUリソース不足など複合的な原因がありましたので今回大幅に見直しをかけています。

今回、Tumblrから自動的に配信されるものをのぞき、アフィリエイトなども原則的には付与しない事にしました。ページレイアウトも可能な限りシンプルなものとして、読み込み速度と可読性の向上を目指しています。

結果的には現在のところ描画終了まで2〜3秒とかなりの高速化が実現できました。なお、利用していたCDNのCloudFlareについてはTumblr側との技術的な相性の問題で利用できないようで使用をあきらめ、Tumblrのみで配信をする事にしました。

振る舞いを見る限りだと、Tumblr側は定期的に、設定された該当のカスタムドメインのDNSを引いてみて、AレコードがTumblr (66.6.44.4)を向いているかどうかを確認しているようでした。ここで、確認が取れない場合は設定を無効化しているようです。無効化されると watermint.org にアクセスしても、Tumblrのエラーページが切なく表示されるだけになってしまします。

当初、さくらインターネット側の設定を66.6.44.4に設定しただけでした。イメージ的にはこの設定をして24〜72時間ぐらいすればインターネットに設定が反映されて、うまく行くとおもっていました。ところが72時間経っても変化が無く、あせっていろいろ設定を変えてみたところCloudFlareのDNS設定でAレコードを、Off CloudFlareとして66.6.44.4を向けてみたところほぼリアルタイムで8.8.8.8 (Google Public DNS)なども更新され無事、ドメイン設定切り替えが完了しました。

セキュリティー、メンテナンスの問題

セキュリティー上の問題。WordPressは普及しているブログエンジンですが、その内部構造がやや複雑で、かつ多数のプラグインを使って構成しているためにそれぞれのコンポーネントにおけるセキュリティー上の問題がありそうで心配でした。あまりWordPressのソース自体をみて何か対策をするという事はありませんでしたが、精神衛生上のコストというイメージでしたが負担がありました。

実際の作業は単にバージョンアップをするだけとはいえWordPress自身、プラグイン、テーマなど各コンポーネントは比較的バージョンアップサイクルが早いため、精神的な負担が高く感じていました。

TumblrはCMS含めてのホスティングになるので、運営をほぼTumblr (Yahoo!)に任せる事が出来ますからこの点では非常に負担が軽くなったと思っています。

Markdownのオーサリング

最近、仕事を始め個人的なメモ等もほとんどをMarkdown形式で書くようにしています。そうするとブログ記事等もすべてMarkdownで書きたくなるのですが、WordPressには操作性・互換性の良いオーサリングプラグインが見当たりませんでした。

WorldPressにMarkdown形式で記事投稿をするという点では、Byword 2はかなり有力な候補でした。理由としてはもともとBywordの頃から手元のドキュメント編集に使っており操作性にも慣れていることがあります。

しかし前述の通りパフォーマンスやセキュリティー/メンテナンスの問題などもありましたので、全体的な見直しをかけることで最終的な選択肢とはなりませんでした。

既存記事の移行

最終的に記事は移行しないと決めたのですが、検討した際の調べたところを紹介しておきます。

WordPressで運用してきた過去の記事は7.8年でおおよそ500本になっていました。手動で移行するのはかなり面倒な量でした。選択肢としては次の2つの方式を検討していました。

WordPressにはWordPress eXtended RSS (WXR)という形式で全記事をエクスポートする機能があります。これを、Tumblr API等を使ってTumblrへ移行するスクリプトを書く。Tumblr APIはすでにtumblifeをつかってRubyで連携プログラムを書いた事があったのでこれを使えば良いだろうというところまでは検討しました。WXR形式のデータをパースしてTumblrへ流し込む形式にするのがやや面倒だったので一度保留としました。

次に商用の移行サービスを検討しました。Import2というサービスがWordPressからTumblrへの移行をしてくれます。Import2は、WordPressとTumblr両方のID/Passwordを入れるとよしなに移行をしてくれるサービスで、サンプルとして10記事分を import2 demo というタグ付きで移行してくれます。WordPress側で画像を管理していた場合はさらにDropboxと連携するとDropbox側に画像を移行してURLなどもよしなに移行してくれるようです。 10記事分について移行してみたところ、おおむね問題なさそうに見えました。一つ問題があったのは日本語で書いた記事を編集しようとすると &#xxxxx; のようにユニコードでエスケープされた形式となってしまっており既存資産の移行という点ではやや難ありでした。サポートに問い合わせをすればなおったかもしれませんでしたが、結果的にはこの選択肢も保留としました。ちなみに、料金プランは500記事移行の場合、100記事〜1,000記事移行のPremiumプランとなりUSD 49でした。もう少し安かったら勢いで移行していたかもしれません。

記事を移行する/しないを判断する上で重要だったのはURLまでは移行できないことでした。Tumblrで各記事は「/post/記事ID/任意の文字列」のようなURL構造となるのでWordPressの既存URLをそのまま移行する事は出来ません。このような中途半端な移行かつ、過去の記事もすでに時代遅れとなっていることを勘案して最終的には記事移行をあきらめました。

Tumblrに移行してみて

読者の立場としてみると、読み込み速度がかなり改善したのでこれは良かったと思っています。記事を書く立場です。WordPressのHTMLエディタで時々思った通りに入力できなくて結局HTMLを直書きするということがありました。 このあたりがMarkdownで書けるようになったのでかなり安心して書けるようになったと思います。もちろん、Markdownもいろいろ書式を使い始めると表示崩れがおこりがちです。今回からなるべく文体もわかりにくくならない程度に表組などを少なめにして箇条書き中心に書いています。

写真整理のワークフロー

Aperture中心のワークフローからCapture Oneへ<

事の発端はAperture 3のアップデートが異様なまでにiPhoto側に仕様を寄せてきた事です。iCloudを使わせたいのはわかるけどUXまでiPhotoに寄せてくることには不安がありました。またこれに従い、Aperture自体の継続性ってどうなんだろうという疑問もありました。

Aperture 3.2ぐらいまでは安定して動いていましたが、3.3ぐらいから急にバグらしき挙動が増えて作業に支障がでるようになってくるようになりました。Appleのことだから、コアにするならプロ向けのApertureではなく全製品を取り巻く環境の中心に位置づけたいiPhotoにするでしょう。それでここで見切りを付けて脱Apertureとしようとしたのが今年の1月頃です。

その頃丁度いくつか製品を評価してCaptureOne 7が良いのではという気持ちになってきました。プレビューと最終イメージ(印刷 or RAW現像後のイメージ)が一致する、ヨーロピアンな色使い、パース調整などとにかく出力の気持ちよさにほれぼれしてこれを中核とすることに決めました。

CaptureOneは商業カメラに詳しい方ならご存知の通り、デンマークのPhaseOne社がつくる現像ソフトウエアです。PhaseOneといえば、中判デジタルバックなどをすぐ連想されるとおもいますが、まさに商用写真/印刷向けのソリューション群を扱う会社なのです。CaptureOneもまさにそのコンセプトに沿っており、CYMK印刷、テザー撮影(スタジオなどでPCで確認しながら撮影する)などに特化していました。

CaptureOneはversion 7より、おそらくハイアマチュア向けにかなりコンシューマ市場を意識した作りになっており、ApertureやLightroomでおなじみのカタログ形式(アプリが管理する配下にアプリ経由で写真をインポートし管理下におくような管理形式)の写真管理をサポート。

CaptureOneはもともとその機能名にもある通り、Sessionというテザーセッション向けのディレクトリベースのファイル管理をベースとしておりカタログ形式はまさにCaptureOne 7での新機能でした。

最初、2013年1月頃はCaptureOneを中核に据えるため、すべてをCaptureOneのカタログ形式にしようと既存の写真などをすべてカタログ配下に管理しようとしたのですがそこで問題が生じました。

CaptureOneのカタログは明らかにシングルスレッドでの動作をしており、また、カタログに収容する写真枚数に比例して動作が遅くなる(O(n)で実行時間が長くなる)ため、実用的な収容枚数は1,000枚程度で、10,000枚を超えるとまず、カタログを読み込んで起動するだけで起動の成功率が1/3ぐらいという悲惨な状況でした。

一眼レフでは月々1,000〜2,000枚程度撮影していますので毎月カタログを分けるようにしました。これで半年ほど運用してみましたが下記のような問題がありました。

Capture One 7の問題点

  • 写真の重複排除ができない。ApertureやLightroomを使っていれば当たり前の機能ですが、CaptureOneにはありません。SDカード/CFカードからの読み込み時に前回取り込みを消していなかったり、途中でCaptureOneがクラッシュするなど途中の状況がわからない場合でも手動ですべて解決せねばならずかなりつらい事がわかりました。
  • 頻繁にクラッシュする。使い方の問題ではあるのでしょうけど、CaptureOneは明らかにクラッシュし過ぎです。また、編集結果を即時にfsyncしないため、クラッシュするといくらか編集が巻き戻ってしまうという残念な状況に遭遇します。
  • RAW+JPEGや、ムービーに対する対応が貧弱。RAW+JPEGはそもそも管理できず別々の写真として管理されます。ムービーについてはなんちゃってレベルで実装されているにすぎない印象。また、これもムービーの再生などをタイミングを同じくしてクラッシュするので未成熟さを感じます。
  • かなり処理が遅い。Nikon D800で撮影したデータを扱っているのである程度遅いのは覚悟の上ですが、レーティングやメタデータ編集といった画質とは関係のない操作でもApertureやLightroomと比べれば桁が一つ二つ違うぐらい応答速度が異なります。

一方次のようなこともわかりました。

CaptureOneでカタログ管理ではなく、セッション管理とすれば処理速度の低下傾向からO(n)ではなく、O(1)になる。CaptureOneのカタログに対する操作は明らかにUIの更新 → Update → UIの更新となっていて、100枚も写真を削除したり移動しようものなら、数十分は制御が帰ってこないという、泣けてくる実装です(すくなくともCaptureOne 7.1.3まででは)。セッション管理とすると、その状況が嘘のように、普通のちょっと重めなアプリとして動作してくれます。

ワークフロー

以上のような問題から、CaptureOneをオーサリングの中核とする事はあきらめて、メモリカードからの取り込み/取捨選択/キーワードの付与はCaptureOneではなくLightroomで、それ以降のポストプロダクション処理はCaptureOneでやることにしました。

取り込み/取捨選択/キーワード付与をApertureではなくLightroomにしたのは、CaptureOneとの連携のためです。Apertureはカタログ形式、つまり、Apertureが指定したディレクトリ構造しかサポートしませんが、Lightroomは取り込みデータ+XMP(写真メタデータ)をある程度自由にディレクトリ構成をデザインできるため、CaptureOneのセッションディレクトリと共有できるためです。

Lightroomでのメタデータ編集結果を共有するためにカタログ設定の「変更点をXMPに自動的に書き込む」をオンにしておきます。 CaptureOne側で該当のファイルをすでに読み込んでいるならば「ファイル」→「メタデータの読み出し」で再読み込みすればXMPファイルからメタデータを取得してくれます。

現状の写真管理ワークフローについてまとめます。

ワークフロー

SD/CFカードからはLightroomに取り込み、その取り込み先ディレクトリはCaptureOneセッションが利用するディレクトリと共有しておきます(CaptureOne側からセッションお気に入りフォルダに設定する)。

CaptureOneに読み込まれたら、あとは必要な写真をメタデータ+フィルタによって絞り込み、編集します。

ムービーデータについてはCaptureOneに持ち込む前に、LightroomからPremiereのプロジェクトに渡します。Peremiereに渡した後は、音量、手振れ補正などをそれぞれAuditionならびにAfterEffectsなどで行います。タイトルロゴ、字幕なども同様に編集します。

HDR向けないし、パノラマ写真を時々撮る事があるのですがこれはLightroomから直接ファイルを複数選択してそのように編集するメニューがありますのでそのように編集します。その他高度な編集はPhotoshop側で行います。

写真管理ソフトウエアにはたいてい印刷サービスが連携されていますが、Lightroom 5とApertureを比べるとデザインテンプレートなどの差でApertureに圧倒的な軍配が上がると思っています。Adobe製品は全体的に、テンプレートとかサンプル・素材が少なく、3rdパーティー製品を買う事が前提となっていますがAppleのそれはある程度高品質なテンプレート・サンプル・素材がそろっており、これだけでも十二分な利用価値があります。Apertureで発注したフォトブックはAppleの決済後、各国の印刷パートナーが印刷して配送するようです。いままでに何回かフォトブックを作っていますが、クオリティー・満足度は非常に高いです。値段はさほど高くないながら、納期も5営業日(首都圏だからかもしれませんがたいてい5営業日ではなく、5日以内に届きます)に届き、色管理も十分にしていない中でもはずれがありません。Lightroomのフォトブックは、これに比べるとかなりいろいろな点をスクラッチから作らざるを得ず、少し敷居が高く感じます。

オンラインでの写真共有はflickr、everpix、tumblrを使っています。flickrは旧来のproアカウントを継続しているので容量無制限でアップロード可能です。everpixは無料アカウントで利用しています。無料アカウントでは12ヶ月前までの写真が無制限にアップロードできます。招待などいくつかアクションを行う事でこの期間制限は延長されます。月4.99米ドルで無制限になります。flickrからの同期によるアップロードもサポートしていていまはflickrのバックアップ用に使っています。flickrは公開レベルが家族、友達などコンタクト先属性を意識しますが、everpixはアルバムごとに公開URLを作れるなど短期的な画像共有には非常に相性の良いサービスと思っています。その他に、写真共有ではtumblrを使っていますが、これは自分の良いと思う代表的な写真をのせるために使っています。flickrやeverpixは容量無制限という魅力からほぼすべてシャッターを切った写真をアップロードしていますが、ある程度絞り込んだ結果として自分の写真を管理したいという思いからtumblrに写真を載せています。

flickrならびにtumblrへのアップロードは自作のスクリプトを使っています。flickrアップロードスクリプトを作成したモチベーションは、月々数十ギガのファイルを不安定なネットワーク環境でアップロードする際、既存のアップローダーでは対応ができなかったからです。tumblrについては、EXIF情報からより多くのタグを付与してアップロードしたり、コメントを整形するために使っています。

写真1枚1枚自体の管理についてですが、このワークフローではxmpファイルが大きな意味を持っています。Lightroomでつけたタグやコメントはそのままtumblrなどに運ばれるように作っています。

各ソフトウエアの良いところと、悪いところ。

1ヶ月このワークフローで写真整理をしてみました。その中ででてきた各ソフトウエアの良いところ、悪いところを整理しておきます。

Aperture 3 - 手元にあるソフトウエアの中で最も使い勝手がよく作られています。キーボードショートカットのカスタマイズや、選択、ルーペでの拡大捜査など基本的な機能が洗練されていて、派手さはありませんが最も生産的な作業が出来ると思います。一方、課題としてはAppleの方針がころころ変わってしまうために、やや振り回されている感がある事です。

Capture One 7 - 自動色調補正、現像処理、色調調整、キーストーン調整、ウォーターマークの挿入など仕上がりについて満足のいく結果を安定的に返してくれます。色調などは好みはあるとおもいますが、自動補正の際にあまりハイライトなどが破綻しない傾向があるとおもいます。一方、課題としては操作が重かったり、頻繁にクラッシュすることがあげられます。

Lightroom 5 - 全体的に軽快に動き、Adobe製品群との連携メニューが豊富なところが売りです。ファイル管理形式が柔軟なところも便利です。一方、課題としてはUI/UXが全体的に未熟なところです。モードによって選択範囲に対する操作の適用範囲が違ったり、Camera Rawなどでは空気を読んで適切な場所にフォーカスをあててくれたりするのにLightroomはそういう配慮がありません。

WordPressからtumblrへ、日記から文章へ

過去の記事について

watermint.orgは2005年10月からWordPressを使ってブログを配信ならびに更新してきました。今回、メンテナンス性などの観点からWordPressでの配信ならびに更新をやめて、Tumblrへ移行する事としました。またこれに伴い、現在までに配信してきましたブログ記事についてはいったん公開を終了とし、必要に応じて新しく書き直したものを配信する予定です。

Tumblrへの移行にあたって、最初既存の記事もそれぞれImport2などのサービスを使って移行を検討していました。いくつか問題があったものの、少し時間をかければ技術的には解決できるだろうというところまでは検証を終えました。ここで、既存の記事についてコストをかけて移行する必要があるかどうかについて別途検討を行いました。

今までの記事は、ガジェット、ライフハック的な内容、旅行や遊びにいった記録などでしたが、それぞれ今見直すと再度これらを新しく皆様に配信するほどの必要性が見当たりませんでした。

検索キーワード等を見るといまも少なからぬ方々が本ブログにご訪問いただいている点を考慮するとすべてそれらをリンク切れにしてしまうのは少し心苦しいところでした。一方いつまでも、時代遅れとなってしまい場合によっては今では不正確な情報を掲載し続けることはかえってご迷惑をおかけする事になるだろうとの判断から、ご愛読・ご訪問いただいた皆様には申し訳ないと思いながらも、記事の移行はやめることとしました。

今後の内容について

またwatermint.orgは、いくつか技術的ないし執筆においての実験の場として利用していたために、比較的短文の記事が多かったのですが、これらも時代に合わないとの判断からやめていく事にしました。短文での情報発信は@watermintを中心としたサービスに移行する予定です。

今後は日記的な記録よりも、数日ないし数週間程度考えて熟成させた文章を中心に掲載するつもりです。

これまでは時事ネタに反応したブログ記事をいままで何度か書いてきました。こういったPV向上を狙ったような記事は一時的にはたしかにアクセス統計をみるとPVに影響があるのですが、PV向上を狙った釣り記事が氾濫する昨今、あえて本サイトで同じ事をする必要はないと考えました。今後はホットトピックとは無縁の、地味目なテーマを中心に、より深堀した内容を配信できるよう内容を整備していこうと思います。