2010-12-19

QlikViewメモ

QlikViewリンクのメモ

プレゼンテーション面は、サンプル見ながら作るというのが手っ取り早いなあ。

2010-12-15

Agile Day4に参加させていただきました。

12/10に、Microsoftさま主催のAgile Day4 というイベントに参加させていただきました。

とても評判がよく、人気の高いイベントなので、わたしのようにバリバリ開発中心とは言えない人間が参加するのは、正直申し訳ない気もしています。
(人数の関係で参加できなかった方もいらっしゃるかと思うので...。)
せめて内容などを少しでもお伝えできたら、と思い、簡単なレポートを書いてみることにしました。

* * *

わたしが『アジャイル』というキーワードに関心を持ったのは、Redmineがらみでいろいろな情報を探っていたことがきっかけです。ただ、はじめはXPとかスクラムとか、耳慣れない言葉ばかりで、とても縁遠い世界だな...と感じていました。

そんな中、会社で打合せの『ファシリテーション』スキルについてのミニ講座を受け、限られた時間の中で効率よく実りのあるミーティングを行うためにはどうすれば良いのか、というのを真面目に考えるようになりました。

誰にとってもそうですが、定時でしか勤務できない身のわたしにとっても、これは大きな課題です。また、生産性の高いエンジニアの皆さんの貴重な時間を、無駄な打合せでつぶさせたくない、ということも常々思っていました。

何気なくいろいろなアジャイルに関する資料を見ているうちに、こうしたファシリテーションの面についても大きく取り上げられていることに気が付き、まずはできることからはじめよう、と思うに至りました。

* * *

さて、本題。
たくさんの方々が #msagile で情報を発信してくださっているので、あまり良く知りも知らないわたしが、多くを語ってもどうかな、と思いますが、どうかお付き合い下さいませ (_ _)

* * *

はじめに: マイクロソフト 長沢さん


まず、はじめは、マイクロソフト(以下、MSと略させていただきます)の、長沢さんのご挨拶から。

会場の案内や、MS社としてのアジャイル開発に対する取り組みなどをご説明いただきました。挨拶とは言え、お話を短い時間でまとめるというのは、やっぱり難しいものだと思います。

