# Prijemnik dijagnostike sa TERMINIA uređaja Mali samostalan servis: sluša UDP pakete koje terminal šalje (dnevnik rada i heartbeat), piše ih u fajlove po uređaju i po danu, i prikazuje na jednoj web stranici. - **Nema bazu**, nema spoljnih Go zavisnosti (samo standardna biblioteka). - **Ne dira licencni servis** — zaseban proces, zaseban port, zaseban systemd unit. Deli samo Go modul (isti repo). - Ugovor o formatu paketa: ASP repo, `docs/24-servisni-kanal.md`. ## Šta prima | Vrsta | Kako se prepoznaje | Šta radi sa njim | |---|---|---| | Dnevnik rada (dbg) | čist tekst; prvi red `#TERMINIA ` | linije se upisuju u fajl uređaja | | Heartbeat | paket počinje sa `{` (JSON sa `"hb":1`) | pamti se u memoriji (naziv, MAC, IP, FW, vreme) | | Sve ostalo | — | tiho se odbacuje, brojač „odbačeno" na stranici | **Zaglavlje dnevnika postoji tek od FW 0.13.4.** Stariji uređaj šalje goli tekst — takav se vodi kao **nepoznat uređaj**, razvrstava po izvornoj IP adresi i tako je i **označen na stranici** (ne pravimo se da znamo ko je). Prijemnik **ne odgovara** na pakete. Prijem naloga na uređaju nije implementiran i traži potpis (docs/24 §3.2), pa slanja naloga ovde nema. ## Web stranica | Ruta | Šta daje | |---|---| | `/` | spisak uređaja: naziv, MAC, IP, FW, „poslednji put pre X"; **crveno** = nije se javio duže od 3× svog intervala | | `/uredjaj?k=&q=&n=` | poslednjih N linija dnevnika, sa pretragom po tekstu | | `/dnevnik.txt?k=&n=&q=` | isto, kao čist tekst (za `curl`) | | `/api/uredjaji` | JSON spisak uređaja (za alate) | Interval javljanja se **meri** iz razmaka između dva heartbeat-a; dok ga nema, koristi se `LOGGER_HB_DEFAULT_SEC`. ## Pokretanje lokalno ```powershell cd D:\Terminia\TERMINIA-SOFTWARE\licence-server go build -o terminia-logger.exe .\logger\cmd\terminia-logger $env:LOGGER_UDP_PORT="46465" $env:LOGGER_HTTP_PORT="8081" $env:LOGGER_DIR="D:\Terminia\TERMINIA-SOFTWARE\licence-server\data\logger" .\terminia-logger.exe ``` Zatim otvoriti `http://127.0.0.1:8081`. Proba bez uređaja (PowerShell, u drugom prozoru): ```powershell $u=New-Object System.Net.Sockets.UdpClient; $u.Connect("127.0.0.1",46465) function Send($s){ $b=[System.Text.Encoding]::UTF8.GetBytes($s); [void]$u.Send($b,$b.Length) } Send '{"app":"TERMINIA","name":"TERM-001","mac":"1C:DB:D4:A6:A4:60","ip":"192.168.0.20","fw":"0.13.4","hb":1}' Send "#TERMINIA TERM-001 1C:DB:D4:A6:A4:60 0.13.4`n[stampac] javio se na 192.168.123.100`n" $u.Close() ``` Testovi: ```powershell go test ./logger/... ``` ## Env promenljive | Promenljiva | Podrazumevano | Značenje | |---|---|---| | `LOGGER_UDP_PORT` | `46465` | port na koji uređaji šalju. **Ne 46464** — tamo uređaji slušaju discovery | | `LOGGER_UDP_HOST` | (prazno) | adresa za slušanje; prazno = sve | | `LOGGER_HTTP_HOST` | `127.0.0.1` | web sluša samo lokalno jer dnevnik sadrži **brojeve karata** | | `LOGGER_HTTP_PORT` | `8081` | port web pregleda | | `LOGGER_TOKEN` | (prazno) | ako je postavljen, web traži `?t=` (obavezno ako web nije samo lokalni) | | `LOGGER_DIR` | `./data/logger` | folder sa dnevnicima | | `LOGGER_KEEP_DAYS` | `14` | koliko dana se dnevnici čuvaju | | `LOGGER_MAX_FILE_MB` | `10` | preko toga se dnevni fajl rotira (`.log.001`, `.002`…) | | `LOGGER_MAX_DEVICE_MB` | `50` | kvota po uređaju; preko toga se briše najstarije | | `LOGGER_MAX_TOTAL_MB` | `1024` | ukupna kvota za sve uređaje | | `LOGGER_MAX_DEVICES` | `500` | koliko uređaja se drži u memoriji | | `LOGGER_HB_DEFAULT_SEC` | `60` | pretpostavljeni interval dok se ne izmeri | Neispravna vrednost = servis se **ne pokreće** i kaže koja promenljiva ne valja (bolje nego da tiho radi sa pogrešnim podešavanjem). ## Šta se upisuje u uređaj U SPA uređaja: **Podešavanja → Servis** | Polje | Vrednost | |---|---| | `svcLogHost` | `157.180.119.151:46465` | | „Šalji dnevnik rada na server" | **uključeno** | | heartbeat (`svcHbSeconds`) | npr. `60` | Uređaj šalje **samo brojčani IP:port** — domen se ne može upisati (docs/24 §1). > ⚠️ Ovo ide preko interneta **u čistom tekstu**, a u dnevniku ima brojeva > karata. Za trajno praćenje flote predviđen je HTTPS kanal (docs/24 §3); > ovaj prijemnik je za dijagnostiku dok se problem lovi. ## Puštanje na server (radi vlasnik) ```bash # 1) build na serveru cd /root/projects/licence-server git pull go build -o terminia-logger ./logger/cmd/terminia-logger # 2) podešavanja cp logger/deploy/terminia-logger.env.example logger.env $EDITOR logger.env # 3) systemd cp logger/deploy/terminia-logger.service /etc/systemd/system/ systemctl daemon-reload systemctl enable --now terminia-logger systemctl status terminia-logger journalctl -u terminia-logger -f # 4) firewall — SAMO taj port, UDP ufw allow 46465/udp # 5) provera sa strane (ne sme da vrati odgovor, samo da ne pukne) echo '#TERMINIA PROBA AA:BB:CC:DD:EE:FF 0.13.4 proba veze' | nc -u -w1 157.180.119.151 46465 # 6) pregled (web je vezan za 127.0.0.1) — SSH tunel sa svog racunara: ssh -L 8081:127.0.0.1:8081 root@157.180.119.151 # pa u pregledacu: http://127.0.0.1:8081 ``` Ako web treba da bude dostupan bez tunela: postaviti `LOGGER_TOKEN`, staviti nginx ispred sa TLS-om i lozinkom, i tek onda promeniti `LOGGER_HTTP_HOST`. **Ne otvarati port 8081 direktno na internet.** Šta ovaj servis **ne dira**: bazu `licence_db`, proces `licence-server`, nginx konfiguraciju, portove 8090/8091/8092. ## Granice i odbrane - Paket može poslati bilo ko: sve iz paketa je ograničeno po dužini, kontrolni znaci se izbacuju, a ime foldera se pravi isključivo od belih znakova (`[A-Za-z0-9_-]`) — sadržaj paketa ne može da odluči gde se piše. - Broj uređaja u memoriji je ograničen; kad se granica dostigne, izbacuje se onaj koji se najduže nije javio. - Dnevnici se brišu po tri pravila redom: starost → kvota po uređaju → ukupna kvota. Fajl koji je trenutno otvoren za pisanje se nikad ne briše. - Greška pri upisu ne obara prijem — vidi se kao brojač „greške upisa".