Última atividade 1 month ago

nuno revisou este gist 1 month ago. Ir para a revisão

1 file changed, 276 insertions

gistfile1.txt(arquivo criado)

@@ -0,0 +1,276 @@
1 + function cmd::activity::run() {
2 + local filter_peer="" filter_service="" filter_ip="" filter_type=""
3 + local hours=24 dropped_only=false
4 + local accept_only=false drop_only=false external_only=false
5 +
6 + while [[ $# -gt 0 ]]; do
7 + case "$1" in
8 + --peer) filter_peer="$2"; shift 2 ;;
9 + --service) filter_service="$2"; shift 2 ;;
10 + --ip) filter_ip="$2"; shift 2 ;;
11 + --type) filter_type="$2"; shift 2 ;;
12 + --hours) hours="$2"; shift 2 ;;
13 + --dropped) dropped_only=true; shift ;;
14 + --accept) accept_only=true; shift ;;
15 + --drop) drop_only=true; shift ;;
16 + --external) external_only=true; shift ;;
17 + --help) cmd::activity::help; return ;;
18 + *)
19 + log::error "Unknown flag: $1"
20 + cmd::activity::help
21 + return 1
22 + ;;
23 + esac
24 + done
25 +
26 + if command::json; then
27 + cmd::activity::_output_json "$hours"
28 + return 0
29 + fi
30 +
31 + # Resolve peer name if type provided
32 + if [[ -n "$filter_peer" && -n "$filter_type" ]]; then
33 + filter_peer=$(peers::resolve_and_require "$filter_peer" "$filter_type") || return 1
34 + fi
35 +
36 + # Resolve --service to IP
37 + local service_ip=""
38 + if [[ -n "$filter_service" ]]; then
39 + service_ip=$(net::resolve "$filter_service" 2>/dev/null | head -1 | cut -d: -f1) || true
40 + if [[ -z "$service_ip" ]]; then
41 + log::error "Service not found: ${filter_service}"
42 + return 1
43 + fi
44 + fi
45 + [[ -n "$filter_ip" ]] && service_ip="$filter_ip"
46 +
47 + # Fetch drop/handshake data
48 + local data=""
49 + if ! $accept_only; then
50 + data=$(json::activity_aggregate \
51 + "$(ctx::fw_events_log)" \
52 + "$(ctx::events_log)" \
53 + "$(config::interface)" \
54 + "$(ctx::net)" \
55 + "$(ctx::clients)" \
56 + "$(ctx::meta)" \
57 + "$hours" \
58 + "$filter_peer" \
59 + "$service_ip" 2>/dev/null)
60 + fi
61 +
62 + # Fetch accept data
63 + local accept_data=""
64 + if ! $drop_only; then
65 + local since_arg=""
66 + [[ "$hours" -gt 0 ]] && since_arg="${hours}h"
67 + local ext_flag="0"
68 + $external_only && ext_flag="1"
69 + [[ -f "$(ctx::accept_events_log)" ]] && \
70 + accept_data=$(json::accept_aggregate \
71 + "$(ctx::accept_events_log)" \
72 + "$(ctx::net)" \
73 + "$(ctx::clients)" \
74 + "$since_arg" \
75 + "$filter_peer" \
76 + "$ext_flag" \
77 + 2>/dev/null)
78 + fi
79 +
80 + if [[ -z "$data" && -z "$accept_data" ]]; then
81 + log::wg_warning "No activity data found"
82 + return 0
83 + fi
84 +
85 + # Build accept lookup maps
86 + declare -gA _ACCEPT_PEER=()
87 + declare -gA _ACCEPT_DEST_KEYS=()
88 + declare -gA _ACCEPT_DEST=()
89 +
90 + while IFS='|' read -r type rest; do
91 + [[ -z "$type" ]] && continue
92 + case "$type" in
93 + peer)
94 + local a_name a_bi a_bo a_pi a_po a_conns
95 + IFS='|' read -r a_name a_bi a_bo a_pi a_po a_conns <<< "$rest"
96 + _ACCEPT_PEER["$a_name"]="${a_bi}|${a_bo}|${a_pi}|${a_po}|${a_conns}"
97 + ;;
98 + dest)
99 + local d_peer d_ip d_port d_proto d_bytes d_count
100 + IFS='|' read -r d_peer d_ip d_port d_proto d_bytes d_count <<< "$rest"
101 + local d_key="${d_peer}:${d_ip}:${d_port}:${d_proto}"
102 + _ACCEPT_DEST["$d_key"]="${d_bytes}|${d_count}"
103 + _ACCEPT_DEST_KEYS["$d_peer"]+="${d_key} "
104 + ;;
105 + esac
106 + done <<< "$accept_data"
107 +
108 + # Measure column widths
109 + local w_peer=16 w_drops=1
110 + while IFS='|' read -r type rest; do
111 + case "$type" in
112 + peer)
113 + local name drops
114 + name=$(echo "$rest" | cut -d'|' -f1)
115 + drops=$(echo "$rest" | cut -d'|' -f4)
116 + (( ${#name} > w_peer )) && w_peer=${#name}
117 + (( ${#drops} > w_drops )) && w_drops=${#drops}
118 + ;;
119 + service)
120 + local count
121 + count=$(echo "$rest" | cut -d'|' -f3)
122 + (( ${#count} > w_drops )) && w_drops=${#count}
123 + ;;
124 + esac
125 + done <<< "$data"
126 +
127 + for a_name in "${!_ACCEPT_PEER[@]}"; do
128 + (( ${#a_name} > w_peer )) && w_peer=${#a_name}
129 + done
130 +
131 + (( w_peer += 2 ))
132 + local drops_col=$(( w_peer + 30 ))
133 +
134 + local hours_display="${hours}h"
135 + [[ "$hours" == "0" ]] && hours_display="all time"
136 +
137 + log::section "Activity Monitor (last ${hours_display})"
138 + echo ""
139 +
140 + if display::is_table "activity"; then
141 + cmd::activity::_render_table "$data"
142 + return 0
143 + fi
144 +
145 + # Helper — render accept dests for a peer inline
146 + _render_peer_accept_dests() {
147 + local peer_name="$1"
148 + local keys="${_ACCEPT_DEST_KEYS[$peer_name]:-}"
149 + [[ -z "$keys" ]] && return 0
150 + for d_key in $keys; do
151 + local dest_stats="${_ACCEPT_DEST[$d_key]:-}"
152 + [[ -z "$dest_stats" ]] && continue
153 + local d_bytes d_count
154 + IFS='|' read -r d_bytes d_count <<< "$dest_stats"
155 + local rest_key="${d_key#${peer_name}:}"
156 + local d_ip d_port d_proto
157 + d_ip="${rest_key%%:*}"
158 + local pp="${rest_key#*:}"
159 + d_port="${pp%%:*}"
160 + d_proto="${pp##*:}"
161 + local dest_display
162 + dest_display=$(resolve::dest "$d_ip" "$d_port" "$d_proto" 2>/dev/null \
163 + || echo "${d_ip}:${d_port}/${d_proto}")
164 + local bytes_fmt
165 + bytes_fmt=$(fmt::bytes "$d_bytes")
166 + ui::activity::accept_dest_row \
167 + "$dest_display" "$d_bytes" "$bytes_fmt" \
168 + "$d_count" "$drops_col" "$w_drops"
169 + done
170 + }
171 +
172 + local first_peer=true skip_peer=false current_name=""
173 + local -a rendered_peers=()
174 +
175 + while IFS='|' read -r record_type rest; do
176 + case "$record_type" in
177 + peer)
178 + local name rx tx drops
179 + IFS='|' read -r name rx tx drops <<< "$rest"
180 +
181 + # Flush previous peer's accept dests before starting new peer
182 + if [[ -n "$current_name" ]] && ! $drop_only; then
183 + _render_peer_accept_dests "$current_name"
184 + fi
185 +
186 + skip_peer=false
187 + current_name="$name"
188 + local has_accept="${_ACCEPT_PEER[$name]:-}"
189 +
190 + if $dropped_only && [[ "$drops" -eq 0 ]] && [[ -z "$has_accept" ]]; then
191 + skip_peer=true
192 + continue
193 + fi
194 +
195 + $first_peer || echo ""
196 + first_peer=false
197 + rendered_peers+=("$name")
198 +
199 + local rx_fmt tx_fmt
200 + rx_fmt=$(fmt::bytes "$rx")
201 + tx_fmt=$(fmt::bytes "$tx")
202 +
203 + local name_pad rx_pad tx_pad
204 + name_pad=$(printf "%-${w_peer}s" "$name")
205 + rx_pad=$(printf "%-10s" "$rx_fmt")
206 + tx_pad=$(printf "%-10s" "$tx_fmt")
207 +
208 + local drop_word="drops"
209 + [[ "$drops" -eq 1 ]] && drop_word="drop"
210 +
211 + if ! $accept_only; then
212 + ui::activity::peer_row \
213 + "$name_pad" "$rx_pad" "$tx_pad" "$drops" "$drop_word" "$w_drops"
214 + fi
215 +
216 + # Accept summary row
217 + if [[ -n "$has_accept" ]] && ! $drop_only; then
218 + local a_bi a_bo a_pi a_po a_conns
219 + IFS='|' read -r a_bi a_bo a_pi a_po a_conns <<< "$has_accept"
220 + local a_in_fmt a_out_fmt
221 + a_in_fmt=$(fmt::bytes "$a_bi")
222 + a_out_fmt=$(fmt::bytes "$a_bo")
223 + ui::activity::accept_row \
224 + "$name_pad" "$a_in_fmt" "$a_out_fmt" "$a_conns" "$w_drops"
225 + fi
226 + ;;
227 +
228 + service)
229 + $skip_peer && continue
230 + local peer dest_display drop_count
231 + IFS='|' read -r peer dest_display drop_count <<< "$rest"
232 + local svc_drop_word="drops"
233 + [[ "$drop_count" -eq 1 ]] && svc_drop_word="drop"
234 + if ! $accept_only; then
235 + ui::activity::service_row \
236 + "$dest_display" "$drop_count" "$svc_drop_word" "$drops_col" "$w_drops"
237 + fi
238 + ;;
239 + esac
240 + done <<< "$data"
241 +
242 + # Flush last peer's accept dests
243 + if [[ -n "$current_name" ]] && ! $drop_only; then
244 + _render_peer_accept_dests "$current_name"
245 + fi
246 +
247 + # Accept-only peers — not in drop data, render separately
248 + if ! $drop_only; then
249 + for a_name in $(echo "${!_ACCEPT_PEER[@]}" | tr ' ' '\n' | sort); do
250 + local already=false
251 + for rp in "${rendered_peers[@]:-}"; do
252 + [[ "$rp" == "$a_name" ]] && already=true && break
253 + done
254 + $already && continue
255 +
256 + $first_peer || echo ""
257 + first_peer=false
258 +
259 + local a_stats="${_ACCEPT_PEER[$a_name]}"
260 + local a_bi a_bo a_pi a_po a_conns
261 + IFS='|' read -r a_bi a_bo a_pi a_po a_conns <<< "$a_stats"
262 + local a_in_fmt a_out_fmt
263 + a_in_fmt=$(fmt::bytes "$a_bi")
264 + a_out_fmt=$(fmt::bytes "$a_bo")
265 + local name_pad
266 + name_pad=$(printf "%-${w_peer}s" "$a_name")
267 + local a_in_pad a_out_pad
268 + a_in_pad=$(printf "%-10s" "$a_in_fmt")
269 + a_out_pad=$(printf "%-10s" "$a_out_fmt")
270 + ui::activity::accept_row \
271 + "$name_pad" "$a_in_pad" "$a_out_pad" "$a_conns" "$w_drops"
272 + done
273 + fi
274 +
275 + echo ""
276 + }
Próximo Anterior