Lancard.com http://www.lancard.com/ Lancard.com 新着情報とスタッフブログのRSS(RSS 2.0) <![CDATA[弊社、峰松が Software Design 2017年3月号 (技術評論社) に『Webメーラーへのセキュア機能実装例』を寄稿しております]]> http://www.lancard.com/news/archives/59 Mon, 20 Feb 2017 12:00:00 +0900 http://www.lancard.com/news/archives/59 2017年2月18日発売の Software Design 2017年3月号 (技術評論社)

http://gihyo.jp/magazine/SD/archive/2017/201703


第3特集
どうなってる? なりすましメール対策
〜DKIMとホワイトリストによる安心の可視化〜

 

第3章 プログラマには何ができる『Webメーラーへのセキュア機能実装例』

 

を弊社、峰松が寄稿しております。ぜひ御覧ください。
 

]]>
2017年2月18日発売の Software Design 2017年3月号 (技術評論社)

http://gihyo.jp/magazine/SD/archive/2017/201703


第3特集
どうなってる? なりすましメール対策
〜DKIMとホワイトリストによる安心の可視化〜

 

第3章 プログラマには何ができる『Webメーラーへのセキュア機能実装例』

 

を弊社、峰松が寄稿しております。ぜひ御覧ください。
 

]]>
<![CDATA[Laravel 5.1 でログ出力、それから (ログメールドライバー動作不良対処、クエリ出力の調整)]]> http://www.lancard.com/blog/2017/02/01/laravel-5-1-%E3%81%A7%E3%83%AD%E3%82%B0%E5%87%BA%E5%8A%9B%E3%80%81%E3%81%9D%E3%82%8C%E3%81%8B%E3%82%89-%E3%83%AD%E3%82%B0%E3%83%A1%E3%83%BC%E3%83%AB%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90%E3%83%BC/ Wed, 01 Feb 2017 14:33:20 +0900 http://www.lancard.com/blog/?p=4691 おひさしぶりです。運用していたら結構変わったので、またこのネタです。

一応以前の記事へのリンクおいときます。

『Laravel 5.1 で実行ユーザー毎にログ出力』

『Laravel 5.1 でログ出力、その後 (出力レベル設定、クエリ出力)』

が、以前の記事の方法だとログメールドライバーが動作しないという問題が発生したので参考にしちゃだめ。

というわけで、以下の要件と不具合対処のために改修した内容を紹介します。

  • ログファイルの権限絡みのエラー回避、何処から起動された処理かわかりやすくする等の目的で実行ユーザー名ベースでログファイルを作成。
  • 動作環境(local, testing, production等のenvironment)でもログファイルを分ける。
  • バッチ処理やartisanのコマンド実行の場合はARTISAN_BINARYをログファイル名に挿入してWebアクセスとはログファイルを分ける。
  • デバッグフラグ(app.debug)を落とした状態ではINFO以上のログのみ出力。
  • .envでAPP_QUERY_LOGGINGにtrueを設定したら発行されたクエリをinfoログで専用ログファイルに出力(デバッグフラグでのコントロールを廃止し個別にコントロール可能とし、ファイルも分けた)
  • 以前の実装ではログメールドライバー(メール送信内容をログ出力するドライバ)が正常動作しなかったためLoggerインスタンスを差し替える方法から既存Loggerインスタンスのhandlerを差し替える方法に実装を変更。

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        //登録されたloggerのhandlerを置き換える
        $monolog = \Log::getMonolog();
        $monolog->popHandler(); //既存のhandlerを削除
        $monolog->pushHandler(
                    (new \Monolog\Handler\RotatingFileHandler(
                        $this->app->storagePath() . '/logs/' 
                            . $this->app->environment() . '_'
                            . (defined('ARTISAN_BINARY') ? ARTISAN_BINARY . '_' : '')
                            . posix_getpwuid(posix_geteuid())['name'] 
                            . '.log',
                        \Config::get('app.log_max_files', 5),
                        (\Config::get('app.debug') || $this->app->environment('testing')) 
                            ? \Monolog\Logger::DEBUG 
                            : \Monolog\Logger::INFO //出力レベル制御のため追加
                    ))
                    ->setFormatter(new \Monolog\Formatter\LineFormatter(null, null, true))
                );
        $monolog->pushProcessor(
                    new \Monolog\Processor\IntrospectionProcessor(
                        \Monolog\Logger::NOTICE,    //DEBUG,INFOは発生場所の情報を付加しない
                        [
                            'Illuminate\\',
                            //他、呼び出し元としてはスキップしたい対象を設定,
                        ]
                    )
                );

        //.envのAPP_QUERY_LOGGINGがtrueの場合クエリを独自ログquery_{実行アカウント}.logに出力する。
        if(env('APP_QUERY_LOGGING', false)) {
            \DB::listen(function($query, $bindings, $time){
                $queryLogger = (new \Monolog\Logger(
                    $this->app->environment()
                ))->pushHandler(
                    new \Monolog\Handler\StreamHandler (
                        $this->app->storagePath() . '/logs/query_' . posix_getpwuid(posix_geteuid())['name'] . '.log')
                );

                $queryLogger->info('QUERY:[' . $query . '] BINDINGS:'
                        . json_encode($bindings), ['TIME' => $time]);
            });
        }
