mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-31 00:55:13 +08:00
🦄 Sync 2026-09-27 22:25:23
This commit is contained in:
1 parent
67a7165b7e
commit
4c6d0df36f
67 files changed
+415
-8397
No files matched your search
@@ -197,7 +197,7 @@ function summary_json(out) {
|
||||
out = out ",\"top_drops\":" summary_top(summary_drop_counts, 3)
|
||||
out = out ",\"top_rules\":" summary_top(summary_rule_counts, 3) "}"
|
||||
# LC_ALL=C makes this a byte budget; utf8_prefix keeps field cuts valid.
|
||||
if (length(out) > 256) return "{\"scope\":\"top of shown sample\",\"truncated\":true}"
|
||||
if (length(out) > 1024) return "{\"scope\":\"top of shown sample\",\"truncated\":true}"
|
||||
return out
|
||||
}
|
||||
BEGIN {
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
# Log messages are treated as data (jsonfilter + awk stdin); never interpolated
|
||||
# into shell command strings. Usage: ubus call log read '...' | fwlive-log-filter.sh
|
||||
#
|
||||
# Performance: one jsonfilter for @.log[*] plus one awk classify. The same
|
||||
# awk pass counts enumerated entries for messages_received; process count is
|
||||
# constant per poll, not O(entries).
|
||||
# Performance: one jsonfilter for @.log[*] plus one awk classify. An empty
|
||||
# @.log array pays a second jsonfilter -t to tell healthy empty from a
|
||||
# parse failure. The same awk pass counts enumerated entries for
|
||||
# messages_received; process count is not O(entries).
|
||||
#
|
||||
# Entry point (pipeline). The classifier sibling is sourced and must not set
|
||||
# strict mode itself.
|
||||
@@ -37,10 +38,12 @@ fi
|
||||
# (or paused FETCH_LINES_MAX poll) can exceed that and make jsonfilter fail
|
||||
# while this script still returns a valid empty result.
|
||||
# A valid input with no log entries is not fatal; the classifier closes JSON
|
||||
# and reports messages_received:0. A jsonfilter failure is different:
|
||||
# it must remain an error so rpcd does not record a fast healthy sample. Keep
|
||||
# jsonfilter output in a secure temporary file before classification so a
|
||||
# partial pipeline cannot produce malformed JSON on failure.
|
||||
# and reports messages_received:0. OpenWrt jsonfilter exits 1 when @.log[*]
|
||||
# matches nothing, including a real empty array, so that rc alone is not a
|
||||
# parse failure. A missing log key or malformed JSON must remain an error so
|
||||
# rpcd does not record a fast healthy sample. Keep jsonfilter output in a
|
||||
# secure temporary file before classification so a partial pipeline cannot
|
||||
# produce malformed JSON on failure.
|
||||
# This script runs from rpcd as root and reopens the path for classification.
|
||||
# Match _fwlive_mktemp: only use a verified, sticky dump directory. The
|
||||
# production rpcd caller passes /tmp; the explicit argument lets host tests
|
||||
@@ -50,17 +53,40 @@ if [ ! -d "$FILTER_TMP_DIR" ] || [ -L "$FILTER_TMP_DIR" ] || ! [ -k "$FILTER_TMP
|
||||
printf '%s' '{"log":[],"error":"filter_tempfile_failed"}'
|
||||
exit 1
|
||||
fi
|
||||
_filter_tmp=$(mktemp "$FILTER_TMP_DIR/fwlive-filter.XXXXXX") || {
|
||||
_filter_in=$(mktemp "$FILTER_TMP_DIR/fwlive-filter-in.XXXXXX") || {
|
||||
printf '%s' '{"log":[],"error":"filter_tempfile_failed"}'
|
||||
exit 1
|
||||
}
|
||||
trap 'rm -f "$_filter_tmp"' 0
|
||||
trap 'rm -f "$_filter_tmp"; exit 129' 1
|
||||
trap 'rm -f "$_filter_tmp"; exit 130' 2
|
||||
trap 'rm -f "$_filter_tmp"; exit 131' 3
|
||||
trap 'rm -f "$_filter_tmp"; exit 143' 15
|
||||
if ! jsonfilter -e '@.log[*]' >"$_filter_tmp" 2>/dev/null; then
|
||||
_filter_tmp=$(mktemp "$FILTER_TMP_DIR/fwlive-filter.XXXXXX") || {
|
||||
rm -f "$_filter_in"
|
||||
printf '%s' '{"log":[],"error":"filter_tempfile_failed"}'
|
||||
exit 1
|
||||
}
|
||||
trap 'rm -f "$_filter_in" "$_filter_tmp"' 0
|
||||
trap 'rm -f "$_filter_in" "$_filter_tmp"; exit 129' 1
|
||||
trap 'rm -f "$_filter_in" "$_filter_tmp"; exit 130' 2
|
||||
trap 'rm -f "$_filter_in" "$_filter_tmp"; exit 131' 3
|
||||
trap 'rm -f "$_filter_in" "$_filter_tmp"; exit 143' 15
|
||||
cat >"$_filter_in" || {
|
||||
printf '%s' '{"log":[],"error":"filter_failed"}'
|
||||
exit 1
|
||||
}
|
||||
_jf_rc=0
|
||||
jsonfilter -e '@.log[*]' <"$_filter_in" >"$_filter_tmp" 2>/dev/null || _jf_rc=$?
|
||||
if [ "$_jf_rc" -ne 0 ]; then
|
||||
# Empty @.log array: extract rc=1 and empty stdout on OpenWrt jsonfilter.
|
||||
# Confirm the member is an array before treating it as a healthy empty poll.
|
||||
if [ ! -s "$_filter_tmp" ]; then
|
||||
_log_type=$(jsonfilter -t '@.log' <"$_filter_in" 2>/dev/null) || _log_type=
|
||||
if [ "$_log_type" = "array" ]; then
|
||||
: >"$_filter_tmp"
|
||||
else
|
||||
printf '%s' '{"log":[],"error":"filter_failed"}'
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
printf '%s' '{"log":[],"error":"filter_failed"}'
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
_fwlive_filter_json_reply <"$_filter_tmp"
|
||||
@@ -263,8 +263,8 @@ EOF
|
||||
|
||||
# One awk pass: prefix<TAB>comment. Last quoted log prefix / comment on
|
||||
# the line, including \" units (same capture as the former sed).
|
||||
# Raw tabs in prefix/comment become the two-character sequence \t so the
|
||||
# separator tab is unique. Backslashes are not re-encoded.
|
||||
# Raw tabs become \t and backslashes become \\ so the separator tab is
|
||||
# unique. Walk bytes: BusyBox awk ≥1.37 gsub cannot emit those sequences.
|
||||
nft_dump_fields() {
|
||||
LC_ALL=C awk '
|
||||
function last_at(s, needle, p, i, found) {
|
||||
@@ -276,6 +276,22 @@ nft_dump_fields() {
|
||||
}
|
||||
return found
|
||||
}
|
||||
function tsv_escape(s, out, i, n, c) {
|
||||
# BusyBox awk ≥1.37 treats gsub replacement "\\t" as a tab
|
||||
# (and "\\\\" as one backslash). Walk bytes instead.
|
||||
out = ""
|
||||
n = length(s)
|
||||
for (i = 1; i <= n; i++) {
|
||||
c = substr(s, i, 1)
|
||||
if (c == "\\")
|
||||
out = out "\\\\"
|
||||
else if (c == "\t")
|
||||
out = out "\\t"
|
||||
else
|
||||
out = out c
|
||||
}
|
||||
return out
|
||||
}
|
||||
function quoted_at(s, needle, i, rest, out, c, n, esc, j) {
|
||||
i = last_at(s, needle)
|
||||
if (i == 0)
|
||||
@@ -307,10 +323,8 @@ nft_dump_fields() {
|
||||
comment = quoted_at($0, "comment \"")
|
||||
if (prefix == "" && comment == "")
|
||||
next
|
||||
gsub(/\\/, "\\\\", prefix)
|
||||
gsub(/\t/, "\\t", prefix)
|
||||
gsub(/\\/, "\\\\", comment)
|
||||
gsub(/\t/, "\\t", comment)
|
||||
prefix = tsv_escape(prefix)
|
||||
comment = tsv_escape(comment)
|
||||
print prefix "\t" comment
|
||||
}
|
||||
' || return 1
|
||||
|
||||
Reference in new issue
Block a user