投稿者のアーカイブ

CakePHP で debug.log にクエリを出力する(手抜き版)

シェル書いてる時とか Web でも Ajax のときとか

「画面にクエリだされても見えないし、困る〜」

ってときありますよね?

「つーか、なんで画面にだすんだ?ログファイルに出してくれればいいのに 」

とか思いません?

で、調べたらみなさんDBのドライバを拡張して対応されてるようです。
ですが、常にクエリをログに書いて欲しいわけでもないし、ドライバ拡張とか面倒。

クエリを画面にだしてるとこどうなってるのかなぁ、と思って調べたら

cake/libs/view/elements/sql_dump.ctp

にゴリゴリに書いてありました。

これマネしてapp_model.phpにでもメソッド作ればいいんじゃないかなーってことで、作りました。

    /**
     * 通常画面に表示されるログを取得してdebug.logに出力する。
     */
    function sqlToLog(){
        $db =& $this->getDataSource();
        if ($db->isInterfaceSupported('getLog')){
            $this->log($db->getLog(), LOG_DEBUG);
        }
    }

元のログ表示と違って明示的に呼び出すものなのでgetLogインターフェースの確認とか要らない気がしますが、一応。

このメソッドを実行すると debug.log にそれまでに実行されたクエリやら付帯情報(画面に表示されてますよね)が書き出されます。注意点として、画面に出すデータを横取りしているのでログに書き出されたものは画面には表示されません。

配列を print_r で出力した形式なので見やすくはないですが、まぁ、十分かな。

Facebooktwitterlinkedintumblrmail

ぼっちBazaar

5/21(土)、『NAGASAKI-IT hands-on Spring 2011』に参加して、ライトニングトークしてきました。

弊社の吉田くんが

「ひとりぎっと 〜ひとりで使うバージョン管理システム導入編〜」

というGitのハンズオンをやるとのことだったので、それにからめて

「ぼっちBazaar 〜ぼっちを感じるバージョン管理〜」

というわけです。

今回、HTML Slidyでスライドを作りましたのでそのまま貼り付けます(slideクラスのdivには枠を付けました)。

目論見としてはスライド自体をBazaarでバージョン管理して編集しながら実演するつもりだったのですが、残念!

時間がたりませんでした(5分枠で何しようとしてるんだという意見多数)。

ぼっちBazaar

〜 ぼっちを感じるバージョン管理 〜

村部淳也(@murave)

3大分散バージョン管理システムといえば


  • Git
  • Mercurial(hg)
  • Bazaar(bzr)

 

異論はありますまい。

ぼっち


数年前からBazaarを使っていますが

他に使ってる人に会ったことがない。

 

何故だろう。

選択理由


  • 日本語ファイル名に強い(Subversion程度には)
    • 日本語ディレクトリで変な動きをしたりはします。残念ながら。
  • Bazaar Explorer の存在

弱点


ともかく日本語の情報が少なかった

 

ドキュメントは日本語化されてるんですがね

弱点解消


しかし、今年になって

「Bazaarでござ~る。猿でもできる分散バージョン管理“超”入門」

というすばらしい記事が!

さぁ「Bazaarでござ〜る」で検索!

エテ公め!


と言いたい所だけど某社のサルの方が上にでてくるのだった。

 

弱えぇ orz

 

「Bazaarでござ〜る バージョン管理」とでも検索してください

最後に、一言


ぼっちになりたくなければGitを使っとくといいと思います。

 

以上。

時間まで適当に実演


Bazaar Explorer 最高

