Skip to content

Instantly share code, notes, and snippets.

@mainyaa
Created July 26, 2012 01:28
Show Gist options
  • Save mainyaa/3179738 to your computer and use it in GitHub Desktop.
Save mainyaa/3179738 to your computer and use it in GitHub Desktop.
Google App Engine Log Downloader (forked by mainyaa)
// ==UserScript==
// @name Google App Engine Log Downloader (forked)
// @namespace gldf
// @description Google App Engine Log Downloader (forked by mainyaa)
// @include http://appengine.google.com/logs*
// @include https://appengine.google.com/logs*
// @author pto.developer (http://pto-s2.appspot.com/d/ or http://twitter.com/pto_developer)
// @author forked by mainyaa (http://twitter.com/mainyaa)
// ==/UserScript==
( function(){
var gldf = {};
// date format
// true : yyyy/MM/dd HH:mm:ss.SSS
// false : MM/dd HH:mm:ss.SSS
// null : (disable re-format)
gldf.ENABLE_FORMAT_YYYY = false;
// log date timezone, default : PST(GMT-08:00, non daylight saving time)
gldf.log_timezone_offset_in_minutes = -8 * 60;
// your timezone, default : from your localtime ex) JST=9*60, GMT=0
gldf.your_timezone_offset_in_minutes = new Date().getTimezoneOffset();
// enable firebug logging
gldf.enable_firebug_logging = false;
//////////////////////////////////////////////////////////////////////////////////////////////////
gldf.leftZeroPad = function(text, len){
var tmp = "00000000" + text;
return tmp.substring(tmp.length - len, tmp.length);
}
gldf.log = function(str){
if(gldf.enable_firebug_logging && console && console.info){
console.info(str);
}
}
gldf.req = function(param){
var xhr = new XMLHttpRequest();
xhr.open("GET", param.url, true);
xhr.onreadystatechange = function(){
if (xhr.readyState==4){
if(xhr.status == 200){
param.onload(xhr, param);
}
else{
param.onerror(xhr, param); // TODO retry
}
}
}
xhr.send(null)
}
// TODO not worked
gldf.getValue = function(key, value){
if(false && GM_getValue){
GM_getValue(key, value);
}
}
gldf.setValue = function(key, default_value){
if(false && GM_setValue){
GM_setValue(key, default_value);
}
}
////////////////////////////////////////////////////////////////////////////////////
gldf.parseLogPres = function(parentDiv, updateView, reqlog){
var str = "";
var pres = parentDiv.getElementsByTagName('pre');
if (!reqlog){
pres = parentDiv.getElementsByClassName('snippet');
}
var len = Math.min(7, pres.length);
var timepos = reqlog ? 0 : 1;
for(var k=0; k<len; k++){
var s = pres[k].innerHTML.toString();
if(k==timepos && (gldf.ENABLE_FORMAT_YYYY!=null)){
//gldf.log("time:" + s);
var adjusted = gldf.adjustTz(s);
if(adjusted){
s = adjusted;
if(updateView){
pres[k].innerHTML = adjusted; //.substring(5);
return "";
}
}
}
s = s.replace(/<.*?>/g, ""); // link
str += s + (reqlog?"\t":" ");
}
return str.replace(/\n/g, " ");
}
gldf.parseLogDiv = function(div, updateView){
var tsv = "";
var reqlog = document.getElementById("ae-logs-requests-all").checked == true;
var log_divs = div.getElementsByClassName("ae-logs-reqlog");
for(var i=0; i<log_divs.length; i++){
var tmp = log_divs[i];
tsv += gldf.parseLogPres(tmp, updateView, true); // true : always reqlog
// find app log
applog = tmp.parentNode.getElementsByClassName("ae-logs-applog");
for(var j=0; j<applog.length; j++){
tsv += gldf.parseLogPres(applog[j], updateView, false) + "\t"; // false : always applog
}
tsv += "\n";
}
var nextUrl = null;
var next = div.getElementsByClassName("ae-paginate-next");
if(next && next.length > 0){
nextUrl = next[0].getAttribute("href");
}
gldf.log("page:" + gldf.page + " parseed, tsv="+tsv.length + ", nextUrl=" + nextUrl);
return [tsv, nextUrl]
}
gldf.PAT_DATE = /^(\d\d)-(\d\d) (\d\d):(\d\d)(AM|PM) (\d\d)\.(\d\d\d)$/;
gldf.offset = (gldf.your_timezone_offset_in_minutes + gldf.log_timezone_offset_in_minutes) * 60 * 1000;
gldf.adjustTz = function(str){
var match = str.match(gldf.PAT_DATE);
if(!match){
//gldf.log("!match : " + str)
return null;
}
var date = new Date();
date.setMonth(new Number(match[1]) - 1, match[2]);
var hour = new Number(match[3]);
if(hour == 12){hour = 0;}
date.setHours(match[5] == "AM" ? hour : hour + 12);
date.setMinutes(match[4]);
date.setSeconds(match[6], match[7]);
date.setTime(date.getTime() - gldf.offset);
// TODO unconsidered "last year"
var ret = (gldf.ENABLE_FORMAT_YYYY ? (date.getFullYear()+"-") : "") + gldf.leftZeroPad(date.getMonth() + 1, 2)
+ "-" + gldf.leftZeroPad(date.getDate(), 2) + " " + gldf.leftZeroPad(date.getHours(), 2)
+ ":" + gldf.leftZeroPad(date.getMinutes(), 2) + ":"
+ gldf.leftZeroPad(date.getSeconds(), 2) + "." + gldf.leftZeroPad(date.getMilliseconds(), 3);
return ret;
}
// variables for state
gldf.page = 0;
gldf.all_log = "";
gldf.ta = null;
gldf.limit = gldf.getValue("gldf_pages", 2);
gldf.cache = [];
gldf.parse = function(text, cache_key_url){
var tmpdiv = document.getElementById("gldf_tmpdiv");
var targetdiv = null;
if(text == null){
cache_key_url = location.href;
targetdiv = document.getElementById("ae-logs");
}
else{
tmpdiv.innerHTML = text;
targetdiv = tmpdiv;
}
var ret = gldf.parseLogDiv(targetdiv, false);
if(ret && ret[0]){
gldf.all_log += ret[0];
gldf.ta.value = "page:" + gldf.page;
if(cache_key_url && !gldf.cache[cache_key_url]){
gldf.log("cache added " + cache_key_url);
gldf.cache[cache_key_url] = ret;
}
}
tmpdiv.innerHTML = "";
var nextUrl = (ret && ret[1]) ? ret[1] : null;
gldf.next(nextUrl);
}
gldf.next = function(url){
gldf.log("next (" + gldf.page + "/" + gldf.limit + "), url=" + url);
if(gldf.page++>=gldf.limit || !url){
gldf.ta.value = gldf.all_log;
return;
}
var cache_key_url = url;
if(url.indexOf("&layout=none") == -1){
url = url + "&layout=none";
}
else{
cache_key_url = cache_key_url.replace(/&layout=none/, "");
}
if(gldf.cache[cache_key_url]){
gldf.log("cache found " + cache_key_url);
var ret = gldf.cache[cache_key_url];
gldf.all_log += ret[0];
var nextUrl = ret[1];
gldf.next(nextUrl);
return;
}
else{
gldf.req({
url : url,
onload : function(x){ gldf.parse(x.responseText, cache_key_url);},
onerror : function(x){ gldf.ta.value = "failed. please retry. status=" + x.status; }
});
}
}
////////////////////////////////////////////////////////////////////////////////////
gldf.init = function(){
var target = document.getElementById("ae-logs-form-options");
var main_area = document.createElement("span");
main_area.setAttribute("id", "gldf_main");
main_area.setAttribute("style", "margin-left:40px");
main_area = target.parentNode.insertBefore(main_area, target);
main_area.innerHTML
= "<button style='background:#DDDDDD url(/img/button-bg.gif) repeat-x scroll left top;"
+ " border-style:solid; border-color:#99CCFF #6699EE #6699EE #77AAFF; border-width:1px'"
+ " id='gldf_get' onclick='return false'>getTSV</button> for "
+ "<input type='text' value='2' size='3' style='width:24px;' id='gldf_pages'>pages &nbsp;&nbsp;&nbsp;"
+ "result:<textarea id='gldf_ta' rows='1' cols='20' style='overflow:hidden; paddin:0px; margin-bottom:-2px'>"
+ "</textarea><div id='gldf_tmpdiv' style='display:none'></div>"
;
gldf.ta = document.getElementById("gldf_ta");
var button = document.getElementById("gldf_get");
button.addEventListener("click",function(){
var limit_str = document.getElementById("gldf_pages").value;
if(!limit_str || !limit_str.match(/^[0-9]+$/)){
alert("input number!");
return false;
}
gldf.limit = new Number(limit_str);
gldf.setValue("gldf_pages", gldf.limit);
gldf.ta.value="";
gldf.page = 0;
gldf.all_log = "";
gldf.parse(null);
return false;
}, false);
if(gldf.ENABLE_FORMAT_YYYY != null){
var potentialUpdate = false;
function periodicalUpdate(force){
if(!force && !potentialUpdate){
return;
}
gldf.log("periodicalUpdate:" + potentialUpdate);
potentialUpdate = false;
gldf.parseLogDiv(document.getElementById("ae-logs"), true);
}
periodicalUpdate(true);
document.getElementById("ae-logs").addEventListener("DOMNodeInserted", function(){potentialUpdate = true;}, false);
setInterval(function(){periodicalUpdate();}, 1000);
}
}
gldf.init();
}) ();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment