analyticsを設計していく

初期画面

<?php

// $date1 = date("Y-m-d H:i:s", strtotime("- 6 day"));
$date1 = date("Y-m-d", strtotime("0 day"));
// $date2 = date("Y-m-d H:i:s", strtotime("- 1 day"));
$date2 = date("Y-m-d H:i:s");


$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$filter =  &#91;
	'date' => [ '$gte' => $date1, '$lte' => $date2]
];
$options = [
  'projection' => ['_id' => 0],
  'sort' => ['_id' => -1],
];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $mng->executeQuery('app.na007', $query);

foreach ($cursor as $document) {
  // var_dump($document);
  $pv[] = $document->date;
  $cookie[] = $document->cookie;
  $session[] = $document->session;
  if(!is_null($document->referrer)){
  $referrer[] = $document->referrer;
  }
}
// var_dump($session);
$uu = array_unique($cookie);
$session = array_unique($session);
$bounce = (count($pv) - count($referrer))/ count($pv) * 100;
$exit = (count($pv) - count($session))/ count($pv) * 100;
?>
<style>
.flex-container {
  display: flex;
}
.flex-1{
  flex:1;
}
.flex-2{
  flex:4;
}
</style>
<h1>アナリティクス</h1>
<div class="flex-container">
<div class="flex-1">
  <ul>
    <li><a href="">Audience</a></li>
    <li><a href="">Acuisition</a></li>
    <li><a href="">Behavior</a></li>
  </ul>
</div>
<div class="flex-2">


<?php
echo $date1 ." ~ ".$date2 ."<br>";
echo "<br>Users :".count($uu)."<br>";
echo "Pageviews :".count($pv)."<br>";
echo "Bounce rate :" .sprintf('%.2f',$bounce)."%<br>";
echo "Exit rate:" .sprintf('%.2f',$exit)."%<br>";
?>
</div>
</div>

必要項目
-average session duration
-時間別のユーザー数(折れ線グラフ)
-return userとnew user(円グラフ)

google analyticsのソースを見ると、json.parseして、jsに値を渡しています。

visualizationで、corechartというパッケージをloadしているように見えます。

// TODO(abdussabur): Lazily load gViz instead.
      // NOTE: Due to a conflict with galaxy's copy of gviz, the geochart does not work in GAFE4.
      // See cl/145118637 for more information.
      google.load('visualization', '1', {packages:['corechart', 'table']});
      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
      })(window,document,'script','https://www.google-analytics.com/analytics.js','gaAPI');

      // Tracking codes are being used in tracking-service.js . Please keep them in sync.
      gaAPI('create', 'UA-hoge', 'auto');
      gaAPI('create', 'UA-hoge', 'auto', {'name': 'ta'});
      gaAPI('create', 'UA-hoge', 'auto', {'name': 'tw'});

これのjsはなにしてるんだ?
https://ssl.gstatic.com/analytics/20180419-00/app/js/js.js

monoを使う

昔入れたmono、versionは4.8.0です。

