はてなブックマーク - PostgreSQLのログをデバッグに活用しよう
    このエントリーをはてなブックマークに追加

    はじめての人もそうでない人もはじめまして。河野と申します。

    Advent Calendar も中頃、私は3回目に突入しました。

    さて、本日は「PostgreSQLのログをデバッグに活用しよう」というお話を皆様にしたいと思います。

    ログを見る前に

    さっそくログを見ていきたいところですが、まずはログの出力が行われているか確認します。
    ログの出力先はOSやサーバによって違うかと思いますが、今回は以下のように設定されているものとします。

    postgresql.conf

    
    #log_destination = 'stderr'
    redirect_stderr = on
    log_directory = 'pg_log'
    log_filename = 'postgresql-%a.log'
    log_truncate_on_rotation = on
    log_rotation_age = 1440
    log_rotation_size = 0
    
    

    ざっくり言うと…

    標準出力にログを吐き出し、吐き出されたログは pg_log 以下の postgresql-曜日.log へ保存。
    ログは 1日ごとにローテーションするという設定です。

    ざっくりすぎま…せんよね?

    ちなみに「log_destination」を syslog に設定することで syslog を利用する事が可能ですが、メッセージの一部が syslog では出力されない可能性があるため信頼性は高くありません。

    Linux であれば基本的に「log_destination」を stderr に。
    「redirect_stderr」を on に設定して PostgreSQL にログローテーションまで任せましょう。

    何を出力するか

    さっそくログを見ていきたいところですが、まずは何を出力するか設定します。
    デバッグに役立つ設定値をかいつまんで、紹介差し上げたいと思います。

    ● エラーのSQLを記録

    SQLにエラーが発生した場合、エラーとなったSQLをログに出力したい時、以下の設定を error に設定することでログに保存できます。
    開発中やテスト時には error に設定を変更する事をおすすめします。

    私のサーバではデフォルトで panic となっていました。
    これはエラー時もログを出力しない設定となります。

    
    #log_min_error_statement = panic
    
    

    ● 時間のかかるSQLを記録

    複雑なSQLやインデックスの貼り忘れ、テーブルの結合など、色々な条件が原因でレスポンスがなかなか帰って来ないことがあります。
    その原因となったSQLを知りたい場合は「log_min_duration_statement」の設定をしましょう。

    デフォルトでは -1 無効となっています。
    ここの設定値はミリ秒単位ですので30秒ならば 30000 と設定しましょう。

    
    #log_min_duration_statement = -1
    
    

    データが少ない開発時より、運用されてからこの設定が生きてくることもあるかと思います。

    ● クライアントからの接続・切断を記録

    ひとつのデータベースを複数のアプリケーションで参照する場合、以下の設定を行っておくと接続元のIPが記録されるため、どこからの接続が多いかがログから判断できます。

    デフォルトでは off となっています。
    有効にする場合は on に設定してください。

    
    #log_connections = off
    #log_disconnections = off
    
    

    もし PostgreSQL の最大接続数に達するほど接続数が増えている場合は、安易に max_connections を増やさずにログを見てから判断しましょう。

    ● すべてのSQLを記録する

    とにかく全てのSQLを記録したい。
    レガシーなプログラムのデバッグでは有用になってくるかもしれない設定です。

    そのようなプログラムのデバッグをせねばならない状況…お察しします。
    この設定値で頑張ってください!

    デフォルトでは none となっています。
    全て出力したい場合は all と設定してください。

    
    #log_statement = 'none'
    
    

    PostgreSQLのログをデバッグに活用しよう

    いかがでしたでしょうか?
    データベース設計や運用・保守はメインではない(とお考えの)開発者ですとデータベースのログを見ることはあまり無いのではと思います。
    とくに最近のフレームワークはいい具合にSQLのログなどを出力してくれる為、開発中は見なかったなんて方もいるかも…。

    ログは運用されてから発生してくる問題の原因究明にこそ役立ちます(だから開発中見なかったはダメw)

    さて、ログの設定は終わりましたか?
    では、さっそくログを見ていきましょう!

      はてなブックマーク - PHPExcelとReviserの比較(前編)
      このエントリーをはてなブックマークに追加

      好きな元素はイッテルビウム(元素記号:Yb)
      ・・・という設定になっているらしい1年目の新人、萩原です。よろしくお願いします。
      大学院では化学を専攻しておりました。

      今回アドベントカレンダーということで順番が回ってきましたのでExcelについて触れていこうと思います。

      普段、CakePHPを使って仕事をしているのですが、その中でPHPでエクセルを出力すると言う場面によく出くわします。

      弊社ではExcelの出力には、基本的にReviserを使用しているのですが、たまたまPHPexcelを使う機会もありましたので、今回、これら二つのPHP用のExcel出力機能について比較を行っていきたいと思います。

      両者ともに、基本的にPHP5.2以上対応となっています。

      PHP5.1でも使用することは可能ですが、PHPExcelの場合はExcel2007形式(.xlsx)の出力ができません。(体験済)
      Reviserに至っては現在最新の0.33は動きません。(体験済)
      私の開発環境(PHP5.1.6、CentOS5.5)では0.24であれば動くことを確認しています。

      まぁそういった制限された環境で比較をしても仕方ないので、今回、勉強という意味も含めてPHP5.3.3を使用して比較を行いました。

      機能の比較

      機能において、PHPExcelとReviserの両者の一番大きな差は扱えるExcelの種類です。
      PHPExcelはExcel2007(.xlsx)形式に対応しています。Excel5形式(.xls)形式も扱うことは可能ですが、こちらの方は色などに少々バグがあります。(体験済)
      Reviserは.xlsx形式を扱うことはできません。.xlsのみの対応となっています。

      数式については現在両方とも扱うことが可能です。
      しかし、古いReviserを使用すると数式が扱えないものがあるので注意が必要です。
      (上記に示した0.24は数式に対応していません。)

      色や罫線も両方とも使用が可能ですが、使い方は大きく異なります。
      PHPExcelは直接指定のセルに色や罫線を引くことが可能です。
      一方、Reviserですが、直接指定をすることはできません。
      かわりに指定したセルから情報をコピーして使用します。
      指定したセル部分は後で削除することができるので、PHPExcelと出来ることは同等ということになります。

      その他の特徴はPHPExcelはテンプレートのファイルがなくても出力をすることが可能ですが、Reviserはテンプレートファイルがないと出力することができません。

      両者ともできないことはマクロの作成、出力です。
      テンプレートファイルにマクロが含まれていた場合、私が見た限りだと、PHPExcelはマクロの後らしきものが一応出力されますが、クリック等しても反応しません。

      Reviserの場合はマクロ自体が完全に削除される形になります。

      ソースの書き方はPHPExcelよりReviserの方が簡単に書くことができます。

      書き方の一例

      PHPexcel

      ini_set("memory_limit" , -1);
      set_time_limit(0);
      $this->layout = false;
      Configure::write('debug', 0);
      // 必要なクラスをインクルードする
      set_include_path(get_include_path() . PATH_SEPARATOR . "./Classes/");
      include APP . "vendors/phpexcel/Classes/PHPExcel.php";
      include APP . "vendors/phpexcel/Classes/PHPExcel/IOFactory.php";
      // PHPExcelオブジェクトを生成する
      $objReader = PHPExcel_IOFactory::createReader("Excel2007");
      $objPHPExcel = $objReader->load(APP . "vendors/templates/templete.xlsx");
      $objPHPExcel->setActiveSheetIndex(0);
      $sheet = $objPHPExcel->getActiveSheet();
      //シート名
      $sheet->setTitle('sheet_name');
      //セルA2に文章入力
      $sheet->setCellValueByColumnAndRow(0, 1, 'PHPExcel');
      //セルに罫線を引く
      $sheet->getStyleByColumnAndRow(0, 1)->getBorders()->getTop()->setBorderStyle(
      PHPExcel_Style_Border::BORDER_THIN);
      $sheet->getStyleByColumnAndRow(1, 1)->getBorders()->getLeft()->setBorderStyle(
      PHPExcel_Style_Border::BORDER_MEDIUM);
      //背景色の指定
      $sheet->getStyleByColumnAndRow(0, 1)->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
      $sheet->getStyleByColumnAndRow(0, 1)->getFill()->getStartColor()->setRGB('336699');
      $target_filepath = TMP . "PHPExcel.xlsx"; //ファイル名生成
      $file_name = "PHPExcel.xlsx";
      $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007");
      //ファイルの保存
      $objWriter->save($target_filepath);
      $media_id = basename($file_name);
      //保存したファイルの出力
      $file = TMP . $media_id;
      $file_length = filesize($file);
      header("Content-Disposition: attachment; filename=$media_id");
      header("Content-Length:$file_length");
      header("Content-Type: application/octet-stream");
      readfile ($file);

      Reviser

      Configure::write('debug', 0);
      $this->layout = false;
      ini_set("memory_limit" , -1);
      set_time_limit(0);
      App::import('Vendor', 'reviser/reviser');
      $reviser = new Excel_Reviser();
      $reviser->setInternalCharset('utf-8');
      //1枚目のA1のセルデータを読み込んで1枚目のB1に文字を入力
      //引数7つは前から順にシート番号、縦(数字)、横(英語),入力文字,コピーするセルの縦(数字)、横(英語),シート番号
      $reviser->addString(0,0,1,'reviser',0,0,0);
      //1枚目のA1のセルデータを読み込んで1枚目のB3に数字を入力
      $reviser->addNumber(0,0,2,3,0,0,0);
      //1枚目のB4に数式を入力
      $reviser->addFormula(0,0,3,'A2+A3');
      $readfile = APP . 'vendors/templates/templete.xls';
      $outFile = 'reviser.xls';
      // 出力
      $reviser->reviseFile($readfile, $outFile);

      まぁ実際のところ、PHPExcelはそのままでは書くのが煩わしくなってくるので私はコンポーネントにして使用しました。
      reviserはそのままでも十分簡潔に書くことができると思います。

      ここまで機能について簡単にまとめてきました。
      機能についてみるとReviserも十分使用に耐えうるものはもっていますが、ReviserにできてPHPExcelにできないことはおそらくほとんどないと思われます。
      単純にExcel2007が使えるかどうかだけでも使用可能な関数などに差があります。

      長くなってきたので続きは次回に。

      最後に役に立たない化学豆知識を。

      今年正式に名前が発表されたコペルニシウム(Cn)という元素。
      原子番号は112番なのですが、この金属、実は常温で液体だと言われています。
      他に常温で液体の金属は水銀のみです。
      また、原子番号が100を超えるような元素は基本的に半減期が数秒程度のものがほとんどなのですが、Cnは半減期が数分程度という実験結果も出ています。

      それでは

        はてなブックマーク - CakePHPのdebug_kitに定数やサーバ変数を表示するパネルを追加
        このエントリーをはてなブックマークに追加

        こんにちは。モンハン3rdで早く上位に行きたい、Fusicサクこと桜川です。
        2回目の登場になります。よろしくお願いします。

        モンハンの内容をブログに書きたいところですが技術の内容を書けと怒られそうですので、ここはぐっと我慢をして本日はCakePHPについて書かせて頂きたいと思います。

        さて、本日の内容は「debug_kitに定数やサーバ変数を表示するパネルを追加」するプラグイン「debug_kit_settings」を作成しましたので、そちらをご紹介させて頂きます。

        作成した経緯

        CakePHPを使っているときwebrootディレクトリまでのパスを取得したい場合「WWW_ROOT」定数を使用すると思うのですが、みなさんはふと忘れてしまうことはないでしょうか?

        自分はよく忘れます。。。

        しかも、APP_DIR?WWW_ROOT?APP?どれだったけ?と似たような名前でどこへのパスなのかがわからなくなることもしょっちゅうあります。

        というわけで物覚えの悪い自分の為に、定数等を表示するdebug_kitのパネルがdebug_kit_settingsになります。
        あと、単純にsymfonyに定数を表示する機能があるのにCakeに内のはなんか悔しい気がするからです。

        機能

        debug_kit_settingsが表示できる機能は以下の4つになります。

         1.Defines
           CakePHPとPHPそれぞれの定数を表示します。(検索機能あり)
         2.Servers
           $_SERVERの値を表示します。(検索機能あり)
         3.Extensions
           読み込まれているExtensionの一覧を表示します。
         4.Database
           現在接続されているデータベースの情報を表示します。

        使い方

        kozo’s debug_kit_setting at master – GitHub -

         1.GitHubでソースは公開していますので、ダウンロードしてください。
         2.「app/plugins/debug_kit_setting」となるように配置してください。
         3.app_controller.phpで以下のようにdebug_kit_settingsをパネルとして読み込んでください。

         4.完成
          image

         あら簡単♪
         これで、もう定数や$_SERVERに迷うことがありません!

        おまけ

        debug_kit_settingsのDefinesServersには、表示される数が多いのでjavascriptで検索機能を追加しています。
        この機能は弊社javascript部隊の一人島田が前回ご紹介しました、jquery.simplesearch.jsの機能を使い追加してくれました。
        ですので、javascript関連でバグがでた場合は私ではなく弊社島田へバグってるぞ!!とご連絡ください。
        よろしくお願い致します。

        では、また次回お会いしましょう。
        さよ~なら~