mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-04 03:43:56 +08:00
update 2026-09-22 16:57:57
This commit is contained in:
1 parent
f0ef5fcc0f
commit
35e3e3404d
1987 files changed
+1524591
-24
No files matched your search
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-daede
|
||||
PKG_VERSION:=1.15
|
||||
PKG_RELEASE:=2
|
||||
PKG_RELEASE:=3
|
||||
PKG_MAINTAINER:=kenzok8
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
|
||||
@@ -336,6 +336,15 @@ function renderDaeForms(ctx) {
|
||||
|
||||
s = m.section(form.NamedSection, 'config', 'dae', _('Logging'));
|
||||
s.addremove = false;
|
||||
o = s.option(form.ListValue, 'log_level', _('Log level'),
|
||||
_('Debug and trace show per-connection routing details, but increase CPU usage and log volume. Enable them only while troubleshooting.'));
|
||||
o.value('error', 'ERROR');
|
||||
o.value('warn', 'WARN');
|
||||
o.value('info', 'INFO');
|
||||
o.value('debug', 'DEBUG');
|
||||
o.value('trace', 'TRACE');
|
||||
o.default = 'info';
|
||||
o.rmempty = false;
|
||||
o = s.option(form.Value, 'log_maxsize', _('Max Log Size (MB)'),
|
||||
_('Rotate the log file once it grows past this many megabytes.'));
|
||||
o.datatype = 'uinteger';
|
||||
|
||||
@@ -37,6 +37,7 @@ const CSS = [
|
||||
'.dd-log-pane .dd-line.dd-warn{color:#e8b95a}',
|
||||
'.dd-log-pane .dd-line.dd-error{color:#ea7878;background:rgba(234,120,120,.06)}',
|
||||
'.dd-log-pane .dd-line.dd-debug{color:#7a8290;opacity:.7}',
|
||||
'.dd-log-pane .dd-line.dd-trace{color:#68717d;opacity:.62}',
|
||||
'.dd-log-pane .dd-line.dd-hidden{display:none}',
|
||||
'.dd-log-pane .dd-empty{opacity:.5;font-style:italic}',
|
||||
/* 简化后的字段视觉 */
|
||||
@@ -46,6 +47,7 @@ const CSS = [
|
||||
'.dd-log-pane .dd-lvl-warn{color:#e8b95a;background:rgba(232,185,90,.10)}',
|
||||
'.dd-log-pane .dd-lvl-error{color:#ea7878;background:rgba(234,120,120,.10)}',
|
||||
'.dd-log-pane .dd-lvl-debug{color:#7a8290;background:rgba(122,130,144,.10)}',
|
||||
'.dd-log-pane .dd-lvl-trace{color:#68717d;background:rgba(104,113,125,.10)}',
|
||||
'.dd-log-pane .dd-msg{color:inherit}',
|
||||
'.dd-log-pane .dd-kv{margin-left:6px;color:#6b7480;font-size:11px;opacity:.85}',
|
||||
'body.dark .dd-log-card,html[data-theme="dark"] .dd-log-card,html[data-bs-theme="dark"] .dd-log-card{border-color:rgba(255,255,255,.08);background:rgba(255,255,255,.02)}',
|
||||
@@ -54,20 +56,39 @@ const CSS = [
|
||||
|
||||
/* 拆字段:time="May 25 07:04:59" level=info msg="..." key=val key="val with space" ... */
|
||||
const RE_LINE = /^time="([^"]*)"\s+level=(\w+)\s+msg=(?:"((?:[^"\\]|\\.)*)"|(\S+))\s*(.*)$/;
|
||||
const RE_PREFIXED_LINE = /^\[([^\]]+)\]\s+(DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|PANIC)\s*(.*)$/i;
|
||||
const RE_PLAIN_LEVEL_LINE = /^\s*(DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|PANIC)\s+(.*)$/i;
|
||||
const RE_PREFIXED_LINE = /^\[([^\]]+)\]\s+(TRACE|DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|PANIC)\s*(.*)$/i;
|
||||
const RE_PLAIN_LEVEL_LINE = /^\s*(TRACE|DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|PANIC)\s+(.*)$/i;
|
||||
|
||||
function detectLevel(line) {
|
||||
// daed/dae logs use lvl=info / [INFO] / level=warning style
|
||||
const m = line.match(/\b(DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|PANIC)\b/i);
|
||||
const m = line.match(/\b(TRACE|DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|PANIC)\b/i);
|
||||
if (!m) return '';
|
||||
const lvl = m[1].toUpperCase();
|
||||
if (lvl === 'TRACE') return 'dd-trace';
|
||||
if (lvl === 'DEBUG') return 'dd-debug';
|
||||
if (lvl === 'INFO') return 'dd-info';
|
||||
if (lvl.startsWith('WARN')) return 'dd-warn';
|
||||
return 'dd-error';
|
||||
}
|
||||
|
||||
function matchesFilter(line, filter) {
|
||||
if (!filter)
|
||||
return true;
|
||||
|
||||
if (filter === 'trace' || filter === 'debug' || filter === 'info' || filter === 'warn' || filter === 'error')
|
||||
return detectLevel(line) === 'dd-' + filter;
|
||||
|
||||
if (filter === 'node_status')
|
||||
return /\balive\b/i.test(line)
|
||||
|| /\bgroup\b.*\bselects dialer\b/i.test(line)
|
||||
|| /\bgroup\s+'[^']+'\s+\[[^\]]+\]:/i.test(line);
|
||||
|
||||
if (filter === 'proxy_traffic')
|
||||
return line.indexOf('<->') !== -1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 格式化时间戳并按北京时间显示:
|
||||
* - daed 默认输出 UTC ISO 8601 (e.g. "2026-05-28T19:07:54Z"),转成北京时间
|
||||
* - 新格式和旧 logrus 短格式无时区信息,保留原始完整日期时间
|
||||
@@ -101,6 +122,7 @@ function lvlShort(level) {
|
||||
|
||||
function lvlClass(level) {
|
||||
const u = (level || '').toUpperCase();
|
||||
if (u === 'TRACE') return 'dd-lvl-trace';
|
||||
if (u === 'DEBUG') return 'dd-lvl-debug';
|
||||
if (u === 'INFO') return 'dd-lvl-info';
|
||||
if (u === 'WARN' || u === 'WARNING') return 'dd-lvl-warn';
|
||||
@@ -209,11 +231,13 @@ return view.extend({
|
||||
|
||||
const selFilter = E('select', { 'class': 'dd-log-btn' }, [
|
||||
E('option', { 'value': '' }, _('All')),
|
||||
E('option', { 'value': 'trace' }, 'TRACE'),
|
||||
E('option', { 'value': 'debug' }, 'DEBUG'),
|
||||
E('option', { 'value': 'info' }, 'INFO'),
|
||||
E('option', { 'value': 'warn' }, 'WARN'),
|
||||
E('option', { 'value': 'error' }, 'ERROR'),
|
||||
E('option', { 'value': 'alive' }, _('Node Status')),
|
||||
E('option', { 'value': 'my_group' }, _('Proxy Traffic'))
|
||||
E('option', { 'value': 'node_status' }, _('Node Status')),
|
||||
E('option', { 'value': 'proxy_traffic' }, _('Proxy Traffic'))
|
||||
]);
|
||||
selFilter.addEventListener('change', function() {
|
||||
state.filter = selFilter.value;
|
||||
@@ -271,7 +295,7 @@ return view.extend({
|
||||
function applyFilter() {
|
||||
const f = state.filter;
|
||||
pane.querySelectorAll('.dd-line').forEach(function(el) {
|
||||
if (!f || el.textContent.toLowerCase().indexOf(f) !== -1)
|
||||
if (matchesFilter(el.textContent, f))
|
||||
el.classList.remove('dd-hidden');
|
||||
else
|
||||
el.classList.add('dd-hidden');
|
||||
@@ -285,7 +309,7 @@ return view.extend({
|
||||
const ln = lines[i];
|
||||
if (!ln) continue;
|
||||
const el = buildLine(ln);
|
||||
if (state.filter && ln.toLowerCase().indexOf(state.filter) === -1)
|
||||
if (!matchesFilter(ln, state.filter))
|
||||
el.classList.add('dd-hidden');
|
||||
frag.appendChild(el);
|
||||
}
|
||||
|
||||
@@ -156,6 +156,13 @@ function renderStatusCard(ctx, listenAddr) {
|
||||
let busy = false;
|
||||
let lastError = '';
|
||||
let refreshGeneration = 0;
|
||||
const probeState = {
|
||||
running: false,
|
||||
text: '',
|
||||
kind: '',
|
||||
visibleUntil: 0,
|
||||
hideTimer: null
|
||||
};
|
||||
const body = E('div', { 'id': 'dd-status-body' }, E('em', {}, _('Collecting data…')));
|
||||
const card = E('div', { 'class': 'dd-card dd-status-card' }, [
|
||||
E('h4', { 'class': 'dd-card-title' }, _('Service Status')),
|
||||
@@ -265,13 +272,28 @@ function renderStatusCard(ctx, listenAddr) {
|
||||
}
|
||||
if (state.running && be.name === 'dae') {
|
||||
const ckBtn = E('button', { 'class': 'cbi-button cbi-button-action' }, _('Test YouTube'));
|
||||
const ckRes = E('span', { 'class': 'dd-meta', style: 'margin-left:8px;display:none' }, '');
|
||||
const probeVisible = probeState.running || probeState.visibleUntil > Date.now();
|
||||
const ckRes = E('span', {
|
||||
'class': 'dd-meta' + (probeState.kind ? ' ' + probeState.kind : ''),
|
||||
style: 'margin-left:8px;' + (probeVisible ? '' : 'display:none')
|
||||
}, probeState.text);
|
||||
ckBtn.disabled = probeState.running;
|
||||
ckBtn.addEventListener('click', function(ev) {
|
||||
ev.preventDefault();
|
||||
if (probeState.running)
|
||||
return;
|
||||
if (probeState.hideTimer) {
|
||||
clearTimeout(probeState.hideTimer);
|
||||
probeState.hideTimer = null;
|
||||
}
|
||||
probeState.running = true;
|
||||
probeState.text = _('Testing…');
|
||||
probeState.kind = '';
|
||||
probeState.visibleUntil = 0;
|
||||
ckBtn.disabled = true;
|
||||
ckRes.style.display = 'inline';
|
||||
ckRes.classList.remove('dd-ok', 'dd-err');
|
||||
ckRes.textContent = _('Testing…');
|
||||
ckRes.textContent = probeState.text;
|
||||
/* actually probe YouTube through dae's transparent proxy */
|
||||
fs.exec('/usr/share/luci-app-daede/proxy-check.sh', []).then(function(r) {
|
||||
const out = (r && r.stdout) || '';
|
||||
@@ -279,20 +301,28 @@ function renderStatusCard(ctx, listenAddr) {
|
||||
const code = (out.match(/code=(\S+)/) || [])[1] || '000';
|
||||
const ms = parseInt((out.match(/ms=(\d+)/) || [])[1] || '0');
|
||||
if (ok) {
|
||||
ckRes.classList.add('dd-ok');
|
||||
ckRes.textContent = _('YouTube reachable · %d ms').format(ms);
|
||||
probeState.kind = 'dd-ok';
|
||||
probeState.text = _('YouTube reachable · %d ms').format(ms);
|
||||
} else {
|
||||
ckRes.classList.add('dd-err');
|
||||
ckRes.textContent = (code === '000')
|
||||
probeState.kind = 'dd-err';
|
||||
probeState.text = (code === '000')
|
||||
? _('YouTube unreachable (timeout)')
|
||||
: _('YouTube unreachable (HTTP %s)').format(code);
|
||||
}
|
||||
}).catch(function() {
|
||||
ckRes.classList.add('dd-err');
|
||||
ckRes.textContent = _('YouTube unreachable (timeout)');
|
||||
probeState.kind = 'dd-err';
|
||||
probeState.text = _('YouTube unreachable (timeout)');
|
||||
}).finally(function() {
|
||||
ckBtn.disabled = false;
|
||||
setTimeout(function() { ckRes.style.display = 'none'; }, 8000);
|
||||
probeState.running = false;
|
||||
probeState.visibleUntil = Date.now() + 8000;
|
||||
refresh(true);
|
||||
probeState.hideTimer = setTimeout(function() {
|
||||
probeState.text = '';
|
||||
probeState.kind = '';
|
||||
probeState.visibleUntil = 0;
|
||||
probeState.hideTimer = null;
|
||||
refresh(true);
|
||||
}, 8000);
|
||||
});
|
||||
});
|
||||
actions.push(ckBtn);
|
||||
@@ -314,7 +344,11 @@ function renderStatusCard(ctx, listenAddr) {
|
||||
|
||||
poll.add(refresh);
|
||||
refresh();
|
||||
card._ddCleanup = function() { poll.remove(refresh); };
|
||||
card._ddCleanup = function() {
|
||||
poll.remove(refresh);
|
||||
if (probeState.hideTimer)
|
||||
clearTimeout(probeState.hideTimer);
|
||||
};
|
||||
return card;
|
||||
}
|
||||
|
||||
|
||||
@@ -891,3 +891,9 @@ msgstr ""
|
||||
|
||||
msgid "TTL returned to LAN DNS clients. 0 keeps dae default behavior."
|
||||
msgstr ""
|
||||
|
||||
msgid "Log level"
|
||||
msgstr ""
|
||||
|
||||
msgid "Debug and trace show per-connection routing details, but increase CPU usage and log volume. Enable them only while troubleshooting."
|
||||
msgstr ""
|
||||
@@ -663,6 +663,12 @@ msgstr "代理流量"
|
||||
msgid "Logging"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Log level"
|
||||
msgstr "日志级别"
|
||||
|
||||
msgid "Debug and trace show per-connection routing details, but increase CPU usage and log volume. Enable them only while troubleshooting."
|
||||
msgstr "Debug 和 Trace 会显示逐连接的分流详情,但会增加 CPU 占用和日志量,仅建议排障时启用。"
|
||||
|
||||
msgid "Save manual config"
|
||||
msgstr "保存手动配置"
|
||||
|
||||
|
||||
@@ -663,6 +663,12 @@ msgstr "代理流量"
|
||||
msgid "Logging"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Log level"
|
||||
msgstr "日志级别"
|
||||
|
||||
msgid "Debug and trace show per-connection routing details, but increase CPU usage and log volume. Enable them only while troubleshooting."
|
||||
msgstr "Debug 和 Trace 会显示逐连接的分流详情,但会增加 CPU 占用和日志量,仅建议排障时启用。"
|
||||
|
||||
msgid "Save manual config"
|
||||
msgstr "保存手动配置"
|
||||
|
||||
|
||||
Reference in new issue
Block a user