[vagrant@localhost csharp]$ . /opt/mono/env.sh
[vagrant@localhost csharp]$ mono --version
Mono JIT compiler version 4.8.0 (Stable 4.8.0.495/e4a3cf3 Thu Feb 23 18:33:47 UTC 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          yes(3.6.0svn-mono-/)
        GC:            sgen

cs

using System;

class MyApp {

	static void Main(){
		Console.WriteLine("Hello World");
	}
}

compileはmcs

[vagrant@localhost csharp]$ mcs MyApp.cs
[vagrant@localhost csharp]$ ls
MyApp.cs  MyApp.exe
[vagrant@localhost csharp]$ mono MyApp.exe
Hello World
using System;

class MyApp {

	static void Main(){
		string msg = "Hello csharp";
		Console.WriteLine(msg);
	}
}

定数:const string msg = “Hello csharp”;

visual studio

inputとtodoが多すぎて混乱してきた。
1.mongo DBを使ってanalyticsをつくる
2.c# + visual studioでazure cosmosDBに接続する
3.c#でアプリケーションをつくって、azureで公開する

-> c#、visual studioは基本から学ばなければならないので、習得しながら疑似GAの完成までもっていくには恐らく時間がかかりすぎる
-> azure + c# は慣れるまではもっと簡単なテーマ・アプリケーションから作りたい
-> まずは analyticsは VPS + PHP + mongoDB + chart.jsで作り上げる

よし、これで行こう!

cyberduckでazure app serviceにftp接続する

(1)app serviceのデプロイ資格情報でname、passを入力する

(2)概要->発行プロファイルの取得 でpublish settingファイルを取得する

<publishProfile profileName="nanalytics - FTP" publishMethod="FTP" publishUrl="ftp://hoge.ftp.azurewebsites.windows.net/site/wwwroot" ftpPassiveMode="True" userName="hoge" userPWD="hogehoge" destinationAppUrl="http://nanalytics.azurewebsites.net" SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com" webSystem="WebSites"><databases /></publishProfile>

(3)ファイル転送ツール等で、サーバーは発行プロファイルのpublishUrl、ユーザー名はuserName、パスワードはuserPWDを入れる。ポートは21でOK

(4)webrootに接続完了! timezoneが-9H(GMT)になってますね。

azureでMongoDB\Driver\Managerの接続が上手くいかない

azureで、php・jsファイルは問題なく動くんだが、MongoDB\Driver\Managerが上手くいなかない。

恐らくapp serviceにphp mongodbのドライバーが入ってないからだと思うのだが(そう思いたい..)

app serviceにライブラリを入れる場合はどうするんでしょうか?
アクティビティログでは、Write DatabaseAccounts 失敗と表示されています。。。

stack overflowで他の方もいってますが、mongodbの接続tutorialはNode.js, .NET、Java、Go、Pythonしかないってところです。

あああ、なるほど、C# & visual studioだったら、簡単にドライバーを入れらるのですね。
ここでC#か~~~~
まぁ、C#でやってみるか~。。。。。。どう頑張ってもNGそうだったら、VPSで構築します。

mondoDBを使いたいのでcosmosDBを作成する

azure cloud shell

az cosmosdb create --name nacosmosdb --resource-group myResourceGroup --kind MongoDB

さーどうしましょう

{
  "additionalProperties": {},
  "capabilities": [],
  "consistencyPolicy": {
    "additionalProperties": {},
    "defaultConsistencyLevel": "Session",
    "maxIntervalInSeconds": 5,
    "maxStalenessPrefix": 100
  },
  "databaseAccountOfferType": "Standard",
  "documentEndpoint": "https://nacosmosdb.documents.azure.com:443/",
  "enableAutomaticFailover": false,
  "failoverPolicies": [
    {
      "additionalProperties": {},
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe"
    }
  ],
  "id": "/subscriptions/hoge/resourceGroups/myResourceGroup/providers/Microsoft.DocumentDB/databaseAccounts/nacosmosdb",
  "ipRangeFilter": "",
  "kind": "MongoDB",
  "location": "West Europe",
  "name": "nacosmosdb",
  "provisioningState": "Succeeded",
  "readLocations": [
    {
      "additionalProperties": {},
      "documentEndpoint": "https://nacosmosdb-westeurope.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe",
      "provisioningState": "Succeeded"
    }
  ],
  "resourceGroup": "myResourceGroup",
  "tags": {},
  "type": "Microsoft.DocumentDB/databaseAccounts",
  "writeLocations": [
    {
      "additionalProperties": {},
      "documentEndpoint": "https://nacosmosdb-westeurope.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe",
      "provisioningState": "Succeeded"
    }
  ]
}

primary master keyを発行する

az cosmosdb list-keys --name nacosmosdb --resource-group myResourceGroup --query "primaryMasterKey"

接続

'use strict';

module.exports = {
  db: {
    uri: 'mongodb://:@.documents.azure.com:10255/mean-dev?ssl=true&sslverifycertificate=false'
  }
};

ん?

node.jsが入っているのに、npmコマンドが使えない時

# node server.js
module.js:340
Cannot find module ‘lodash’

npm install lodash –save で、npmインストールしようとしたが、できない。

$ sudo yum groupinstall 'Development tools'
$ wget http://nodejs.org/dist/v0.12.0/node-v0.12.0.tar.gz
$ tar xvf node-v0.12.0.tar.gz
$ cd node-v0.12.0/
$ ./configure --prefix=/usr/local
$ make
$ sudo make install

ほぅ

AppServiceからAzure DatabaseにPDOでssl接続する

vagrant環境をmasterにpushするだけです。

$ git commit -am “azure mysql ssl pdo”
$ git push azure master

PDOもOK

次は、ドメインのマウント。
これが出来れば、一通りアプリケーションの公開まではOKになる(はず?)

あ、無料版のサブスクリプションでは購入できませんが、
ドメイン購入のマニュアル読むと、そんなに難しそうではなさそうですね。
https://docs.microsoft.com/ja-jp/azure/app-service/custom-dns-web-site-buydomains-web-app

ということで、一通りOKですね。
では、いよいよazureでmongoDBです。Let’s Go!

vagrantからPDOでazure mysqlにssl接続する

以下のURLから証明書を取得し、BaltimoreCyberTrustRoot.crt.pemで、vagrantに保存する。
https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt.pem

azure mysqlのadminで接続のセキュリティがSSLを強制する、となっているか確認する。

optionで、PDO::MYSQL_ATTR_SSL_CA => ‘BaltimoreCyberTrustRoot.crt.pem’ と書きます。

$dsn = "mysql:dbname=sier;host=namysql.database.windows.net";
$user = "hoge";
$password = "hogehoge";
$options = array(
  PDO::MYSQL_ATTR_SSL_CA => 'BaltimoreCyberTrustRoot.crt.pem' 
);
try {
    $dbh = new PDO($dsn, $user, $password, $options);
} catch (PDOException $e){
    print('connection failed:'.$e->getMessage());
} 

$sql = "select * from forein";
// $sql = "show status like 'ssl_cipher'";
$stmt = $dbh->query($sql);
 
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r('<pre>');
var_dump($result);
print_r('</pre>');

$sql = “show status like ‘ssl_cipher'”;と書くと、ssl通信の場合、[“Value”]=>string(10) “AES256-SHA” で返ってきます。

> .pemは、Base64で符号化された証明書です。.pem SSL サーバ証明書(連結SSLサーバ証明書)では複数のサーバ証明書を1ファイルに連結させることができ、SSLサーバ証明書のインストール用によく使われます。

いいね~
しかし、azure始めた途端、参照するブログ書いている方のレベルが高くなった気が。。。

では、続いてgit commit/pushしましょう。

auzreのmysqlからPDOでデータをselectする

$dsn = "mysql:dbname=sier;host=namysql.database.windows.net";
$user = "hoge@namysql";
$password = "hogehoge";
try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e){
    print('connection failed:'.$e->getMessage());
} 

