Skip to content

Instantly share code, notes, and snippets.

@AKB428
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AKB428/9e02b83a2bd18b1376ef to your computer and use it in GitHub Desktop.
Save AKB428/9e02b83a2bd18b1376ef to your computer and use it in GitHub Desktop.
[Mastering DMP] 05

#5章 データーベースにCookieを保存する

ブラウザからDMPサーバーへリクエストがあった場合、初期アクセスならCookieID発行、2回目以降のアクセスの場合はそのオーディエンスの過去のリクエストログから広告を出すのがCookieを利用したDMPの基本的な処理になります。

ここではリクエストのログをMariaDB(MySQL)に保存する方法について説明します。

application.conf設定

以下の記述を追加します

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/open_micro_dmp?characterEncoding=UTF8"
db.default.username=root
db.default.password=""

play.db.pool=bonecp

build.sbtの設定

MySQLのドライバを追加します

libraryDependencies ++= Seq(
  javaJdbc,
  cache,
  javaWs,
  "mysql" % "mysql-connector-java" % "5.1.35"
)

Playが起動中の場合は再起動します。

modelの作成

PlayにもORマッパーは用意されていますが、今回は素のJDBCを使用します。

app/models/Audience3rdAccessLog

package models;
import play.Logger;
import play.db.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.util.Date;

/**
 * Created by Siori on 15/07/06.
 */

public class Audience3rdAccessLog {
    /**
     * CREATE TABLE `audience_3rd_access_log` (
     `id` bigint(20) NOT NULL AUTO_INCREMENT,
     `audience_cookie_id` varchar(80) NOT NULL DEFAULT '',
     `access_host_name` varchar(255) NOT NULL DEFAULT '',
     `access_url` varchar(4096) NOT NULL DEFAULT '',
     `access_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     `is_first` tinyint(1) NOT NULL,
     `ip` varchar(15) DEFAULT NULL,
     `ua` varchar(255) DEFAULT NULL,
     `created_at` datetime NOT NULL,
     `updated_at` datetime NOT NULL,
     PRIMARY KEY (`id`),
     KEY `audience_cookie_id_index` (`audience_cookie_id`),
     KEY `access_host_name_index` (`access_host_name`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     */

    public Long id;
    public String audienceCookieId;
    public String accessHostName;
    public String accessUrl;
    public Date access_time;
    public int isFirst;
    public String ip;
    public String ua;
    public Date created_at;
    public Date updated_at;


    // https://www.playframework.com/documentation/2.4.x/JavaDatabase
    public static void create(Audience3rdAccessLog audience3rdAccessLog) {
        Connection connection = DB.getConnection();
        try {
            String query = "INSERT INTO audience_3rd_access_log " +
                    "(audience_cookie_id, access_host_name, access_url, access_time, is_first, ip, ua, created_at, updated_at) " +
                    "VALUES (?,?,?,?,?,?,?,?,?) ";

            PreparedStatement stmt = connection.prepareStatement(query);

            stmt.setString(1, audience3rdAccessLog.audienceCookieId);
            stmt.setString(2, audience3rdAccessLog.accessHostName);
            stmt.setString(3, audience3rdAccessLog.accessUrl);
            stmt.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
            stmt.setInt(5, audience3rdAccessLog.isFirst);
            stmt.setString(6, audience3rdAccessLog.ip);
            stmt.setString(7, audience3rdAccessLog.ua);
            stmt.setTimestamp(8, new Timestamp(System.currentTimeMillis()));
            stmt.setTimestamp(9, new Timestamp(System.currentTimeMillis()));
            stmt.executeUpdate();

            stmt.close();

            connection.close();
        }
        catch (Exception e) {
            Logger.debug(e.toString());
        }
    }
}

MicroDmpCore.java の修正

モデル生成しcreateメソッドを呼ぶメソッドを追加

    public static void saveAudience3rdAccessLog(String cookieId, boolean isFirst) {

        // http://nginx.org/en/docs/http/ngx_http_core_module.html
        // Embedded Variables
        Audience3rdAccessLog audience3rdAccessLog = new Audience3rdAccessLog();
        audience3rdAccessLog.audienceCookieId = cookieId;
        audience3rdAccessLog.isFirst = isFirst ? 1 : 0;
        audience3rdAccessLog.ua = request().getHeader("User-Agent");
        audience3rdAccessLog.ip = request().getHeader("X-Real-IP");
        audience3rdAccessLog.accessHostName = request().getHeader("Referer") != null ? url2Hostname(request().getHeader("Referer")) : "";
        audience3rdAccessLog.accessUrl = request().getHeader("Referer") != null ? request().getHeader("Referer") : "";

        Audience3rdAccessLog.create(audience3rdAccessLog);

    }

    public static String url2Hostname(String url) {
        String hostname = "";
        // FIXME 高速化する場合は自前で文字列を分解する
        try {
            URL urlObject = new URL(url);
            hostname =  urlObject.getHost();
        }
        catch (Exception e) {
            // TODO
            Logger.debug(e.toString());

        }
        return hostname;
    }

クッキーの生成ロジックのメソッドにログをDBに保存するメソッドを実行する処理を追加

    /**
     * CookieIDの処理を行う
     * CookieIDがあれば有効期限を更新
     * CookieIDがなければCokkieIDを発行し設定
     *
     * @return false=Cookie発行済み true=Cookie新規発行
     */
    private static void processingCookieId() {

        //name() まで呼ぶとnullpoになる
        if(request().cookie(COOKIE_ID_KEY) != null) {
            Http.Cookie cookie = request().cookie(COOKIE_ID_KEY);
            Logger.debug("Cookie Exist!");
            Logger.debug(cookie.value());
            response().setCookie(COOKIE_ID_KEY, cookie.value(), COOKIE_MAX_AFTER_AGE);

            saveAudience3rdAccessLog(cookie.value(), false);// <------------ 追加
            return;
        }
        // IDがなかったらID生成

        String id =  generateUniqueId();
        response().setCookie(COOKIE_ID_KEY, id, COOKIE_MAX_AFTER_AGE);
        saveAudience3rdAccessLog(id, true);// <---------- 追加
        return;
    }

nginx.conf の修正

オーディエンスのIPをフォワードします

nginx.dev_mdmp.conf

vi /usr/local/etc/nginx/nginx.dev_mdmp.conf

        location /1.gif {
            proxy_pass http://play-mdmp;
            proxy_set_header X-Real-IP $remote_addr;
        }

sudo nginx -c /usr/local/etc/nginx/nginx.dev_mdmp.conf -s reload

リクエストログのDB保存の確認

http://hotel.com/ にアクセスした後

実際にSQLでselectしDBにリクエストログが保存されているのを確認しましょう。

db

リクエストログがあればリクエストのログからオーディエンスの嗜好をたどることが可能になります。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment