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:
@@ -14,8 +14,8 @@ from steward.models.users import UserRole
|
||||
|
||||
from .models import SyslogLine, SyslogSource
|
||||
from .parse import facility_name, severity_name
|
||||
from .service import (AROUND_LINES, AROUND_SEVERITY, LineFilter, filtered, lines_between, place_for, rates,
|
||||
severity_level, shown_on, source_name, sources_for)
|
||||
from .service import (AROUND_LINES, AROUND_SEVERITY, LineFilter, addresses_by_name, device_address, filtered,
|
||||
lines_between, place_for, rates, severity_level, shown_on, source_name, sources_for)
|
||||
|
||||
|
||||
async def list_syslog_sources(state: str = "") -> dict:
|
||||
@@ -28,6 +28,8 @@ async def list_syslog_sources(state: str = "") -> dict:
|
||||
A device whose lines reach Steward through Docker's own address (a port
|
||||
published on Swarm's ingress) is told apart by the name its lines carry:
|
||||
`through_docker` is true and `address` is Docker's, shared with the others.
|
||||
`device_address` is the device's own: set on the source, or found from the
|
||||
SNMP device or host its name is (else the address its lines come from).
|
||||
|
||||
Each gives its address, the host it is shown on, lines received in all
|
||||
(`lines_total`) and, for an added source, in the last hour, when it was
|
||||
@@ -43,9 +45,10 @@ async def list_syslog_sources(state: str = "") -> dict:
|
||||
sources = list((await db.execute(stmt)).scalars())
|
||||
per_hour = await rates(db, [s.id for s in sources if s.state == "accepted"], now)
|
||||
hosts = {h.id: h.name for h in (await db.execute(select(Host))).scalars()}
|
||||
named = await addresses_by_name(db) if any(s.sender for s in sources) else None
|
||||
return {"sources": [{
|
||||
"source_id": s.id, "name": source_name(s), "address": s.address, "state": s.state,
|
||||
"through_docker": bool(s.sender),
|
||||
"through_docker": bool(s.sender), "device_address": device_address(s, named),
|
||||
"host_id": s.host_id, "host_name": hosts.get(s.host_id), "calls_itself": s.hostname_seen or None,
|
||||
"lines_total": s.lines_total, "lines_last_hour": per_hour.get(s.id, 0) if s.state == "accepted" else None,
|
||||
"last_heard": iso(s.last_seen_at), "last_heard_age_s": age_s(s.last_seen_at, now),
|
||||
@@ -99,7 +102,7 @@ async def search_syslog(source: str = "", host: str = "", text: str = "", severi
|
||||
list_tool="list_syslog_sources", name=source_name)]
|
||||
if host:
|
||||
h = pick(host, list((await db.execute(select(Host))).scalars()), kind="host", list_tool="list_hosts")
|
||||
chosen = sources_for(chosen, h.id, h.address)
|
||||
chosen = sources_for(chosen, h.id, h.address, await addresses_by_name(db))
|
||||
if not chosen:
|
||||
return {"range": key, "matches": [], "returned": 0, "truncated": False,
|
||||
"note": f"No added syslog source is shown on {h.name}."}
|
||||
|
||||
Reference in New Issue
Block a user