// 以下略

クエリ出力については他のログに混ざると見にくくなる、デバッグフラグに連動させていると本番環境での調査で使えない、クエリ出力のログファイルは日付でローテーションさせるより同じファイル名のログファイル一本に出力されるほうが扱いやすい(消して良いものだし)、ということで今の形におさまりました。

ログファイル名に関して、例えばnginxユーザーがphpunitを回したときなど testing_artisan_nginx-2017-01-31.log みたいになるので「なげぇな〜」とは思いますが、場合によってログファイルが別れているのは便利ですよ。

Facebooktwittergoogle_pluslinkedintumblrmail]]>
<![CDATA[CentOS7のPostgreSQL9.2で全文検索]]> http://www.lancard.com/blog/2017/01/27/centos7%E3%81%AEpostgresql9-2%E3%81%A7%E5%85%A8%E6%96%87%E6%A4%9C%E7%B4%A2/ Fri, 27 Jan 2017 12:04:21 +0900 http://www.lancard.com/blog/?p=4682 PostgreSQLの全文検索でLudia, textsearch_sennaを使っていたのですが、9.2ではどちらも使えないので、代替となりそうなものを探した結果、pg_trgm, pg_bigm, textsearch_jaの三つが使えそうでした。
ただpg_trgmは日本語を使うにはソースからのコンパイルが必要で、しかも二文字以下は使えないのでパスしました。

textsearch_ja

textsearch_jaはtsvectorの拡張のようです。

とりあえずtextsearch_jaをインストールしてみます。
gcc-c++とかが必要らしいので事前にインストールしておきました。

まずはmecab。
http://taku910.github.io/mecab/#download
mecab本体とipa辞書をダウンロード。
PostgreSQLの文字コードはデフォルトUTF-8なのでconfigureオプションには、

--with-charset=utf8

をどちらも追加しないと駄目でした。
その後、/etc/ld.so.conf.d/mecab.confを作成して以下一行を追加。

/usr/local/lib

この後ldconfigを実施します。

次にtextsearch_ja本体
http://textsearch-ja.projects.pgfoundry.org/textsearch_ja.html

tar xzf textsearch_ja-9.0.0.tar.gz
cd textsearch_ja-9.0.0/
make USE_PGXS=1
make USE_PGXS=1 install

/usr/share/pgsql/contrib/textsearch_ja.sql はそのまま実行すると駄目で、’C’を小文字に直すか、クォートを外す必要が有りました。

psql [database] -f /usr/share/pgsql/contrib/textsearch_ja.sql
psql [database]
 CREATE INDEX test_tb_content ON test_tb USING gin(to_tsvector('japanese', content));

実行結果

EXPLAIN SELECT * FROM test_tb WHERE to_tsvector('japanese', content) @@ to_tsquery('japanese', '猫');
                                       QUERY PLAN                                       
----------------------------------------------------------------------------------------
 Bitmap Heap Scan on test_tb  (cost=19.65..1470.66 rows=471 width=529)
   Recheck Cond: (to_tsvector('japanese'::regconfig, content) @@ '''猫'''::tsquery)
   ->  Bitmap Index Scan on test_tb_content  (cost=0.00..19.53 rows=471 width=0)
         Index Cond: (to_tsvector('japanese'::regconfig, content) @@ '''猫'''::tsquery)
(4 行)

pg_bigm

pg_bigmはpg_trgmの拡張のようです。

http://pgbigm.osdn.jp/pg_bigm-1-2.html#install

PostgreSQLについてはrpm版を使うので省略。
またインストールにはpostgresql-develが必要なので事前にインストールしておきます。

CentOS6用のrpmが有りましたが、CentOS7のデフォルトのpostgresqlでは使えなかったのでダウンロードしてmakeします。
pg_configはデフォルトパスが通っているので、オプションは入れずに実行可能です。

tar xzf pg_bigm-1.2-20161011.tar.gz
cd pg_bigm-1.2-20161011/
make USE_PGXS=1
make USE_PGXS=1 install

スーパーユーザーでデータベースごとにextensionを追加します。

su - postgres
psql [database]
CREATE EXTENSION pg_bigm;

インデックスを追加して実行してみます。

CREATE INDEX test_tb_content_bigm ON test_tb USING gin (content gin_bigm_ops);
EXPLAIN SELECT * FROM test_tb WHERE content LIKE '%猫%';
                                      QUERY PLAN                                       
---------------------------------------------------------------------------------------
 Bitmap Heap Scan on test_tb  (cost=40.06..71.29 rows=8 width=529)
   Recheck Cond: (content ~~ '%猫%'::text)
   ->  Bitmap Index Scan on test_tb_content_bigm  (cost=0.00..40.06 rows=8 width=0)
         Index Cond: (content ~~ '%猫%'::text)
(4 行)

