fix(syslog): a row from before the name split, last seen as a device, stays that device's (#6096)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -249,6 +249,15 @@ async def store_lines(session, lines: list[Received]) -> None:
|
|||||||
sources = {(s.address, s.sender): s for s in (await session.execute(
|
sources = {(s.address, s.sender): s for s in (await session.execute(
|
||||||
select(SyslogSource).where(SyslogSource.address.in_(addresses)))).scalars()}
|
select(SyslogSource).where(SyslogSource.address.in_(addresses)))).scalars()}
|
||||||
new = [k for k in by_sender if k not in sources]
|
new = [k for k in by_sender if k not in sources]
|
||||||
|
for key in [k for k in new if k[1]]:
|
||||||
|
# A row from before devices at Docker's address were told apart by
|
||||||
|
# name, last seen under this one, is this device: it keeps its state
|
||||||
|
# and name rather than a new row being offered beside it.
|
||||||
|
before = sources.get((key[0], ""))
|
||||||
|
if before is not None and before.hostname_seen == key[1]:
|
||||||
|
before.sender = key[1]
|
||||||
|
sources[key] = sources.pop((key[0], ""))
|
||||||
|
new.remove(key)
|
||||||
if new:
|
if new:
|
||||||
known = (await session.execute(select(func.count()).select_from(SyslogSource))).scalar_one()
|
known = (await session.execute(select(func.count()).select_from(SyslogSource))).scalar_one()
|
||||||
for key in new:
|
for key in new:
|
||||||
|
|||||||
@@ -99,6 +99,20 @@ def test_devices_through_dockers_address_are_told_apart_by_name(app, monkeypatch
|
|||||||
got = sorted((r.address, r.sender, r.lines_total, r.last_line) for r in rows)
|
got = sorted((r.address, r.sender, r.lines_total, r.last_line) for r in rows)
|
||||||
assert got == [("10.0.0.2", "AsusNAS", 2, "d"), ("10.0.0.2", "SynNAS", 2, "c"),
|
assert got == [("10.0.0.2", "AsusNAS", 2, "d"), ("10.0.0.2", "SynNAS", 2, "c"),
|
||||||
("10.9.0.1", "", 1, "e")]
|
("10.9.0.1", "", 1, "e")]
|
||||||
|
await s.execute(delete(SyslogSource))
|
||||||
|
await s.commit()
|
||||||
|
# A row from before the split, last seen under a device's name, is that device's.
|
||||||
|
async with app.db_sessionmaker() as s:
|
||||||
|
async with s.begin():
|
||||||
|
s.add(SyslogSource(address="10.0.0.3", state="accepted", name="DS923", hostname_seen="DS923",
|
||||||
|
first_seen_at=now, last_seen_at=now, lines_total=3))
|
||||||
|
async with app.db_sessionmaker() as s:
|
||||||
|
async with s.begin():
|
||||||
|
await receiver.store_lines(s, [line("10.0.0.3", "DS923", "f"), line("10.0.0.3", "util", "g")])
|
||||||
|
async with app.db_sessionmaker() as s:
|
||||||
|
rows = (await s.execute(select(SyslogSource))).scalars().all()
|
||||||
|
got = sorted((r.sender, r.state, r.name, r.lines_total) for r in rows)
|
||||||
|
assert got == [("DS923", "accepted", "DS923", 4), ("util", "offered", "", 1)]
|
||||||
async with app.db_sessionmaker() as s:
|
async with app.db_sessionmaker() as s:
|
||||||
async with s.begin():
|
async with s.begin():
|
||||||
await s.execute(delete(SyslogSource))
|
await s.execute(delete(SyslogSource))
|
||||||
|
|||||||
Reference in New Issue
Block a user