$sql = "select * from forein";
$stmt = $dbh->query($sql);
 
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r('<pre>');
var_dump($result);
print_r('</pre>');

ぎゃーーー!

って別に驚くことではないが。。

azure mysqlにデータを入れていく

vagrantから普通にtableを作って、データを入れていきます。

mysql -u adminuser@namysql -h namysql.database.windows.net -P 3306 -p

create database sier;

create table sier.forein(
	id int unsigned auto_increment primary key,
	company varchar(255),
	address varchar(255),
	station varchar(255),
	url varchar(2083),
	menu varchar(255)
);


INSERT INTO sier.forein(company, address, station, url, menu)
  VALUES ('Microsoft','〒108-0075 東京都港区港南 2-16-3 品川グランドセントラルタワー','品川','https://www.microsoft.com/ja-jp','office, windows, surface, xbox, お買い得商品,サポート');
INSERT INTO sier.forein(company, address, station, url, menu)
  VALUES ('Oracle','〒107-0061 東京都港区北青山2-5-8 オラクル青山センター','外苑前','https://www.oracle.com/jp/index.html','Cloud, イベント, whats new お客様成功事例');
INSERT INTO sier.forein(company, address, station, url, menu)
  VALUES ('Accenture','〒107-8672 東京都港区赤坂1-11-44 赤坂インターシティ','溜池山王','https://www.accenture.com/jp-ja/new-applied-now','トレンド,サービス,業界,採用情報,会社情報');
INSERT INTO sier.forein(company, address, station, url, menu)
  VALUES ('Cisco','〒107‐6227 東京都港区赤坂9丁目7−1 ミッドタウン・タワー','六本木','https://www.cisco.com/c/ja_jp/index.html','製品&サービス,サポート,購入案内,トレーニング&イベント,パートナー');

なにーー!文字化けしている。。。あれ、azureのmysqlってUTF-8じゃないのかしら?

>Japanese_CI_AS などの日本語照合順序での文字 “あ” は、文字コード 0x82A0として表現されますが、上記の例の場合、データベースの照合順序が SQL_Latin1_General_CP1 であるため、”あ” を表現しているつもりの文字コード 0x82A0 は、実際には “あ” ではなく SQL_Latin1_General_CP1 の文字として扱われます。尚、SQL_Latin1_General_CP1 の文字コード 0x82A0 に対応する Unicode 文字が存在しません。その結果、”あ” の変換結果は “?” となり、テーブル列に “?” が格納されることになります。

なるほど、対応するunicode文字がないようですね。

一旦テーブルを削除します。
mysql> drop table sier.forein;
Query OK, 0 rows affected (0.40 sec)

nvarcharで作り直します。

create table sier.forein(
	id int unsigned auto_increment primary key,
	company nvarchar(255),
	address nvarchar(255),
	station nvarchar(255),
	url nvarchar(2083),
	menu nvarchar(255)
);

今度こそ!

よっしゃ!

さー、次はpdoでselectですね!テンションが上がってまいりました!