Files
fn_registry/bash/functions/infra/telemetry_prelude.sh
T
egutierrez cfdf515228 chore: auto-commit (799 archivos)
- .claude/CLAUDE.md
- .claude/commands/subagentes.md
- .claude/rules/INDEX.md
- .mcp.json
- bash/functions/cybersecurity/analyze_dns.md
- bash/functions/cybersecurity/audit_http_headers.md
- bash/functions/cybersecurity/audit_ssh_config.md
- bash/functions/cybersecurity/check_firewall.md
- bash/functions/cybersecurity/detect_suspicious_users.md
- bash/functions/cybersecurity/encrypt_file.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 00:28:20 +02:00

125 lines
3.8 KiB
Bash

#!/usr/bin/env bash
# telemetry_prelude — Wrapper de telemetria para funciones bash del registry.
# Issue 0085c-bash.
#
# Uso 1 (manual): source bash/functions/<dom>/<fn>.sh primero, despues source
# este archivo, y todas las funciones bash del registry
# quedaran envueltas con logging a call_monitor.operations.db.
#
# Uso 2 (auto): exportar FN_TELEMETRY=1 antes de sourcear; este prelude
# detecta cada funcion definida que coincida con una funcion
# del registry (bash/functions/<dom>/<name>.sh) y la
# redefine como wrapper.
#
# Reglas:
# - Idempotente: marca cada wrapper con flag _FN_T_WRAPPED_<name>=1; no
# re-envuelve si ya esta envuelta.
# - No-op silencioso si BD no existe o INSERT falla. NUNCA aborta el caller.
# - Solo guarda function_id, duration_ms, success, error_class. NUNCA args.
if [ "${FN_TELEMETRY:-0}" != "1" ]; then
return 0 2>/dev/null || exit 0
fi
# ---- Resolve registry root ----
_fn_t_root() {
if [ -n "${FN_REGISTRY_ROOT:-}" ] && [ -f "$FN_REGISTRY_ROOT/registry.db" ]; then
printf '%s' "$FN_REGISTRY_ROOT"
return 0
fi
local d="${PWD}"
while [ "$d" != "/" ]; do
if [ -f "$d/registry.db" ]; then
printf '%s' "$d"
return 0
fi
d=$(dirname "$d")
done
return 1
}
# ---- Resolve operations.db ----
_FN_T_DB=""
_fn_t_resolve_db() {
if [ -n "$_FN_T_DB" ] && [ -f "$_FN_T_DB" ]; then return 0; fi
local root
root=$(_fn_t_root) || return 1
_FN_T_DB="$root/projects/fn_monitoring/apps/call_monitor/operations.db"
if [ ! -f "$_FN_T_DB" ]; then
_FN_T_DB=""
return 1
fi
return 0
}
# ---- Log call ----
_fn_t_log() {
local fn_id="$1" duration_ms="$2" success="$3" error_class="${4:-}"
_fn_t_resolve_db || return 0
command -v sqlite3 >/dev/null 2>&1 || return 0
local sid="${CLAUDE_SESSION_ID:-}"
local ts
ts=$(date -u +%s)
sid="${sid//\'/\'\'}"
fn_id="${fn_id//\'/\'\'}"
error_class="${error_class//\'/\'\'}"
sqlite3 "$_FN_T_DB" "INSERT INTO calls (session_id, function_id, tool_used, args_hash, duration_ms, success, error_class, error_snippet, ts) VALUES ('$sid','$fn_id','bash_wrapper','',$duration_ms,$success,'$error_class','',$ts);" 2>/dev/null || true
}
# ---- Wrap a single function by name ----
_fn_t_wrap() {
local orig="$1" fn_id="$2"
# already wrapped?
local guard
guard="_FN_T_WRAPPED_${orig}"
if [ "${!guard:-0}" = "1" ]; then return 0; fi
# must exist as a function
declare -F "$orig" >/dev/null 2>&1 || return 1
# capture original body, rename to _fn_t_orig_<name>
local body
body=$(declare -f "$orig") || return 1
# body starts with "<orig> ()"; prepend prefix to rename
local renamed="_fn_t_orig_${body}"
eval "$renamed"
# define wrapper with the original name
eval "
${orig}() {
local _t0_ms _t1_ms _rc _dur
_t0_ms=\$(date +%s%3N)
_fn_t_orig_${orig} \"\$@\"
_rc=\$?
_t1_ms=\$(date +%s%3N)
_dur=\$((_t1_ms - _t0_ms))
if [ \$_rc -eq 0 ]; then
_fn_t_log \"${fn_id}\" \$_dur 1 \"\"
else
_fn_t_log \"${fn_id}\" \$_dur 0 \"exit_\$_rc\"
fi
return \$_rc
}
"
eval "$guard=1"
}
# ---- Auto-wrap: walk bash/functions and wrap every function currently defined ----
_fn_t_autowrap() {
local root
root=$(_fn_t_root) || return 1
local f domain name fn_id
while IFS= read -r f; do
domain=$(basename "$(dirname "$f")")
name=$(basename "$f" .sh)
fn_id="${name}_bash_${domain}"
if declare -F "$name" >/dev/null 2>&1; then
_fn_t_wrap "$name" "$fn_id"
fi
done < <(find "$root/bash/functions" -type f -name '*.sh' 2>/dev/null)
}
# ---- Run autowrap on source ----
_fn_t_autowrap