ある日、情シスより突然放たれた非情な宣告。
「以後アクセスログは渡せません。」
理由は明かされなかったが、そんなことどうでもいい。
なにせ、フロントエンドしか扱えない環境で、しかもこの業務はアクセスログがなければ成立しないのだ。
業務存続危機である。
ヤバし。
そこそこ考えた末、GoogleスプレッドシートとGAS(Google App Script)を使って擬似的なアクセスログをつくることにした。
概要
ログに記録したい情報をGoogleスプレッドシートにPOST送信し、GASでその情報を記録する。
フロントエンドだけでも、JavaScript(windowオブジェクトやscreenオブジェクトなど)を使って様々な情報を取得することができる。
なお、後述するが、この方法で記録する場合は、Webで公開可能な情報しか扱えないことに留意されたい。
事前準備
予め受け側のスプレッドシートを作成し、Web公開しておく。
なお、スプレッドシート名は任意の名前で(今回は使用しない)、ワークシート名は「AllLog」とする。
スプレッドシートを作成したら、スプレッドシートのkeyとworksheetIdを確認しておく。
※スプレッドシートのkeyとworksheetIdの確認方法は下記を参照
Googleスプレッドシートをjsから読み書きしてみた - derax’s blog
コード
クライアント側
//*************************************
// 記録したい情報をpostdataに「変数名&変数&...」と格納し、それをスプレッドシートのkey(gasurl)にPOST送信する
//*************************************
function writeLog() {
var gasurl = "予め確認しておいたkey";
var lHr = window.location.href;
var lPa = lHr.match(".+/(.+?)([?#;].*)?$")[1];
var lSe = window.location.search;
lHr = encodeURIComponent(lHr); //URLをpost先で取り込む際、'&'があるとそこまでと判定されるためURLエンコードしておく(GAS側でデコードする)
lSe = encodeURIComponent(lSe);//URLをpost先で取り込む際、'&'があるとそこまでと判定されるためURLエンコードしておく(GAS側でデコードする)
var lHa = window.location.hash;
var dTi = encodeURIComponent(window.document.title);
var dRe = myGetQuery("referrer");
if (dRe === null) {
dRe = window.document.referrer;
}
var nAc = navigator.appCodeName;
var nAn = navigator.appName;
var nAv = navigator.appVersion;
var nCe = navigator.cookieEnabled;
var nPl = navigator.platform;
var nUa = navigator.userAgent;
var nCp = navigator.cpuClass;
// 最優先の言語だけ取得
var uLa =
(window.navigator.languages && window.navigator.languages[0]) ||
window.navigator.language ||
window.navigator.userLanguage ||
window.navigator.browserLanguage;
// クライアント側で受け付けている言語リストを取得
var cLa = window.navigator.languages || [
window.navigator.language ||
window.navigator.userLanguage ||
window.navigator.browserLanguage
];
var sWi = screen.width;
var sHe = screen.height;
var wAv = screen.availWidth;
var sAl = screen.availHeight;
var sCl = screen.colorDepth;
var sPi = screen.pixelDepth;
var postdata =
"lHr=" +
lHr +
"&lPa=" +
lPa +
"&lSe=" +
lSe +
"&lHa=" +
lHa +
"&dTi=" +
dTi +
"&dRe=" +
dRe +
"&dev=" +
dev +
"&nAc=" +
nAc +
"&nAn=" +
nAn +
"&nAv=" +
nAv +
"&nCe=" +
nCe +
"&nPl=" +
nPl +
"&nUa=" +
nUa +
"&nCp=" +
nCp +
"&uLa=" +
uLa +
"&cLa=" +
cLa +
"&sWi=" +
sWi +
"&sHe=" +
sHe +
"&wAv=" +
wAv +
"&sAl=" +
sAl +
"&sCl=" +
sCl +
"&sPi=" +
sPi;
$.ajax({
url: gasurl,
type: "POST",
data: postdata,
dataType: "text"
});
}
GoogleAppScript側
//*************************************
// POST送信された情報(e)の各パラメータを各変数に格納し、sheet.appendRowでスプレッドシートの最下行に挿入する
//*************************************
function doPost(e) {
var spreadsheetId = "予め確認しておいたworksheetId";
var ss = SpreadsheetApp.openById(spreadsheetId);
var sheet;
sheet = ss.getSheetByName("AllLog"); //シート名
var lHr = e.parameter.lHr; //location.href
lHr = decodeURIComponent(lHr); //POSTの際エンコードされたURLをデコード
var lPa = e.parameter.lPa; //location.pathname
var act = e.parameter.action; //action
var eve = e.parameter.event; //event
var lSe = e.parameter.lSe; //location.search
lSe = decodeURIComponent(lSe); //POSTの際エンコードしたURLをデコード
var lHa = e.parameter.lHa; //location.hash
var dTi = e.parameter.dTi; //document.title
var dRe = e.parameter.dRe; //document.referrer
var nAc = e.parameter.nAc; //navigator.appCodeName
var nAn = e.parameter.nAn; //navigator.appName
var nAv = e.parameter.nAv; //navigator.appVersion
var nCe = e.parameter.nCe; //navigator.cookieEnabled
var nPl = e.parameter.nPl; //navigator.platform
var nUa = e.parameter.nUa; //navigator.userAgent
var nCp = e.parameter.nCp; //navigator.cpuClass
var uLa = e.parameter.uLa; //language
var cLa = e.parameter.cLa; //client language
var sWi = e.parameter.sWi; //screen.width
var sHe = e.parameter.sHe; //screen.height
var wAv = e.parameter.wAv; //screen.availWidth
var sAl = e.parameter.sAl; //screen.availHeight
var sCl = e.parameter.sCl; //screen.colorDepth
var sPi = e.parameter.sPi; //screen.pixelDepth
sheet.appendRow([
new Date(),
lHr,
lPa,
act,
eve,
lSe,
lHa,
dTi,
dRe,
nAc,
nAn,
nAv,
nCe,
nPl,
nUa,
nCp,
uLa,
cLa,
sWi,
sHe,
wAv,
sAl,
sCl,
sPi
]);
}
【重要】 扱える情報について
これまで説明したりとおり、この方法はWeb公開したスプレッドシートに対し記録をしていくというものである。
つまり、スプレッドシートのkeyさえわかれば、誰でもスプレッドシートを閲覧することができてしまう。
筆者のような状況(フロントエンドしか扱えない環境)で、JavaScript側に直接記述する場合、扱う情報は他者から閲覧されても支障のないもののみにしなければならない。
たとえば、この方法ではフォームに入力された情報の記録も可能だが、個人情報を送信させるようなものだと、たちまち情報漏洩となってしまう。
こんな応用もできる
スプレッドシートに記録してしまえば、あとはGASで様々なことができるようになる。
筆者の場合、月替りに直前1ヶ月分のアクセスログを別のスプレッドシートに保存し、かつ、任意のメールアドレスにExcel形式で自動送信している。
扱う情報に気を付ければ、使い勝手のいいアクセスログシステムの完成である。
参ったか、情シス。