単純な結果としては、pg_bigmの方が有利なのかなといった感じでした。

Facebooktwittergoogle_pluslinkedintumblrmail]]>
<![CDATA[年末年始営業のご案内]]> http://www.lancard.com/news/archives/58 Wed, 28 Dec 2016 10:00:00 +0900 http://www.lancard.com/news/archives/58 誠に勝手ながら、弊社の年末年始の営業は、下記のとおりとさせていただきます。
皆様にはご迷惑をお掛けしますが、何卒ご容赦願います。
 
今年一年ご愛顧を賜りまして大変感謝申し上げますとともに、皆様のご多幸をお祈りいたします 。
 
年内営業   2016年12月28日 18:00まで
年始営業   2017年1月4日   9:00より
 
緊急のトラブルの際は対応いたしますのでご連絡ください。

 

]]>
誠に勝手ながら、弊社の年末年始の営業は、下記のとおりとさせていただきます。
皆様にはご迷惑をお掛けしますが、何卒ご容赦願います。
 
今年一年ご愛顧を賜りまして大変感謝申し上げますとともに、皆様のご多幸をお祈りいたします 。
 
年内営業   2016年12月28日 18:00まで
年始営業   2017年1月4日   9:00より
 
緊急のトラブルの際は対応いたしますのでご連絡ください。

 

]]>
<![CDATA[何故 git rebase は駄目で git pull –rebase はいいのか]]> http://www.lancard.com/blog/2016/11/07/git-rebase-and-pull-rebase/ Mon, 07 Nov 2016 09:12:22 +0900 http://www.lancard.com/blog/?p=4648 git pull –rebase は便利ですが、rebase と言えば git rebase、これが割と敬遠されがちな声を聞くので –rebase オプションなんて本当に使っていいのか心配になることもあるかと思います。

私も普段は便利に git pull –rebase していますが、ふと git rebase の解説記事をみかけると毎度不安になりこの二つの仕組みを調べてしまうので、いっそのことまとめてしまうことにしました。

git rebase

以下のような状態のリポジトリがあったとします。

git-rebase-flow-rebase1

一番上はリモートの master、下 2 つはローカルで master と作業用 branch です。例えばローカルでブランチを作成して作業し、それを master に rebase する前に pull したところ、リモートの master に更新があった場合等ですね。

この状態で master ブランチから rebase-branch に対し rebase を行ってしまうと以下のような状態になります。

git-rebase-flow-rebase2

ブランチでのコミットがリモートから取得したコミットより手前に挿入される為、リモートに既にあるコミットのハッシュが変わってしまいます。ローカルとリモートが一致しない為 push 出来ないのですが、ここでよく分からず曖昧に git push -f をやると末代まで恨まれることとなります。

これが一般的に git rebase が敬遠される理由でしょう。

git pull –rebase

では git pull –rebase とは一体何なのか。以下のような状況を考えます。

git-rebase-flow-pull-rebase1

登場人物は 2 人、リモートの master ブランチとローカルの master ブランチです。ローカル master にコミットがありますが、リモート master にその手前に反映されるコミットがある場合です。

git-rebase-flow-pull-rebase2

その状態から git pull –rebase するとこのようになります。リモートの更新がローカルのコミットの手前に反映され、ローカルのコミットのハッシュが変わってしまいました。

git-rebase-flow-pull-rebase3

しかしハッシュが変わったコミットはまだリモートに存在していません。なのでここで push してもコンフリクトは発生せず、問題にならないというわけです。

ここで –rebase オプションの何が便利かというと、マージコミットが発生しないことです。pull してコンフリクトしない場合というのは結構多いですが、通常はその際にもマージコミットは発生してしまいます(ローカルでのコミットが無い等で fast forward マージになる場合を除く)。複数人が開発するプロジェクトで、各個人のローカルリポジトリの pull 状況を残したマージコミットは大半の場合不要でしょう。

補足

git pull –rebase が危険なケース(多分少ない)

こういうことを書くと結局よく分からなくなるのでは…と思いつつ、簡潔に。リモートリポジトリを複数持つリポジトリでは注意が必要です。仕組みは git rebase の項のローカルリポジトリをリモートリポジトリに置き替えて考えると分かり易いです。登場人物が 3 人以上になると危険ですね。

但しこの場合も push しようとするとリジェクトされるので、push -f さえしなければとにかく安心と考えることも出来ます。

git pull –rebase がコンフリクトした場合

こういった場合は git rebase –abort 又は git reset –hard HEAD して、通常の git pull を行いマージコミットを作成してもいいかもしれません。コンフリクトした場合の rebase 操作がややこしいというのもありますが、「コンフリクトをどのように解消したかを明確に残す」という意味でマージコミットを作成する意義がある為です。

但し pull した場合の空のマージコミットがリポジトリに大量に含まれている場合、この意味のあるマージコミットが埋もれてしまいます。git pull –rebase 運用を徹底するか、コンフリクト解消のマージコミットはコミットメッセージを明確に記載する等の工夫をしましょう。


Facebooktwittergoogle_pluslinkedintumblrmail]]>