feat(syslog): a device through Docker's address is placed by its name, or a device address set on it (#6096)
The SNMP poll asks each device's sysName in the same GET and keeps it (snmp_003_sys_name). A syslog source told apart by name finds its own address from the SNMP device (reported or given name) or host of that name, so its lines reach the SNMP device's and host's pages again; the edit page gains Device address, which always wins (syslog_004). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,8 @@ from .patterns import (PRESETS, PRESETS_BY_KEY, SOURCE_MODULE, WINDOWS, PatternE
|
||||
resource_of)
|
||||
from .receiver import LISTENER, MAX_SENDERS, send_to, settings
|
||||
from .service import (AROUND_LINES, AROUND_SEVERITY, MARK_SEVERITY, MAX_MARKS, PANEL_LINES, PANEL_SPAN,
|
||||
SEVERITY_CHOICES, apps_of, filtered, line_filter, lines_between, place_for, rates, shown_on,
|
||||
SEVERITY_CHOICES, addresses_by_name, apps_of, device_address, filtered, line_filter,
|
||||
lines_between, place_for, rates, shown_on,
|
||||
source_name)
|
||||
|
||||
syslog_bp = Blueprint("syslog", __name__, template_folder="templates")
|
||||
@@ -53,9 +54,11 @@ def listener_view(port: int, udp: bool, tcp: bool) -> dict:
|
||||
"senders_full": False, "max_senders": MAX_SENDERS}
|
||||
|
||||
|
||||
def source_view(s: SyslogSource, hosts: dict, rate: int | None = None) -> dict:
|
||||
def source_view(s: SyslogSource, hosts: dict, rate: int | None = None, named: dict | None = None) -> dict:
|
||||
host = hosts.get(s.host_id) if s.host_id else None
|
||||
own = device_address(s, named)
|
||||
return {"id": s.id, "address": s.address, "sender": s.sender, "state": s.state, "rate": rate,
|
||||
"device_address": own if own != s.address else "",
|
||||
"docker_address": on_own_network(s.address),
|
||||
"name": s.name or s.hostname_seen or s.address,
|
||||
"hostname_seen": s.hostname_seen, "host": host,
|
||||
@@ -82,10 +85,11 @@ async def index():
|
||||
select(SyslogSource).order_by(SyslogSource.last_seen_at.desc()))).scalars())
|
||||
hosts = await _hosts(db)
|
||||
per_hour = await rates(db, [r.id for r in rows if r.state == "accepted"])
|
||||
named = await addresses_by_name(db) if any(r.sender for r in rows) else None
|
||||
by_id = {h.id: h for h in hosts}
|
||||
views = {state: [] for state in ("accepted", "offered", "ignored")}
|
||||
for row in rows:
|
||||
v = source_view(row, by_id, per_hour.get(row.id, 0) if row.state == "accepted" else None)
|
||||
v = source_view(row, by_id, per_hour.get(row.id, 0) if row.state == "accepted" else None, named)
|
||||
if row.state == "offered":
|
||||
v["suggested_host"] = suggested_host(row, hosts)
|
||||
views.setdefault(row.state, []).append(v)
|
||||
@@ -182,7 +186,8 @@ async def edit_source(source_id: str):
|
||||
async with current_app.db_sessionmaker() as db:
|
||||
source = await _source_or_404(db, source_id)
|
||||
hosts = await _hosts(db)
|
||||
return await render_template("syslog/edit.html", source=source, hosts=hosts,
|
||||
found = device_address(source, await addresses_by_name(db)) if source.sender else source.address
|
||||
return await render_template("syslog/edit.html", source=source, hosts=hosts, found=found,
|
||||
label=source.name or source.hostname_seen or source.address)
|
||||
|
||||
|
||||
@@ -197,7 +202,10 @@ async def save_source(source_id: str):
|
||||
old_name = source.name
|
||||
source.name = await _unique_name(db, source, form.get("name") or "")
|
||||
source.host_id = await _host_id(db, form.get("host_id"))
|
||||
source.device_address = "".join((form.get("device_address") or "").split())[:255]
|
||||
detail = {"name": source.name}
|
||||
if source.device_address:
|
||||
detail["device_address"] = source.device_address
|
||||
if old_name != source.name:
|
||||
detail["old_name"] = old_name
|
||||
if old_resource != resource_of(source):
|
||||
|
||||
Reference in New Issue
Block a user