ご本人も、『5分の時間内に話が終わったのは、はじめて』と仰っていました。
書き留めたメモの中での、長沢さんからのメッセージは、こちら:
  • どんな些細なことでも、次につなげる!
  • あなたの仲間はここにたくさんいます!
  • おかげさまで、ちょっと肩身の狭いわたしも、『ここにいても良いかしら』と感じることができました。
    こうしてイベントが開始しました。

    * * *
    1. アジャイルでのテストを考えてみる: TIS 近江さん


    近江さんは、テスト担当者としてプロジェクトに関わったご自身の経験を元に、お話をして下さいました。

    近江さんの言うテストの目的は、『不具合を検出するためのもの』
    『リリースの判断、次のステップに進めるかどうかの確認や評価のために行うもの』、ということでした。

    アジャイル開発は、前提や決め事の変化に対応することを掲げているため、テストについても、先の段階で考えたものが前提と会わなくなる場合があります。

    やはりテストにおいても、もそういう変化とか反復をうまく受け入れていくことが大事、と仰っていたように、わたしは受け取りました。

    近江さんからのメッセージは、こちら。
    (わたしの勝手な受け取り方で表現していますので、間違いがあったら申し訳ありません....)

  • 変化や反復は、お客様、チームの最新状況を踏まえて、良いものを考えられる機会ととらえていきましょう。
  • 必要なものはドキュメント化しておきましょう。そうすることで、テストの勘所がわかったり、効率よく進めることもできるようになります。
  • 反復の機会には、テスト担当者も積極的にお客様とのコミュニケーションを持ちましょう。デモの場面にも参加して、お客様の本当に必要としているものは何かをキャッチしたり、すばやい調整につなげることができます。
  • 恥ずかしながら、わたしはテストの経験がほとんどないので、近江さんのお話についていけていなかったと思います...。

    ですが、『変化』を『チャンス』と受け取ることや、お客様(利用者)と接する機会を増やすことが大事という姿勢は、不得手ではありますが、取り込んでいこうと思います。

    また、『変化のための場当たり的な対応』と思われないように、きちんとドキュメントを残すことは大事だよね、ということも感じました。


    * * *

    2. やさしいアジャイルのはじめ方: 永和システムマネジメント 西村さん


    アジャイルにおいても著名な方なので、わたしが説明するまでもありませんが、ご本人のお話を拝見する機会は初めて。
    メリハリの利いた、楽しいプレゼン資料でお話をすすめて下さいました。 (フォントが可愛い、というご意見もあったようです)

    アジャイルの動向として、本来は開発現場から広がってきたものだが、最近はマネージャ、経営層が興味を持つようになってきた、とお話して下さいました。

    その背景は、こんなところにあるそうです:

    • ビジネス優先の開発が求められている
    • 生産性の向上が必要 (コスト、品質といった面での生産性)
    • 内製化が進んでいること 
      (いままで外注していたものを、自社開発する必要が出てきた。じゃあ、アジャイルでやってみる?という動き)

    一方で、現場の望みは、『とにかくプロジェクトがうまくいって欲しい!毎日不安を持たずに仕事をしたい!』に尽きるとのこと。

    そこで重要になるのが下記の点:

    • 十分な事前の検証ができること
    • より正確な情報でプロジェクトの進捗や課題を管理できること
    • リスクがあるなら早期発見し、さっさとつぶすことができること (リスクに怯えず安心して眠りたい!)

    ただ、プロジェクトの中では、『予測していなかったことも起こりうる』、ということを心構えとして持っておくことが重要だそうです。
    (最近わたしもそういう状況に遭っただけに、そういう変化が起こりうることへの耐性をもっておかないといけないなと感じました)

    西村さんは、やさしいアジャイルの第一歩として、こんなことを述べられていました。

    • 一回でも多く、動くソフトウェアを提供することを目的とするのはどうでしょう?と。

    また、お話はツールやコーディングではなく、ファシリテーションの面に進んで行きます。
    おなじみの朝会(デイリースクラム)や、ふりかえりの効果的な方法などをお話下さっています。この内容に関しては、西村さんの資料をどうぞ。


    もちろん、そういう時間が取れないという悩みについては、朝じゃなくても良い、夕会だっていいし、ランチミーティングだっていいんじゃないの、というアドバイスも。
    (ちなみに、8時半-5時に制限されるわたしの場合は、朝会が一番良いし、悩み事や、やるべき課題は朝一にすっきりしたいと思っているタイプです)

    こうしたプラクティスの導入を、うまくメンバーに勧めていけない場合でも、『プラクティスには目的がある。目的がみんなで判れば、導入しやすくなる』とのアドバイスもありました。

    個人的には、いま関わっているプロジェクトでも、実は朝会をやりたいんだけど、時間のことを考えると切り出しにくく、躊躇している状況です。でも、メンバーの皆さんに、目的や効果をだんだんと気づいてもらえるように、なんとかうまく運んで行きたいな、と考えている次第です。

    おかげさまで、前に進む元気が沸いてきました。ありがとうございました!

    * * *

    3.自律的、自己組織的チームを作るコミュニケーションワーク : セントラルソフト 林さん

    始まりは、『おおー!?』『ええー?』という掛け声の練習から。
    アジャイルがきっかけ(?)で、慶事を迎える運びとなった林さんのアイスブレイクに、会場もいったんリラックスした雰囲気になりました。


    林さんは、『すくすくスクラム』の名づけ親の方だそうです。

    林さんのセッションでは、自己組織化のためのNLPというコミュニケーションのための心理学のうち、メタモデル、ミルトンモデル、エクセレントサークルという3つの手法を紹介して下さいました。

    (ここで言う自己組織化とは、チームが自発的に活性化し、生き生きとし、協力して互いに成長しようとしているとても良い心理状態に至ること、とわたしは受け取っています)

    心理学の専門のお話はなかなかついていけませんでしたが(汗)、NLPは、上手なコミュニケーションを築くためのテクニックを体系化した学問のようです。

    そのうちのメタモデル、ミルトンモデルは、『質問』に関するテクニックだそうです。 (ミルトンというと、赤ちゃん用製品を思い出してしまうのですが)

    質問による活性化の勘所として、ご紹介下さったのは、下記の点です。
    • いったん相手に共感し、考えさせることが重要。
    • 相手の考えを受け入れているという、『承認』のメッセージも重要。

    承認のメッセージは、単純に挨拶する、朝会の中で相手の『名前』を言って意見を聞く、というスタイルでもよく、重要なのは『あなたのことを尊重しています』というイメージを伝えること、だそうです。

    この観点、子育ての面、子どもとのやりとりにも欠かせない、重要な点だと感じました(^^;
    とくに、承認されているんだよ、意思が尊重されているんだよという安心感は、子どもがいろんなことにチャレンジしていく原動力になっている気がします。大人だってそれは当てはまるんでしょうね。



    実践の場である朝会については、西村さんのセッションでも触れられていましたが、このようなことを目指すといいそうです。

    1. 目標の確認をする
    2. 可能性のある選択肢を広げる場とする (ここでも承認のメッセージをうまく使いながら)
    3. どの課題をいつやるか、という意思の確認のための場とする

    2点めについては、『考えを広げる質問』で情報収集し、対策の可能性を広げて行きます。(たぶんミルトンモデル)
    そして、そこから『閉じてまとめていくための質問』をおこなって、3点めの課題や行動の明確化につなげていくということを仰っていました。(こちらがメタモデルかな?)

    さて、セッション自体は、お話だけではなく、実践を交えつつ進んでいきました。
    行ったことは、次のようなものです。

    (1) エクセレントサークル



    自分にとって最高の状態を思い浮かべ、それをいつでも追体験できるようにトレーニングすることで、緊張や困難な時でもリラックスし安定した心の状態を保てるようにするための、『エクセレントサークル』という方法を実践しました。

    (2) 2分間相手の話を聞く

    2人で交代で、互いに相手の話を2分間づつ聞く、というもの。話したくなってもできるだけ聞くようにしてください、との指示をいただき、今回のイベントの参加目的を述べ合いました。

    (3) ミルトンモデル、メタモデルを踏まえた質問のやりとり


    3人が組みになって、1人が質問をし、1人が答え、1人が観察するということを行いました。こちらもローテーションしてそれぞれが必ずどの役割も行うようにしました。

    後半は、これらのお話や実践を踏まえ、6人のグループでのワークショップを行いました。


    まず、みんなで、今回のイベントの参加目的を書き出しました。共感できるものがあったら、星印を付けました。
    つぎに、課題について各自書き出しました。ここでも、共感できるものがあったら、星印を付けました。

    * * *

    と、ここまで偉そうに書かせていただきましたが、実は、わたしは17時過ぎまでしか時間が確保できず、このセッションの最後を見届けることができませんでした....(_ _)
    ワークショップ形式で進んでいたのですが、中途半端にしか参加できず、逆に場を乱していなかったか心配になっておりましたた。結果もどうまとまったのか...。

    この記事を書いている途中、Webを調べたところ、みんなで書き込んだ模造紙は、林さんのBlogに掲載されていることが判りました。 (ありがとうございます!)

  • http://d.hatena.ne.jp/essence/20101212/p1
  • 目的と課題の共有を行ったあと、この作業を通しての『気づき』と、『対策』を導いて行く、という流れになっていたようです。
    想像になってしまいますが、こういう流れだったのかな...と思います。

    • 文章に書き出すことで、自分の目的と課題をみんなに伝わる形で表現する
    • 表現した内容をみんなで見て、共感をしてもらう
    • 共感した内容から、各自が気づきを得る
    • 『みんな』の課題としての対策を、一緒に導いていく

    今回は、各自の思うことを引き出しやすいように、見て判りやすいように、模造紙を使ったのかなと思います。
    実際は、これらを会話の中で実践していく形になるのでしょうね。そのために、メタモデル/ミルトンモデルを利用していくのかな、と、書いている今、まさに『気づき』ました。

    ただ、なかなか会話でうまくいかなさそうなので、お互いの考えを共有するための補助ツールとして、ホワイトボードをうまく使っていきたいなと考えています

    わたしがご一緒させていただいたグループの模造紙もちゃんとありました :)
    対策に記載してあるとおり、自分の会社に持ち帰って、(とりあえず自分から)やってみることにします。

    * * *

    最後に:

    同じグループになった皆様、講師のみなさま、スタッフのみなさま、貴重な時間を共有させていただき、どうもありがとうございました。

    2010-11-29

    Redmine Importerを使わせていただきました。

    Redmineに関する重大なニュースが流れて、びっくりした週末。
    何が自分にできるんだろうな....と思いつつも、なかなか使うばかりで提供ができません。お恥ずかしい限りです。

    * * *
    さて、先日、「チケットを一括でインポートしたいんだけど、カスタムフィールドも一緒に登録できますか?」というリクエストを同僚からいただきました。
    今まででも、下記のプラグインを利用していたのですが、カスタムフィールドはNGでした。

    いろいろ探してみたところ、@yusuke_kokubo さんから、もう一つのプラグインを紹介していただきました。(ありがとうございます!)

    こちらのプラグイン、有難いことにカスタムフィールドからファイルのエンコーディング指定まで可能。(ありがとうございます!)
    ※残念ながら、上記2つのプラグインは名前がかぶってしまうので、そのままでは同居は出来ません。

    さて、junoさんのプラグインを、Redmine0.9xで試したところ、まず言語ファイルの場所が変わっているため、config/locales 以下にファイルを移動させました。このあたりは、多くの皆さんがBlogに書かれている通りで、インデントの調整なども行いました。

    その後、こちらの記事も拝見し、NKFによる文字コードの変換の部分を、1行づつ変換ではなく、ファイルを読み込むところで一気に変換するよう、調整してみました。

    加えてみた変更は、以下の通り。

    • 読み込み時にNKFでまとめて変換
    • Permissionの調整 (Controllerの :authorize を利用)
    • ルーティングを調整 (/:project/:controller/:action の順にしてみた)
    • メッセージの調整
    • プラグインに関しては、r-labs チュートリアルを参考にしています!

    せっかくなので、Gitの練習用に、junoさんのソースをフォークさせていただいたき、そちらに変更分を登録してみました
    たぶん1.0xでも動くかな...と思っていますが、不具合があったら修正してみます。

    なお、一括インポートの注意点ですが、チケットが作成/更新されると、通常のフローと同じで、メールが送信されます。

    Issue.saveのところで、コードには明示しなくとも、Issue Observerがメール送信のコードを呼び出すようです。
    一括登録時は、メールが出ないように設定できるといいなあ...と思いました。

    2010-11-15

    Hudson勉強会に行ってきました。(20111112)

    諸般の事情により、平日夕方や週末のIT系の勉強会からは、ずっと遠ざかっていました。

    ですが、どうしても、『川口さん自身がいらっしゃる、Hudson勉強会だけには参加したい~!』と思い、なんとか周囲のご理解とご協力を得て、出席に漕ぎ着けることができました。

    #ちなみに、職場から会場までは、さほど遠くないので、開始45分前に出れば十分だろうな…と思っていたのですが、意外と駅から会場の法政大学までの行き方がわからず、思ったより時間がかかってしまいました(^^;
    念願の勉強会、書きたいことはたくさんあるのですが、本当に楽しかった、の一言に付きました。
    セッションもLTも、どれも甲乙付けがたく、これで(基本の)参加費は無料というのが申し訳ないくらいです。

    * * *

    個人的に、非常に感銘を受けたのは、@magnet88jp さんの、 Hudson活用事例 です。

    私は仕事の中で、こじんまりと、社内向けのWebアプリやツールを作ったりもしているのですが、QAとかテストのことを全く考慮していませんでした。
    ですから、@magnet88jpさんのプレゼンで、もう穴があったら入りたいくらいに恥ずかしくなってしまいました…。
    実は私の職場の後輩も、今回の勉強会に参加してくれていたので、本人なりにいろいろ感じ取っているはず。きっと今後に活かしてくれる、と思っています。

    ご本人には、とても恐れ多くてお話することができませんでしたが、本当に貴重なお話をしてくださって、有難うございました。

    今回の勉強会のメモです。久しぶり。
    プレゼン&LTの中で、大ウケで、かつ遊びゴコロが一番刺激されたのは、@kiy0takaさんの モテるHudsonエンジニア
    Hudsonに絡めた、『これでもか、これでもか~!』という、モテるための策が次々と繰り出され、会場も大爆笑でした。
    Groovyを利用したTerminal Pluginも物凄く楽しいのですが、LTの最後の『合コン』テロが衝撃的。

    ......とても『ご清聴』どころじゃありませんでした!!
    • なお、合コンテロ、週明けに会社のHudsonで試してみよう、と画策し、Scriptを埋め込んで検証してみたところ、IEではテロが未遂に終わってしまいました(互換性の問題)。
      IEでなんとか表示させたいなと思ったのですが、如何せんJSも明るくないので、ここは断念。
    • Firefoxではバッチリですが、カスタマイズしたダッシュボード/View上では、やはりテロは行われませんでした。
      トップページでは見事に遂行されていますが、各Viewの説明毎に記載しないと、気づいてもらいにくいかもしれません。
      (Hudsonのヘッダそのものに埋め込む手もありますが)
    * * *
    いつもお世話になっている、haruさんのLTの中では、E-mail Extプラグインを使って、Redmineにチケットを上げているという使い方が紹介されていました。私も同じプラグインを使っているんですが、そういう発想はありませんでした。
    なるほど…(^^;
    ちなみに、私はRedmine派でRedmine Hudson pluginを利用していますが、懇親会の会場では、周りをtracユーザの皆様に囲まれてしまいました...。
    * * *
    もちろん、川口さんご本人のお話も外せませんが、書ききれないので、またいつか。
    #ご本人による、『ハドソン』ではなく、『ハドスン』という響きが、とても意外でした。

    とにかく、なんといっても、MLやネットでお世話になった方にご挨拶することが出来たのは、本当に嬉しく、こうして書いていても、しみじみとした気持ちが沸いてきています。
    たぶん今後もそんなに勉強会には参加できないと思います。それだけに、改めて、今回機会をいただけたこと、そして会そのものを企画、進めてくださった皆様に心から感謝申し上げます。

    HudsonからSVNリポジトリへのアクセス

    普通はあんまりなにも考えずに、Subversionリポジトリにアクセスしてチェックアウトできます。
    ただし、Hudsonのサーバから見て、SubversionのサーバはProxy経由でアクセスできない場合は、このままだとチェックアウトもポーリングもできません。
    どうしたものかなあ…と思っていたら、Proxyの設定が可能なようで、Hudsonの場合は、下記を参考にして hudsonの実行ユーザの .subversion/config を調整しました。

    なるほど、なるほど。
    環境変数のhttp_proxyに設定してしまうと、proxyの使い分けがうまくできませんが、Subversionの設定ファイルを利用すれば、ドメイン毎にプロキシを利用したり、しなかったりと、細かい調整が出来るようです。

    2010-04-09

    Svnsyncでリポジトリの同期 (Remote To Remote)

    Redmineの利用前からSubversionは使っていたのですが、当初リポジトリはWindowsのファイルサーバ上に置いていました。
    ドメイン構成を行っていたので、特にApacheやSvnservの必要はなく、それはそれで楽でしたが、自宅からリポジトリを参照したくなったりすることがあるため、HTTPでアクセスできる環境に移動させることになりました。

    もちろん、Gitを使うという方法もあるのですが、新しいユーザだと不慣れなことや、参考資料、クライアントが少ないこともあって、こちらは却下。

    (一部ユーザはVisualStudioを使っているため、VisualStudio用のプラグインのあるSubversionのほうが何かと好都合でした)

    HTTPベースに移行しても、そんなに不都合は無く、これはこれでなかなか便利です。

    さて、そんな折、既存のリポジトリを、私の扱っているリポジトリに移動させてみたいというリクエストがありました。

    双方のリポジトリはネットワーク的に分断されていて、HTTPでのみしかアクセスできません。

    そこで、今回は、svnsyncを使ってリポジトリの同期(転送)をすることにしてみました。このsvnsync、リモートのサーバからローカルのファイルシステムにダンプするのは数回試していますが、いったんローカルにダンプして、転送先にSCPやFTPするのも面倒なので、Remote to Remote で同期させてみることにしました。

      • 元リポジトリ:         http://source.site/svn/hoge/
      • 転送先リポジトリ:   http://sync.site/svn/hoge/
      • 仲介サーバ:           とあるCentOS
        (svnsyncコマンドが使えて、両方のサーバにHTTPアクセスできればどこでもOK)

    中間の某CentOSを利用して、Remoteからデータを取得し、Remoteにデータを転送するという方法です。

    一応こんな感じで出来ました。

    1. 事前準備

      • http://sync.site/svn/以下 に、hoge という同名の空っぽのリポジトリを作成。
      • アカウントを設定し、Webからのアクセス権限を与えておきます。
    • 上記の作業は、USVN という、WebベースのSubversion管理ツールを利用しています。

    2. リモート同士での初期化

      • この作業は、仲介のCentOS上で実行します。
      • svnsync init 転送先URL 元リポジトリURL というコマンドになります。
    [CentOS]$ svnsync init http://sync.site/svn/hoge/ http://source.site/svn/hoge/  --no-auth-cache --source-username hogehoge --source-password xxxxxxx --sync-username hogehoge --sync-password xxxxxxxxxx


    3. sync を実施





      • 初期化の成功後は、同じく仲介のCentOS上でsync作業になります。


      • init以降は、ソースのURLは指定しなくともOKです。





    [CentOS]$ svnsync http://sync.site/svn/hoge/ --no-auth-cache --source-username hogehoge --source-password xxxxxxx --sync-username hogehoge --sync-password xxxxxxxxxx


    双方のサーバが分断されていても、仲介サーバがあればOKなので、これは便利。


    Hudson利用して同期させるというのも良いかな…なんて思っています。

    2010-03-11

    RPMでhudsonをインストール

    今日のトラブル: HUDSON_HOMEを変えても認識されない...。
    Redmineのプラグインでお世話になっている r-labs 様提供のHudsonプラグインを導入すべく、まずはHudsonのインストールをしてみました。

    テスト環境でのHudsonは、単純にhudson.warを取ってきてJavaでコマンドラインで実行していたのですが、CentOS用のRPMのパッケージ化がされているとのことなので、今回はそちらを利用することにしました。

    ありがたいことに、RPM版を使うと、サービスの登録やユーザの作成まで行ってくれて、至れりつくせり。

    メインの設定ファイルは/etc/sysconfig/hudson になりますが、こちらを見て、$HUDSON_HOMEをデフォルトの /var/lib/hudson を変更することにしました。
    (それに合わせて、インストール時に自動で作成された /var/lib/hudson は削除しました)

    その後、service hudson start で起動したのですが、どうしても、以下のエラー?が出てしまいます。

    # /etc/rc.d/init.d/hudson start
    Starting Hudson runuser: warning: cannot change directory to /var/lib/hudson: そのようなファイルやディレクトリはありません


    一応、サービスは起動し、指定した$HUDSON_HOMEにも必要なものが展開されるのですが、どうにも感じがよくありません。serviceコマンド経由でも、init.dからの起動でも(結局同じなので)、上記のWarningは消えてくれません。

    仕方がないので、一度サービスからの登録を削除して、再度手動で追加すると、Warningが出なくなりました。

    # chkconfig --del hudson
    # chkconfig --list hudson
    サービス hudson は chkconfig をサポートしますが実行レベルで参照されていません (run 'chkconfig --add hudson')
    # chkconfig --add hudson
    # chkconfig --list hudson
    hudson 0:off 1:off 2:off 3:on 4:off 5:on 6:off
    # chkconfig hudson on
    # chkconfig --list hudson
    hudson 0:off 1:off 2:on 3:on 4:on 5:on 6:off
    # /etc/rc.d/init.d/hudson start
    Starting Hudson [ OK ]

    さて、これでひと安心。

    HudsonはCIツールなのですが、個人的にはソースコードのビルドというタスクには利用しません。
    どちらかというと、DBのバックアップやインデックスの再構築、シェルで作成したメンテナンス用のタスクの管理に使おうと思っています。

    * * * 補足 * * *

    嬉しいなと思ったのは、ジョブ(タスク)のスケジューリングや依存関係の設定ができること。 Cronだと、いろんなステップを踏んだ処理を実行させる場合、1つのスクリプトに全部書かないと難しいのですが、逆に、どこか途中で失敗しても、その原因がつかみにくくなります....。 Windowsサーバの場合は、SQL ServerのIntegration Services(SSIS)+SQL Agentの機能を使って、細かくステップ分けした処理を、1つのジョブとしてパッケージ化して集中管理していました。 でも、Linuxとかの環境だと、どうしたらいいものか...と思っていたところに、Hudsonはなんとなく使えそう、と分かってきました。なお、UIが可愛い、というのも大きなモチベーションの一つです。

    2010-02-16

    iw.rotatezlogs

    通常は、Zope/PloneはApacheと同様に KILL -HUPなどでログをローテートしないといけません。
    Windows版のPlone2.1x を使っていたころは、WindowsのサービスをKill hup するような方法がわからなかったので、rotatezlogs というZope専用のプロダクトを利用していました。

    現在は、ベースのOSをCentOSに切り替えているので、/etc/logrotate.d/ 以下に設定を追加すれば良いのですが、zopecrl logreopen がどうもうまく動いてくれません…。 (ただいま調査中)

    どうしたら良いものかと思っていたところ、iw.rotatezlogs というPlone3対応のものが出ていたので、今回もその方法に頼ることにしました。


  • Package:  iw.rotatezlogs
  • easy_install で追加しています。(buildoutだと、依存関係で失敗した場合、設定ファイルが消えたり、全体に影響が出てしまうため)
    • easy_install iw.rotatezlogs で Pythonのsite_pakages に追加。
    • zope.conf に 設定追加。
    • 私の場合は、/var/log/zope に 1MBで6世代ローテートします。(このへんはオプションで設定できます)

    ※iw.rotatezlogsは、ログの指定はサイズ指定なので、Dailyでのローテートは出来ません。ですが、形式を指定したアーカイブオプションなどがあり、機能としては十分かなと思います。

    設定は以下のような感じになります。

    <eventlog>
    level INFO
    # zopeのデフォルト
    # <logfile>
    # path /var/log/zope/instance.log
    # level INFO
    # </logfile>

    <rotatelogfile>
    # Required parameters
    # -------------------
    path /var/log/zope/instance.log
    # 1MBごとに過去5世代まで
    max-bytes 1MB
    backup-count 5

    # Optional parameters
    # -------------------
    # compression zip
    # format ------\n%(asctime)s %(levelname)s %(name)s %(message)s
    </rotatelogfile>
    </eventlog>

    <logger access>
    level WARN
    # zopeのデフォルト
    # <logfile>
    # path /var/log/zope/instance-Z2.log
    # format %(message)s
    # </logfile>
    <rotatelogfile>
    # Required parameters
    # -------------------
    path /var/log/zope/instance-Z2.log
    # 1MBごとに過去5世代まで
    max-bytes 1MB
    backup-count 5

    # Optional parameters
    # -------------------
    # compression zip
    # format ------\n%(asctime)s %(levelname)s %(name)s %(message)s
    </rotatelogfile>
    </logger>


    ところで、ログのローテートの指定は、zope.conf上になるので、何も指定しないとbuildoutを実行した場合はzope.confが更新されてしまい、せっかく書いた設定も消えてしまいます。うっかりbuildoutしたのを忘れてしまい、Zopeを再起動させると、ログのローテートが無効になってしまうので、気がついたらログが数十MBになっていました。

    これは困ったな~と思っていたら、幸いにも buildoutで設定できるというBlogを発見!



    * How to add rotatezlogs in your buildout ( http://tarekziade.wordpress.com/2008/03/02/how-to-add-rotatezlogs-in-your-buildout/ )



    以下のような感じで、buildout.cfgに指定すれば、zope.confに書き出してくれます。



    [instance]

    ...

    event-log-custom =
    %import iw.rotatezlogs
    <rotatelogfile>
    path ${buildout:folder}/var/log/instance.log
    max-bytes 1MB
    backup-count 5
    </rotatelogfile>

    access-log-custom =
    %import iw.rotatezlogs
    <rotatelogfile>
    path ${buildout:folder}/var/log/instance-Z2.log
    max-bytes 1MB
    backup-count 5
    </rotatelogfile>



    ということで、これでだいぶ助かりました。

    buildout.cfgで、ずいぶんいろんな設定ができるものだと感心しきりです。まだまだ便利な使い方があるので、もっとうまく利用できるようにしたいなと思います。

    2010-02-04

    SetEnvIf を使うんだけど…。

    Ploneで公開しているコンテンツについて、アクセス元のIPをチェックして、アクセス制限を行ったり、ドキュメントルートに割り当てるパスを調整しようと思いました。

    ただし、アクセス元は、Proxyを経由してくるので、環境変数の HTTP_X_FORWARDED_FOR を見て判断することにしました。

    動作確認として、SetEnvIf 条件 環境変数 –> で、Options Deny,Allow を利用して試すことに。

    環境変数は、PerlのCGIを使ってチェック。

    #!/usr/bin/perl

    print "Content-type: text/plain\n\n";
    foreach $var (sort(keys(%ENV))) {
        $val = $ENV{$var};
        $val =~ s|\n|\\n|g;
        $val =~ s|"|\\"|g;
        print "${var}=\"${val}\"\n";
    }

    上記のコードで拾った HTTP_X_FORWARDED_FOR を元にhttpd.conf を調整したのですが、どうも思ったように動きません…。

    # Access Control From Source IP
     
    SetEnvIf HTTP_X_FORWARDED_FOR xx\.xx\.xx check

    Order deny,allow
    deny from all
    allow from env=check
    Deny from all

    なにやら、許可されるべきIPなのに、どうやってもアクセスがブロックされてしまいます…(x_x)

    仕方がないから、mod_perlでPerlAccessHandlerまで書かないといけないの??とまで考えたのですが、ちょっと調べたら、出てきました、その答えが…。

    SetEnvIf X-Forwarded-For xx\.xx\.xx check 

    こうしないといけないんですね…。

    逆に、RewriteCond の場合は、RewriteCond %{HTTP:X-Forwarded-For} という具合に指定しないといけないそう。

    うーん、勉強になりました…。

    2010-02-01

    blobstorageの中身

    Ploneのblobstorageの中身は、ファイルシステム上からは何がなんだかわかりません…。

    それでも、実際の本体のファイルはどういうドキュメントなのかくらいは見当がついて欲しいこの頃。

    そう思っていたら、Twitter経由でこんなふうにコマンドでチェックするといいよ、という書き込みを発見しました。

    # find /var/blobstorage -type f 

    やってみると、なるほど、とりあえず *.blob というファイル本体だけは、きちんと取得できました。

    fileコマンドと組み合わせると、もうちょっとわかりやすくなりました。

    # find /var/blobstorage -type f  -ls -exec file {} \;

    …0x0380724.blob: Microsoft Office Document
    …/0x03f07855.blob: PDF document, version 1.4
    …/0x03816348bb.blob: Zip archive data, at least v2.0 to extract

    なんとかOSからファイル名がわかるような仕組みだとうれしいのですが、やはりReflectoとか、FSSを使うほうが良いんでしょうか。

    2010-01-27

    Varnishのタイムアウト

    慣れないながらも、Ploneのアクセラレータ用にVarnishを利用しています。

    匿名アクセスの場合はそれなりに早いかな、と感じるようになりましたが、逆に、いろいろと「あれれ~?」な現象も出てきました。

    コンテンツのCacheを行うことで、ユーザ側から見たパフォーマンスを改善するのが目的なので、当然古いデータが見えてしまったり、更新が即座には反映されなかったりします。

    具体的には、このようなパターン。

    • 匿名アクセス、匿名でのコメントがOKなコンテンツに対し、匿名アクセスでコメントを行うと、ページを再読み込みしても投降したコメントが表示されない。
    • Varnishのメモリにキャッシュさせないといけないので、コンテンツの1回目の読み込みだけは時間がかかることがある。
      (誰かがすでに同じページにアクセスしていれば、その恩恵にあずかることはでるけれど)

    また、わたしの環境の場合だけかもしれませんが、Ploneの更新情報(RSS)が、Varnishを通した場合、更新されなくなってしまいました。

    具体的には、ブラウザからRSSの画面にアクセスして表示する場合は問題ないのですが、Thunderbirdに付属のRSSリーダーやSharpReaderなどの、専用のRSSリーダーは、最初の一回目のRSSの読み込み以降、その後の更新を検知してくれなくなってしまったのです…

    Varnishは設定ファイルによって、メモリのキャッシュを返したり、バックエンドにリクエストを通したりという動作を振り分けるのですが、RSSリーダなどは匿名アクセス扱いになってしまいます。しかも、どういうわけか、Last-Modifiedもあまり認識してくれないようでした…。

    仕方がないので、Ploneに限ってなのですが、末尾が “/RSS” というURLの場合は、varnish.vcl を調整して、Varnishのメモリを使わないようにしてみました。(赤字の部分です)


            if (req.http.Authenticate || req.http.Authorization) {
    pass;
    }



            # We only care about the "__ac.*" cookies, used for authentication
    if (req.http.Cookie && req.http.Cookie ~ "__ac(|_(name|password|persistent))=") {
    pass;
    }

    # File type that we will always cache
    if (req.request == "GET" && req.url ~ "\.(gif|jpg|swf|css|js|png|jpg|jpeg|gif|png)$") {
    lookup;
    }

    if (req.request == "POST") {
    pipe;
    }

    # Added on 20091201 not to cache RSS info.
    if (req.request == "GET" && req.url ~ "/RSS$") {
    pipe;
    }






    もう一点困ったこと、というと、Ploneの管理画面にアクセスし、Indexの再構築などの重い処理を行うと、Zopeからのレスポンスが返ってくるまでに時間がかかり、Varnishがタイムアウトでエラーを起こすようになってしまう、ということでした。



    また、片方で重い操作をしていて、別のユーザがPloneにアクセスした際にも、全体でパフォーマンスが落ちていると、Varnishがタイムアウトを起こしてしまいます。



    この間隔が思ったよりも短く、何も設定しないでおくと、ユーザさんには、下記のような意味不明の恐ろしげなエラーが表示されてしまいます。





    • "Error 503 Service Unavailable Backend did not respond. Guru Meditation: XID: 456452130".




    デフォルトではどうも短すぎるので、下記のURLを参考に、タイムアウトの値を調整してみることにしました。





    といっても、以下のように1行加えただけ。







    backend default {

            # Your Zope / Plone instance.


            .host = "localhost";


            .port = "8080";      
            .first_byte_timeout = 300s; #ここを追加

    }





    本当は、ZopeをZEO化して、重い処理は別プロセスで行って、参照専用のリクエストには影響がないように作りたいのですが、そこまでは、まだまだ…。

    2010-01-12

    リポジトリブラウズに、SVNIndexXSLTを利用する

    Subversionのリポジトリへのアクセスは、当初はファイルサーバのfile://プロトコルからのアクセスがメインでした。

    ですが、次第に利用するメンバが増えてきたことと、ネットワークの制限でファイルサーバにアクセスできない場合に困るということで、http(https)プロトコルを利用してアクセスできるように調整を進めています。

    (http経由でのアクセスはApache + mod_dav/mod_dav_svn で設定できます)


    さて、リポジトリへのアクセスは、TortoiseSVNやRedmineなどの専用クライアントを使うので、あんまり気にしなくてもいいのですが、たまにブラウザからもリポジトリを参照することがあります。(テキストファイルなどを眺める際は、ブラウザのほうが便利なので)

    ただし、基本は素のmod_dav_svnを通しての表示なので、非常に味気ないものになってしまいます
    例えに出しては申し訳ないのですが、Redmineのリポジトリなどもそう。

    単純にファイル/ディレクトリの一覧が表示されるだけで、初めてリポジトリを使う人には、『なんじゃこりゃ~?』な気がするかもしれません。
    使うにしても、ガイドも注意点などもなく、なんだか不親切です。

    #別に見るだけなら専用のリポジトリブラウザ、ViewVCとかを使えば良いじゃないの、というご意見もあるかもしれませんが、そうなるとまた別途認証を用意しないといけません…。


    ちょこちょこと調べたところ、SVNIndexXSLTというオプションを使えば、リポジトリ情報をXMLで生成し、Lokk&FeelはXSLTでカスタマイズできることがわかりました。単純にブラウザで表示する以外にも、http経由でXMLでデータを取得することができると、何かと便利です。

    TortoiseSVNのマニュアルにサンプルがありましたので、いろいろカスタマイズしてみました。
    リポジトリのチェックアウト用のアイコンをクリックすると、TortoiseSVNが起動する仕掛けも入っています。(マーカーで囲んだ部分)

    キャプチャ2

    [ 補足 ]

    このXMLのオプションですが、svnコマンドでも、—xml というオプションをつけると、XMLでアクセスできるようですね。

    たとえば、こんな感じ。

    svn list --xml http://redmine.rubyforge.org/svn/

    上記のようにすると、XMLでリポジトリ情報が取得できます。svn log, svn infoなども同じ。

    Redmineのソースをよく見ると、リポジトリへのアクセスは、svnコマンドを通して行っています。また、一覧取得には、やっぱり “—xml” オプションを使っています。該当するのは、{REDMINE_ROOT}/lib/redmine/scm/adapters/subversion_adapter.rb の、このあたり。

    # Get info about the svn repository
    def info
      cmd = "#{SVN_BIN} info --xml #{target('')}"  # <- ここ。 
      cmd << credentials_string
      info = nil
        ..................
    end

    なるほど…。


    でも、やっぱりコミットログや、Authorなどの属性は表示されるわけではないので、あくまでも補助的なものになりますね。

    2010-01-07

    Ploneおぼえがき

    取り急ぎ、メモ。(ちゃんとした記事でなく、自分用..。)

    Ploneをbuildoutして、プロダクトの追加を行ったら、以下のようなエラーが出てインスタンスが起動してくれませんでした。

    ConfigurationExecutionError: zope.component.interfaces.ComponentLookupError: (<InterfaceClass zope.security.interfaces.IPermission>, 'plone.app.portlets.ManageOwnPortlets')
      in:
      File "/usr/local/Plone3.3.2/buildout-cache/eggs/collective.portlet.feedmixer-1.4-py2.4.egg/collective/portlet/feedmixer/configure.zcml", line 30.4-37.10
          <plone:portlet
              name="collective.portlet.feedmixer.FeedMixer"
              interface=".portlet.IFeedMixer"
              assignment=".portlet.Assignment"
              renderer=".portlet.Renderer"
              addview=".portlet.AddForm"
              editview=".portlet.EditForm"
              />

    なにやら、セキュリティのパーミッションでのエラーらしい。

    とりいそぎ、上記のエラーに出ていたプロダクトのconfigure.zcml を修正しました。

    具体的には、以下の一行を追加するだけ。

    <include package="plone.app.portlets" />

    これだけでとりあえず済んでよかった….

    #なぜこの方法がわかったのか、ちょっと忘れてしまいましたが、いろいろとエラーが出なかったバージョンのzcmlを参照しまくったような気が…。

    2010-01-05

    TortoiseSVNのインストール / 設定

    Subversion関係の話題はネットにはたくさんありますので、わたしが書くまでも無いのですが、Redmineを使っている関係でSubversionにはお世話になりっぱなしです。また、PerlやRubyといったスクリプト言語だけでなく、VisualStudioで開発している .NETのコードも、Subversionで管理したりしています。この関係で、いくつか覚書のようなものを書いていこうと思います…。

    TortoiseSVNインストール

    Windowsのインストーラーをダウンロードしてインストール、その後に日本語化パックを適用させます。

    ダウンロードサイト: http://tortoisesvn.net/downloads

    1. “Download Application”から、最新版(Installer)を選択します。
    2. “Language packs”から、JapaneseのSetupを選択します。
    3. Installerを起動してインストールします。完了すると、OSの再起動を促されます。(再起動しないと完全に設定が反映されないという意味なので、すぐにTortoiseSVNを使いたいというのでなければ、あわてて再起動しなくても大丈夫…)
    4. 続けて、日本語化パック(上記の2)をインストールします。

    TortoiseSVNはシェル拡張なので、インストールしても、直後にアプリケーションが起動する、というものではないのでご注意。

    まず、ウインドウの適当な場所で右クリックします。カメのアイコンとともに”TortoiseSVN”というメニューが出ますので、TortoiseSVN –> Settings という順で選択すると、設定画面が表示されます。

     TortoiseSVNの日本語設定

    "General"から、”Language”の設定で言語を切り替えれば、日本語メニューでの利用ができるようになります。

    コマンドラインからの利用

    TortoiseSVNは、基本はGUIでの操作になります。

    ですが、バッチ操作を行いたい場合、コマンドラインから操作できるほうが便利だったりします。Subversionのコマンドライン操作には、svn.exe という、一番シンプルなコマンドライン専用インタフェースがありますが、TortoiseSVNには含まれていません。でも、『TortoiseSVNとsvn.exeを両方入れないとだめなの?』かというと、そうでもありません。

    TortoiseSVNは、TortoiseProc.exe というプログラムを通して操作できます。

     

    TortoiseSVNをインストールすると、TortoiseProc.exeへのパスが通るはずなので、適当にcmd.exeでプロンプトを開いて、以下のような感じで実行できます。

    たとえば、Redmineのconfig(trunk)のディレクトリ一式をエクスポートする場合は、以下のようになります。

    C:\Users\akiko>TortoiseProc /command:export /url:"http://redmine.rubyforge.org/svn/trunk/config" /path:C:\Temp\config /closeend

    *.batなどのファイルを書けば、ジョブでsvn.exeを使うのと同じように、updateやcommitを行うことができます。