Skip to main content

herokuで作るお手軽データ分析基盤

· 5 min read

image-20220320131919980

PDF作成時のトランザクションデータを分析用データとしてherokuのpostgresに送信するようにして、それをデータ分析に利用する


なぜやるか

PLG プロダクト・レッド・グロース #102 を読んでやろうと思った。

このサービスのバリューメトリクスはPDFをダウンロードできるということなのでPDFダウンロードなのでそのデータをもっと深掘りして分析したり、監視する必要がある。

実は、もともとGASで運用している。データ分析用のデータを貯める場所があるのだが、流石に限界がきた。 まず、ファイルがバカ重いし、SQLが書けないという点で分析しにくい。

もっとSQL使って集計とかしたいのでGAS運用から乗り換えたい。 そうすれば

  • 人気のテンプレート
  • どの経路からPDFがダウンロードされているか

などがわかりやすくなるはず。


どうやるか

herokuにpostgresを立ててそこにデータを入れていく。 herokuにした理由は月9$くらいで運用できそうなので値段もわかりやすいし、Heroku Dataclipsを使えばデータの見える化が楽そうだと思ったから。

元々redashを入れようかと思っていたけど、サーバー立てたりが面倒なのでHerokuならDBも分析もできるから楽そうだという理由。

postgresの立て方、接続は適当に済ませて。まずテーブルをつくる。

テーブル名: downloaded_pdfs
カラム:
id: SERIAL
user_id: VARCHAR(100)
plan: VARCHAR(100)
from: VARCHAR(100)
template_name: VARCHAR(100)
template_id: VARCHAR(100)
data: TEXT
data_length: SMALLINT
created_at: TIMESTAMP DEFAULT CURRENT_TIMESTAMP

こんな感じ?SQLはこんな感じ

CREATE TABLE downloaded_pdfs(
id SERIAL,
user_id VARCHAR(50),
plan VARCHAR(100),
create_from VARCHAR(100),
template_name VARCHAR(100),
template_id VARCHAR(100),
input_data TEXT,
input_length SMALLINT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

データを入れてみる

INSERT INTO downloaded_pdfs (user_id, plan, create_from, template_name, template_id, input_data, input_length) VALUES
('pkXf8hEtzvh28SEQEm0cPKApwNp2', 'free', 'base', 'レターパック', '7aba5640-ea8a-11ea-bd67-419dd69ca92e', '[{"a": "b"}]', 1);

とりあえず手動で入れることができたからサービスから挿入できる様にする。

https://github.com/brianc/node-postgres このライブラリが有名どころっぽいので利用する 動き的には冒頭に出ていたやつ。こんな感じ。

image-20220320131919980

import { Pool } from "pg";

const pool = new Pool({
connectionString:"postgres://...",
ssl: { rejectUnauthorized: false },
});
export const sendDownloadedPdfs = functions
.region("asia-northeast1")
.https.onRequest(async (request, response) => {
if (request.method === "OPTIONS") {
response.status(200).send("This is OPTIONS request");
return;
}
if (request.method !== "POST") {
response.status(500).send("This is not POST request");
return;
}

const body = JSON.parse(request.body);
const data = {
user_id: body.user_id,
plan: body.plan,
create_from: body.create_from,
template_name: body.template_name,
template_id: body.template_id,
input_data: body.input_data,
input_length: body.input_length,
};
const insertQuery = `INSERT INTO downloaded_pdfs (user_id, plan, create_from, template_name, template_id, input_data, input_length) VALUES
('${data.user_id}', '${data.plan}', '${data.create_from}', '${data.template_name}', '${data.template_id}', '${data.input_data}', ${data.input_length});`;

pool.query(insertQuery, (err) => {
if (err) {
response.set("Access-Control-Allow-Origin", "*");
response.status(500).send();
return;
}
response.set("Access-Control-Allow-Origin", "*");
response.status(200).send();
return;
});
});

こんな感じでデータを挿入する。 ssl: { rejectUnauthorized: false } を入れないと接続できなくてちょっと詰まった 個人情報データは扱いたくないのでマスキングするなりしてください。

とりあえず実装はできたので、デプロイしていく

  • GCP
  • Netlify

とりあえずdata clipsで確認はできた...!

CleanShot20220320at155433@2x

デプロイできたのでとりあえずデータを育てていく。しばし待つ。

dataclipsでいい感じにクエリが叩ける様になるまで少し待つ。

人気のテンプレートとか、有料会員がよく使うテンプレートとか、どこから作られているとかそういうのをもっと明確にできたらいいなと思う。

そのうち運用とか、いろいろ知見が得られる様なアクションをしていけたら続編書きます。