补测:行为检测支持历史区间;特征扫描自动时间切片;历史画像保留

This commit is contained in:
DeepFal committed 2026-10-19 12:51:04 +08:00
1 parent d78eabc458
commit 897828f506
5 files changed
+229 -18

No files matched your search

+38 -5
View File
@@ -345,7 +345,8 @@ class Store:
country_code TEXT, country_name TEXT, region TEXT, city TEXT
)"""
)
for column in ("asn_brand TEXT", "asn_type TEXT", "asn_icon TEXT"):
for column in ("asn_brand TEXT", "asn_type TEXT", "asn_icon TEXT",
"historical INTEGER DEFAULT 0"):
try:
self.conn.execute(
"ALTER TABLE behavior_profiles ADD COLUMN %s" % column)
@@ -497,10 +498,40 @@ class Store:
return item
# ---------------------------------------------------------- behaviour
def upsert_historical_profiles(self, items):
"""Insert backfilled behaviour profiles; live rows win on conflict."""
stamp = now_iso()
with self.lock, self.conn:
for item in items:
self.conn.execute(
"""INSERT OR IGNORE INTO behavior_profiles
(ip, score, verdict, signals, reason_text, share_note,
behavior_type, asn, asn_org, shared_type, asn_brand,
asn_type, asn_icon, total, pct4, uri_card, uri_templates,
ua_card, host_card, coverage, peak_share, top_uri, top_ua,
last_ts, updated_at, country_code, country_name, region,
city, historical)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,1)""",
(item["ip"], item.get("score"), item.get("verdict"),
json.dumps(item.get("signals") or [], ensure_ascii=False),
item.get("reason_text"), item.get("share_note"),
item.get("behavior_type"), item.get("asn"),
item.get("asn_org"), item.get("shared_type"),
item.get("asn_brand"), item.get("asn_type"),
item.get("asn_icon"), int(item.get("total") or 0),
item.get("pct4"), item.get("uri_card"),
item.get("uri_templates"), item.get("ua_card"),
item.get("host_card"), item.get("coverage"),
item.get("peak_share"), item.get("top_uri"),
item.get("top_ua"), item.get("last_ts") or stamp, stamp,
item.get("country_code"), item.get("country_name"),
item.get("region"), item.get("city")))
def replace_behavior_profiles(self, items):
stamp = now_iso()
with self.lock, self.conn:
self.conn.execute("DELETE FROM behavior_profiles")
self.conn.execute(
"DELETE FROM behavior_profiles WHERE COALESCE(historical,0)=0")
for item in items:
self.conn.execute(
"""INSERT OR REPLACE INTO behavior_profiles
@@ -509,8 +540,8 @@ class Store:
asn_type, asn_icon, total, pct4, uri_card, uri_templates,
ua_card, host_card, coverage, peak_share, top_uri, top_ua,
last_ts, updated_at, country_code, country_name, region,
city)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
city, historical)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0)""",
(item["ip"], item.get("score"), item.get("verdict"),
json.dumps(item.get("signals") or [], ensure_ascii=False),
item.get("reason_text"), item.get("share_note"),
@@ -649,11 +680,13 @@ class Store:
if beh["verdict"] != "建议封禁" or ip in wanted:
continue
prev = existing.get(ip)
historical = bool(beh["historical"]) if "historical" in beh.keys() else False
fallback = (beh["last_ts"] if historical and beh["last_ts"] else now)
wanted[ip] = {
"sources": "behavior",
"feature_score": None,
"behavior_score": beh["score"],
"first_banned_at": prev["first_banned_at"] if prev else now,
"first_banned_at": prev["first_banned_at"] if prev else fallback,
"last_activity_at": iso(beh["last_ts"]),
"fused_reason": "行为表现:" + (beh["reason_text"] or ""),
}