Bazaar Explorer を使うのがお勧め(当然、コマンドラインでも使えますが)。

  • Mac や Linux ならターミナルから起動 
    • bzr explorer
  • Windowsならメニューやアイコンから起動

    管理の基本

    • 共有リポジトリ作成 init-repo (必須ではありません) 
      • 複数のブランチで効率的にディスクを利用させるためのディレクトリを共有リポジトリという。
    • ディレクトリのブランチ化 init 
      • 管理の基本となるディレクトリをブランチという。
    • ブランチ作成 branch
    • 他のブランチを取得 pull (merge) 
      • 他のブランチの変更を取得する場合も使用します。
      • 作業後に他のブランチの変更を取得する場合はmergeを使用する。
    • 作業ブランチに反映 commit
    • 他のブランチに反映 push

      独特(?)なしくみ

      • チェックアウト(バインド・ブランチ) 
        • 他のブランチ(以降、親と呼びます)にバインドされたブランチをチェックアウトという(たぶん)。
        • コミット(commit)すると親にも反映されたり。
        • さらにSubversionっぽくなる感じ。
           

          おわり

      Facebooktwitterlinkedintumblrmail

      CakePHP でシェルを書くときに最初にやったこと(親クラス作り)

      CakePHP にはデバッグで便利な pr() って関数があります。
      出力の前後に pre タグ を付けてくれる print_r() のラッパーです。当然Web用。

      シェルにも欲しいです。てなわけで作りました。

          function pr($obj){
              $pr = print_r($obj, true);
              $this->out($pr);
          }
      

      簡単。こんな感じで使います。

          $popopopooon = array('こんにちわ' => 'こんにちワン', 'ありがとう' => 'ありがとウサギ');
          $this->pr($popopopooon);
      

      このようにコンソールに出力されます。

       Array
      (
          [こんにちわ] => こんにちワン
          [ありがとう] => ありがとウサギ
      )
      

      print_r() は第2引数に true を渡すと出力せずに結果を返してくれるのでオブジェクト構造をログに出したりするときにも便利です。
       
      でもコレ、全部のシェルに書きたくない。

      どこに集約したらいいのか悩んだのですが、実際に実行するシェルの親クラスを作成して継承することにしました。継承の段数が増えるのはあまりすきじゃないのですが、Shellクラス をそのまま継承するよりも1段増やしといたほうがいいかな?って気もしたので。

      appbase.php

      class AppbaseShell extends Shell {
      
          function initialize() {
              parent::initialize();
          }
      
          function startup() {
              //ウェルカムメッセージを消すためにオーバーライド
          }
      
          /**
           * デバッグ用
           */
          protected function pr($obj){
              $pr = print_r($obj, true);
              $this->out($pr);
          }
      }
      

      ついでに startup() をオーバライドしてウェルカムメッセージを消しました。
      こういう事やるには1段あいだに入ってるほうがいいですね。

      実際に起動するシェルは AppbaseShellクラス を継承します。

      aisatu.php

      App::import('Shell', 'Appbase');
      class AisatuShell extends AppbaseShell {
          function initialize() {
              parent::initialize();
          }
      
          function main() {
              $popopopooon = array('こんにちわ' => 'こんにちワン', 'ありがとう' => 'ありがとウサギ');
              $this->pr($popopopooon);
          }
      }
      

      サンプルコードは今テキトーに書いたのでちょっとあやしいかも。

      最後にオチを。

      このprメソッド、実際に作ったんですが普通に print_r() すればコンソールに出力されるんですよねー。「そりゃそうだ」と後で気づいたわけで。

      CakePHP のシェルでは $this->out() でコンソールへの出力をすることになってますが、開発中にしか使わないし print_r() をそのまま使えばいいかなと。親クラスは機能の集約に役立ってます。

      Facebooktwitterlinkedintumblrmail

      OSC 2011 Kansai@KOBE セミナー前説

      オープンソースカンファレンス 2011 Kansai@KOBEで
      「OpenCOBOLとPerlを使った汎用機ダウンサイジング」
      というセミナーを、弊社、峰松がやります。

      私も行くので軽い内容の前説をやることにしました。

      この土日で前説用のスライドを作ったのですが、
      ネタに走ったので後でスライドを公開するという
      わけにもいかない内容になってしまいました。

      見に来て欲しいなぁ。

      4/16(土)です。よろしくお願いします。

      ※ただし、一部にしか刺さらないネタです。

      Facebooktwitterlinkedintumblrmail

      OSC北海道、設営完了。開場待ち。

      設営完了しました。

      昨日は会場の場所を下見してホテルまであるいてみたら1時間
      かかったりしましたが、タクシーだと一瞬だったぜ!(言い過ぎ)。

      設営完了して油断してる代表を激写。
      OSC北海道、設営完了

      Facebooktwitterlinkedintumblrmail

      OSC北海道に向けて出発!

      の準備中です。私は着替えるだけですけども。

      隣の部屋ではmine氏がギリギリまでスライドを作っていたようです。
      午前3時とかにつぶやいてましたし、@minemaz。

      今回のセミナーは前回の神戸よりも技術寄りな内容になります。
      https://www.ospn.jp/osc2011-do/modules/eguide/event.php?eid=23

      ブースには仮想プリンタの出力見本なども用意しています。
      のぞきにきてくださいね。

      それではいってきます(の前に服着ないと)。

      Facebooktwitterlinkedintumblrmail

      munin-node-win32でWindowsのリソース監視

      「パソコンがなんか遅いんだよ」的なお客様のご不満。

      弊社はデータベースサーバー側のチューニング等を行っているのですが状況を聞いてみると「プログラムの起動が遅い」といった話で、どうもクライアント側の問題かもなぁといった感じ。どうも他社のシステム(しかも画像絡み)が同時に動いているらしいのでそちらにリソースを取られているんじゃないかと想像。

      しかし、想像にすぎないのでどうにか確かめられないかと考えていたらmineさんは言いました。

      「そのパソコンにSNMPd設置するとか」

      MRTGで監視しようってことです。

      それで閃いた(といいますか、なぜそれまで思いつかなかったのか)。

      そのお客様のところのデータベースサーバーとファイルサーバーはMuninで監視してるわけで

      「Windows用のmunin-nodeがあれば監視できるじゃない」

      ありました。munin-node-win32

      http://sourceforge.net/projects/munin-nodewin32/

      現在はお客様のパソコンへの投入前のテストをやっているのですが、バッチリです。

      引っかかったところは2つ

      1. zip解凍して実行ファイルmunin-node.exeをダブルクリックして「あれ?」
      2. 「メモリのグラフが出来ないなぁ」

      一つ目はマニュアルをちゃんと読めってことで。
      サービスとしてインストールするには次のようにします。

      > munin-node.exe -install
      

      逆にサービスから削除するときには -uninstall オプション。

      二つ目のメモリのグラフについては偉大な先人がいらっしゃいました。

      munin-node-win32でメモリーのグラフが出ない問題 « こにやnのぶろぐ

      munin(cronで起動されてグラフを作成してる方)の設定(munin.conf)内の対象Windows機のmunin-nodeに関する所には次のようにmemoryに関する記述の追加が必要ってことですね。

      [TargetPC] #Windows PC
      address xxx.xxx.xxx.xxx #IP Address
      memory.swap.label swap
      memory.swap.draw STACK
      memory.swap.info Swap memory used.
      

      ありがてぇ。ありがてぇ。

      Facebooktwitterlinkedintumblrmail

      とある休日のうどん打ち

      ふと思い立ってひさしぶりにうどんを打ってみました。 ヘタになってた。

      季節で加水率を変えたほうがいいのですが(寒い時期は増やして暖かい時期は減らす。たぶん)、私は次のレシピで固定してます。

      • 小麦粉 200 g
      • 水 90 g
      • 塩 10 g

       

      おぼえやすいでしょ? これで3食〜2食分です。

      小麦粉は今回、うどんづくりではスタンダードな中力粉を使ってますが薄力粉でもいいと思います。作ってすぐ食べたいときなんかは薄力粉がお勧めです。今回も薄力粉のほうがよかったんだけどね。

      分量をちゃんと計れば勝ったも同然! 小麦粉料理にデジタルキッチンスケールは必須です。

       

      水には塩を溶きます。電子レンジで少しあたためてぬるま湯位にするとやりやすいです。

       

      まず、水回し。少しずつ塩入りぬるま湯を加えながら全体に馴染ませます。私は箸をつかってやってます(ここらへん、『ウー・ウェンの北京小麦粉料理』という本を参考にしてます。小麦粉料理やるなら持っといて損はない本です。中華料理の本なのでうどんは載ってませんが)。

      こんな感じになります。

      この状態からコネていきます。ある程度までコネたらラップでもして寝かしてから(30分以上推奨)再度コネると良いです。

      薄力粉の場合は寝かしなしでOK。

      今回、中力粉でやってるのに早く食べたくて寝かしを10分弱で切り上げてしまいました(起きてすぐに朝飯用に作ってたんだもの)。

      その結果がこの熟成と練が足りてない小麦粉の塊だよ!

       

      普通は表面がなめらかになるまでコネますが、腹へってたのでこの状態で延ばして切っちゃったのでした。

      打ち粉して延ばして、ほどよいところまで延びたらさらに打ち粉して折りたたたんで切ります(苦手です。とくに延ばすのが。均等に出来ずに端がうすくなっちゃう)。

      打ち粉は片栗粉を使いました。なかったら小麦粉でもいいのですが片栗粉のほうが扱いやすい気がします。

       

      一食分は切ったので茹でます(朝食用)。

      お湯はなるべく多めが良いです。写真の状態だとギリって感じ。

      吹きこぼれないように気をつけつつ麺が自然に回る火加減で10分位。

      鍋から揚げたての麺です。表面がぬるぬるしてます。このまま卵にぶち込んで釜玉もいいですね。

      水で数回ゴシゴシと洗ってあげるとツルンツルンになります。

      ここまで撮影したりしつつボチボチやって1時間弱です。 ね? 簡単でしょ?

       

      すぐに食べたいときには薄力粉で寝かしなしで全力で作れば30分位で食べるところまでいけます。

       

      朝食は出汁醤油と鰹節をかけていただきました。今回、ひどい手抜きでしたがちゃんと美味しい。

       

      残りは昼にカレーうどんにして食べました。 前日のカレーの残りでカレーうどんを作りたくて打ったんだ。実は。

       

      麺が残ったら茹でる前の切った状態で密閉して冷凍しとくと良いです。乾麺ほどじゃないですが、かなりもちます。

       

      Facebooktwitterlinkedintumblrmail

      CakePHPのRouter::normalizeにヤラれる

      あるいは認証後に存在しないsコントローラーに飛ばされてエラーになる件。

      1.3.6での話なのですが、例えば

      http://lancard.com/hoge/

      というCakePHPで構築したサイトがあってAuthで認証を行っているとします。
      そこにhogesコントローラーがあったとしましょう。そのindexアクション

      http://lancard.com/hoge/hoges/

      で認証切れすると戻り先のUrlとしてAuth.redirectセッションに/hogesが
      保持されるのですが、この状態で認証して再ログインすると

      http://lancard.com/hoge/s

      に飛ばされる不思議現象。 犯人はRouter::normalize。

      リダイレクト処理時にRouter::normalizeで前処理されるのですがその中に

      if (!empty($paths['base']) && stristr($url, $paths['base'])) {
          $url = preg_replace('/^' . preg_quote($paths['base'], '/') . '/', '', $url, 1);
      }
      

      というコードがあって、結果、Router::normalize('/hoges')は/sを返しやがります。

      if (!empty($paths['base']) && stristr($url, $paths['base'] . '/')) {
          $url = preg_replace('/^' . preg_quote($paths['base'], '/') . '/', '', $url, 1);
      }
      

      と改造して$paths['base']の後ろに/がある時だけ置換するようにして対処しました。
      悪影響がないことを祈りつつ。

      なるべくならフレームワークに手を入れるのは避けたいところ。いい手があったら教えてください。

      Facebooktwitterlinkedintumblrmail

      VB.NETのMy.Application.Logをラッピングしたクラス作ってみた

      現在進めているプロジェクトでのロギングにはmiyazakiさんに調べてもらったMy.Application.Logを使うことにしました。

      が、そのままだとちょいと辛かったのでラッピングしてクラスを作ってみました。

      Public Class Log
          Public Shared Sub Write(
              ByVal message As String,
              ByVal traceEventType As String,
              Optional ByVal isShowMsgBox As Boolean = False
          )
              Dim severity As System.Diagnostics.TraceEventType =
                  System.Enum.Parse(GetType(System.Diagnostics.TraceEventType), traceEventType)
      
              My.Application.Log.WriteEntry(My.Computer.Clock.LocalTime.ToString & "> " & message, severity)
              My.Application.Log.TraceSource.Flush()
              '下記表示判定は何パターンか試した結果ですが正しいかの確認は出来ていません。
              If My.Application.Log.TraceSource.Switch.Level > severity Then
                  showMsgBox(message, severity, traceEventType, isShowMsgBox)
              End If
          End Sub
      
          Private Shared Sub showMsgBox(
              ByVal message As String,
              ByVal severity As System.Diagnostics.TraceEventType,
              ByVal title As String,
              Optional ByVal isShowMsgBox As Boolean = False
          )
              If isShowMsgBox Then
                  Dim msgBoxButtons As MsgBoxStyle
                  Select Case severity
                      Case Diagnostics.TraceEventType.Critical, Diagnostics.TraceEventType.Error
                          msgBoxButtons = MsgBoxStyle.Critical
                      Case Diagnostics.TraceEventType.Warning
                          msgBoxButtons = MsgBoxStyle.Exclamation
                      Case Else
                          msgBoxButtons = MsgBoxStyle.Information
                  End Select
                  MsgBox(message, msgBoxButtons, title)
              End If
          End Sub
      
          Public Shared Sub Verbose(
              ByVal message As String,
              Optional ByVal isShowMsgBox As Boolean = False
          )
              Log.Write(message, "Verbose", isShowMsgBox)
          End Sub
      
          Public Shared Sub Info(
              ByVal message As String,
              Optional ByVal isShowMsgBox As Boolean = False
          )
              Log.Write(message, "Information", isShowMsgBox)
          End Sub
      
          Public Shared Sub Warn(
              ByVal message As String,
              Optional ByVal isShowMsgBox As Boolean = False
          )
              Log.Write(message, "Warning", isShowMsgBox)
          End Sub
      
          Public Shared Sub Err(
              ByVal message As String,
              Optional ByVal isShowMsgBox As Boolean = False
          )
              Log.Write(message, "Error", isShowMsgBox)
          End Sub
      
          Public Shared Sub Exception(
              ByVal ex As Exception,
              ByVal message As String,
              Optional ByVal isShowMsgBox As Boolean = False
          )
              message &= System.Environment.NewLine &
                  " [例外内容] " & ex.Message & System.Environment.NewLine &
                  " [スタックトレース] " & System.Environment.NewLine & ex.StackTrace
              Log.Err(message, isShowMsgBox)
          End Sub
      End Class
      

      Verboseがlog4netのDebugにあたる感じで使えると思います。
      メッセージボックスを表示したりも出来ます。

      My.Application.Log.には例外用のメソッドWriteExceptionがあるのですが出力される情報がイマイチだったので使わないで実装しました。

      まだあまり使ってないのでバグってたりするかもしれません。
      コードを修正したらここも修正するということで。

      Facebooktwitterlinkedintumblrmail