A library of airflow log highlight for airflow helper
Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta
// @require https://update.greasyfork.org/scripts/460424/1152786/Airflow%20log%20hightlight%20library.js
// ==UserScript==
// @name Airflow log hightlight library
// @namespace https://greasyfork.org/zh-CN/scripts/430272-airflow-log-hightlight-lib
// @description A library of airflow log highlight for airflow helper
// @include http://airflow.yimian.com.cn/*
// @include http://airflow.onework.yimian.com.cn/*
// @include http://172.16.24.11:18080/*
// @grant GM_log
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_openInTab
// @grant GM_registerMenuCommand
// @version 0.1.4
// ==/UserScript==
;(function () {
var isOpera = !!this.opera,
isChromium = !!this.chromium;
var STYLE_COLOR = ['#FFFF80','#99ccff','#ff99cc','#66cc66','#cc99ff','#ffcc66','#66aaaa','#dd9966','#aaaaaa','#dd6699'];
var BORDER_COLOR = ['#aaaa20','#4477aa','#aa4477','#117711','#7744aa','#aa7711','#115555','#884411','#555555','#881144'];
var but_c = '#99cc99', but_ca = '#FFD000', but_cd = '#999999', but_cb = '#669966'; // button normal/active/disable background color/border color.
// Initialize value
var PRE = 'wordhighlight', ID_PRE = PRE + '_id';
var STYLE_CLASS = '0123456789'.split('').map(function(a,i){return PRE + '_word'+i;});
var keyword = "AnalysisException|ValueError|TypeError|ProgrammingError|JSONDecodeError|AnalysisException|NameError|IndentationError|KeyError|IndexError|AttributeError|FileNotFoundError|\
ConnectionError|HTTPError|Received SIGTERM|SyntaxError|OutOfMemory|Container killed by YARN for exceeding memory limits|Failed to get minimum memory|\
Permission denied|Memory limit exceeded|Could not resolve table reference|Could not resolve column/field reference|File does not exist|RemoteException|\
TExecuteStatementResp|object has no attribute|InternalError|NullPointerException|ConnectionError|Failed to close HDFS|cannot be null|IntegrityError|\
ArrayIndexOutOfBoundsException|has more columns|Unknown column|No such file or directory|Out Of Memory|RuntimeError|Traceback|AirflowTaskTimeout|AssertionError|\
Check 'stl_load_errors' system table for details|OperationalError|Lost connection to MySQL server during query|AirflowTaskTimeout|files cols number not match target file cols number, check it|\
Data too long for column|DataError|Initial job has not accepted any resources|/tmp/oneflow_|http://oneflow.yimian.com.cn/dag|num_dumped_rows|com.yimian.etl"
var words = [];
var words_off = [];
// 创建一个观察器实例并传入回调函数
const observer1 = new MutationObserver(setup);
const observer2 = new MutationObserver(setup);
if (window.location.href.includes('log')) {
init_keyword()
observeTargetDOM()
}
function observeTargetDOM() {
const logMenu = document.querySelectorAll('.nav.nav-pills')[3]
const logContent = document.querySelector('.tab-content').lastChild.previousSibling
const config = { childList: true, subtree: true, attributes: true };
// 以上述配置开始观察目标节点
observer1.observe(logMenu, config);
observer2.observe(logContent, config);
}
function init_keyword() {
keyword = trim(keyword);
window.name = PRE + '::' + encodeURIComponent(keyword);
words = init_words(keyword);
}
function setup() {
addsheet();
highlight(document.body)
observer2.disconnect()
}
function highlight(doc) {
const _words = words.filter((w,i) => !words_off[i]);
if (_words.length <= 0) return;
let exd_words, xw;
if (_words.length === 1 && _words[0].exp) {
exd_words = _words.map((e) => e.exp);
xw = '';
} else {
exd_words = _words.map(function(w){return w.test ? w : new RegExp('(' + w.replace(/\W/g,'\\$&') + ')(?!##)', 'ig');});
xw = ' and (' + _words.map(function(w){return ' contains(translate(self::text(),"abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ"),'+escapeXPathExpr(w.toUpperCase())+') ';}).join(' or ') + ') ';
}
$X('descendant::text()[string-length(normalize-space(self::text())) > 0 ' + xw +' and not(ancestor::textarea or ancestor::script or ancestor::style or ancestor::aside)]', doc)
.forEach(function(text_node) {
let parent = text_node.parentNode;
// 关键词父元素标签为span 说明已经被高亮过
if (parent.tagName.toUpperCase() === 'SPAN') return;
let df,
text = text_node.nodeValue,
id_index = 0,
range = document.createRange(),
replace_strings = [],
new_text = reduce(exd_words, (text,ew,i) => {
return text.replace(ew,($0,$1) => {
replace_strings[id_index] = '<span id="' + ID_PRE + id_index + '" class="' + STYLE_CLASS[i%10] + '" name="'+PRE+'_word'+i+'">' + $1 + '</span>';
return '##'+(id_index++)+'##';
});
}, text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/##(\d+)##/g, ($0,$1) => replace_strings[$1] || '');
if (replace_strings.length) {
try {
if (isChromium) {
const htmlDoc = document.implementation.createHTMLDocument('hogehoge');
range.selectNodeContents(htmlDoc.documentElement);
} else {
range.selectNode(text_node);
}
df = range.createContextualFragment(new_text);
console.log('df', df);
if (df.firstChild) parent.replaceChild(df, text_node);
range.detach();
} catch (e) {
error(e);
}
}
});
}
function addsheet() {
const hilistyles = STYLE_COLOR.map((rgb,i) => {
return 'span.' + PRE + '_word'+i+',.' + PRE + '_item'+i+'{background:'+rgb+'!important;}';
});
const borderstyles = BORDER_COLOR.map((rgb,i) => {
return 'li.' + PRE + '_item'+i+'{outline:1px solid '+rgb+'!important;}';
});
const panel_pos_arr = ['right:-1px;','bottom:-1px;'];
sheet = addCSS([
//Additional Style
'span[class^="' + PRE + '_word"]{color:black!important;font:inherit!important;display:inline!important;margin:0!important;padding:0!important;text-align:inherit!important;float:none!important;position:static!important;}', //vertical-align:inherit !important;
'#' + PRE + '_words, #' + PRE + '_words *{font-family: Arial ;}',
'#' + PRE + '_words{line-height:1;position:fixed;z-index:60000;opacity:0.8;list-style-type:none;margin:0;padding:0;width:auto;max-width:100%;' + panel_pos_arr[0] + panel_pos_arr[1] +'}',
'#' + PRE + '_words > section{clear:right;line-height:1;border:1px solid #666;/*border-left-width:10px;*/background:#fff;display:block;position:relative;}',
'#' + PRE + '_words * {margin:0;padding:0;width:auto;height:auto;}',
'#' + PRE + '_words:hover{opacity:1;}',
'#' + PRE + '_words:hover > section{opacity:1;border-color:#333;}',
'#' + PRE + '_words #_ewh_handle{background:#666;width:10px;cursor:move;}',
'#' + PRE + '_words:hover #_ewh_handle{background:#333;}',
'#' + PRE + '_words.ewh_hide #_ewh_handle{cursor:pointer;}',
// '#' + PRE + '_words.ewh_hide:hover #_ewh_handle{width:10px;}',
// '#' + PRE + '_words.ewh_hide > section form.' + PRE + '_ctrl > input.c_b{display:none;}',
'#' + PRE + '_words > nav{display:none;width:100%;padding:3px;position:relative;}',
'#' + PRE + '_words > nav > canvas.backport{background:rgba(0,0,0,0.5);cursor:pointer;position:absolute;right:6px;z-index:3;}',
'#' + PRE + '_words > nav > canvas.viewport{background:rgba(79,168,255,0.7);cursor:default;position:absolute;bottom:0px;right:6px;}',//outline:6px solid rgba(79,168,255,0.7);
// '#' + PRE + '_words > nav:hover > canvas.backport{background:rgba(0,0,0,0.5);}',
'#' + PRE + '_words:hover > nav{display:block;}',
'#' + PRE + '_words > nav._locked{display:block;}',
'#' + PRE + '_words:hover > nav > canvas.backport{bottom:0px;}',
'#' + PRE + '_words > nav._locked > canvas.backport{bottom:0px;}',
'#' + PRE + '_words.ewh_edit{opacity:1;}',
'#' + PRE + '_words.ewh_edit #' + PRE + '_word_inputs_list{display:none;}',
'#' + PRE + '_words form.' + PRE + '_editor{display:none;}',
'#' + PRE + '_words.ewh_edit form.' + PRE + '_editor{display:inline-block;}',
'#' + PRE + '_words.ewh_edit form.' + PRE + '_editor input{min-width:80px;}',
'#' + PRE + '_words li{display:inline-block;margin:0.1em 0.2em;line-height:1.3em;font-size:medium;}',
'#' + PRE + '_words > section > * {vertical-align:middle;}',
'#' + PRE + '_words > section td {border:none;}',
'#' + PRE + '_words > section > h3.' + PRE + '_title{display:inline-block;background:#333;color:#fff;padding:0.1em 0.3em;border:none;margin:0 0.2em;}',
'#' + PRE + '_words > section form.' + PRE + '_ctrl{display:inline-block;}',
'#' + PRE + '_words > section form.' + PRE + '_ctrl > input{display:inline;width:1.3em;margin:0.1em 0.1em;background:'+ but_c +';border:1px solid '+ but_cb +';cursor:pointer;font-size:10pt;color:black;}',
'#' + PRE + '_words > section form.' + PRE + '_ctrl > input._active{background:'+ but_ca +';}',
'#' + PRE + '_words > section form.' + PRE + '_ctrl > input._disable{background:'+ but_cd +' !important;cursor:default;}',
'#' + PRE + '_words > section form.' + PRE + '_ctrl > input:hover{outline:1px solid '+ but_cb +'!important;}',
'#' + PRE + '_word_inputs_list {padding:0!important;margin:0.2em!important;display:inline-block;border:none!important;}',
'#' + PRE + '_word_inputs_list > li{position:relative;padding:0 4px;}',
'#' + PRE + '_word_inputs_list > li.ewh_disable{background:white!important;outline:1px solid #999!important;}',
'#' + PRE + '_word_inputs_list > li > label{cursor:pointer;color:black!important;}',
'#' + PRE + '_word_inputs_list > li > input{cursor:pointer;}',
// '#' + PRE + '_word_inputs_list > li > label > input[type=image]{vertical-align:top;padding:0;height:12px;}',
'#' + PRE + '_word_inputs_list > li > input[type=checkbox]{display:none;position:absolute;right:0px;top:0px;opacity:0.7;}',
'#' + PRE + '_word_inputs_list > li:hover{outline-width:2px!important;}',
'#' + PRE + '_word_inputs_list > li:hover > input[type=checkbox]{display:block;}',
'#' + PRE + '_word_inputs_list > li > input[type=checkbox]:hover{opacity:1;}',
'#' + PRE + '_words > section td+td+td > input {display:inline;width:1.3em;margin:0.1em 0.1em;background:#FAFAFA;border:1px solid #aaaaaa;cursor:pointer;font-size:10pt;color:black;}',
].concat(hilistyles, borderstyles).join('\n'));
}
function trim(str) {
return str.replace(/[\n\r]+/g,' ').replace(/^\s+|\s+$/g,'').replace(/\.+\s|\.+$/g,'');
}
function uniq(arr) {
var a = [], o = {}, i, v, len = arr.length;
if (len < 2) {return arr;}
for (i = 0; i < len; i++) {
v = arr[i];
if (o[v] !== 1) {
a.push(v);
o[v] = 1;
}
}
return a;
};
function init_words(word) {
var erg = word.match(new RegExp("^ ?/(.+)/([gim]+)?$"));
if (erg) {
var ew = erg[1], flag = erg[2] || '';
var word_s = [{exp:new RegExp('(' + ew + ')(?!##)', flag), text:ew, toString:function(){return ew;}}];
} else if (word) {
var ret=[], eword = word.replace(/"([^"]+)"/g,function($0,$1){$1 && ret.push($1);return '';});
var word_s = eword.split(/[\+\|#]/).filter(function(w){return !!w;}).concat(ret);
word_s = uniq(word_s);
for (var i in word_s) {
if (/^[a-z0-9]$/i.test(word_s[i]))
words_off[i] = true;
else words_off[i] = false;
}
}
return word_s;
}
// http://d.hatena.ne.jp/amachang/20090917/1253179486
function escapeXPathExpr(text) {
var matches = text.match(/[^"]+|"/g);
function esc(t) {
return t == '"' ? ('\'' + t + '\'') : ('"' + t + '"');
}
if (matches) {
if (matches.length == 1) {
return esc(matches[0]);
} else {
var results = [];
for (var i = 0, len = matches.length; i < len; i ++) {
results.push(esc(matches[i]));
}
return 'concat(' + results.join(', ') + ')';
}
} else {
return '""';
}
}
function $X(exp, context, resolver, result_type) {
context || (context = document);
var Doc = context.ownerDocument || context;
var result = Doc.evaluate(exp, context, resolver, result_type || XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (result_type) return result;
for (var i = 0, len = result.snapshotLength, res = new Array(len); i < len; i++) {
res[i] = result.snapshotItem(i);
}
return res;
}
// reduce https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce#Compatibility
function reduce(arr, fun) {
var len = arr.length, i = 0, rv;
if (arguments.length >= 3) rv = arguments[2];
else {do {
if (i in arr) {
rv = arr[i++];break;
}
if (++i >= len) throw new TypeError();
} while (true)};
for (; i < len; i++) if (i in arr) rv = fun.call(null, rv, arr[i], i, arr);
return rv;
}
function error(e) {
if (isOpera) {
opera.postError(e);
} else if (window.console) {
console.error(e);
}
}
function addCSS(css) {
var sheet, self = arguments.callee;
if (document.createStyleSheet) { // for IE
sheet = document.createStyleSheet();
sheet.cssText = css;
return sheet;
} else if (!self.__style || !self.__root) {
sheet = document.createElement('style');
sheet.type = 'text/css';
self.__style = sheet;
self.__root = document.getElementsByTagName('head')[0] || document.documentElement;
}
sheet = self.__style.cloneNode(false);
sheet.textContent = css;
return self.__root.appendChild(sheet).sheet;
}
})();