لا ينبغي أن لا يتم تثبيت هذا السكريت مباشرة. هو مكتبة لسكبتات لتشمل مع التوجيه الفوقية // @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;
}
})();