adatgyűjtő queue algoritmus embedded linux-on

Fórumok

hello,

Egy embedded linux-os gépen az lenne a feladat, hogy egy soros portról érkező adatfolyamot kell naplózni, mindig az utolsó n adatot kell megtartani.

Mivel nincs nagy disk, az első ötlet az, hogy egy queue-ban tárolom a beérkező eseményeket, majd, ha a queue megtelik, akkor mondjuk kiveszek x%-nyi adatot majd a maradékot kiírom file-ba. Így van x%-nyi idő kiírni a file-t, ill. ennyi időnként lesz file írás. (nyilván a elején akkor van az első file írás, ha már van x%-nyi adat)
Természetesen nem ragaszkodom a C++ programnyelvhez, busybox van, ha kell fordíthatok bele akár perl-t is.

Felmerült a logrotate ügyes felparaméterezése is, de a korlátos disk terület nem teszi lehetővé két file fenntartását.

Minden ötletet szívesen fogadok...

Hozzászólások

hat, fel kell programozni ;) nem tunik bonyolultnak. inkabb a konkret kvantitativ adatmennyiseg az erdekes (milyen sebesseggel jon az adat, mekkora a tarhely, mekkora az atmeneti tarhely). gondolom egyik sem egetveroen szelsoseges, soros portbol is max pa'r k/sec-et lehet kicsikarni.

> soros portbol is max pa'r k/sec-et lehet kicsikarni.

Volt mar a praxisban 920Kb/sec is ami azert nem olyan keves, foleg, hogy 5msec-onkent 128 byte jott. Itt meg nem tudom pontosan mennyi lesz az adatmennyiseg, mert meg nem kaptam reszleteket, de azt hiszem nehany-tiz byte (max 64byte) meretu adatcsomagok lesznek, de a surusegrol nincs meg pontos info.

És mi van, ha létrehozol egy fix méretű file-t, s abba írogatsz körbeforgóan, ezen felül az aktuális pointert is nyilvántartod, ami az fseek()-hez kell majd. Így lényegében pontosan az utolsó n üzenet marad meg. A file éppen akkora, hogy n üzenet fér bele.

Hátránya, hogy a file közvetlen nézegetésével nem megy az ember sokra, kell írni egy olyan függvényt, amelyik helyes megjelenítést ad. Viszont ezt is könnyű megírni.

tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE

Ugyan nem értek hozzá, de valamilyen device file-lal gondolom, el lehetne játszani, hogy azt megnyitva valójában a Te programod fut, s az pointertől a fix méretű file végéig, majd file elejétől pointerig visszaadná az adatokat. Mert például a /dev/urandom is valójában nyilván valaminek a kimenete.

Ne kérdezd, ezt hogyan lehet megcsinálni.

tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE

mondtam volna rrdtool.

De ez meg mi: "a korlátos disk terület nem teszi lehetővé két file fenntartását."
"ha kell fordíthatok bele akár perl-t is. "

Hany Byte/sec -el kapja a soros?
Mennyi hely van ?
Mennyi adatnak kell meglennie ?
Milyen gyorsan tud irni a "disk"ed ?

lzop tomorites jatszik ? CPU birna ?

Miert nem fogod es mented ki az adatot x% onkent mondjuk kulon fileba, a fileneve meg novekszik mondjuk 1 -tol . (lehet base64 kodolni is a nevet)
A legregebbit meg torlod.
(logrotate is hasonlo lenne, csak tobb atnevessel)

Akit erdekel meg majd osszefuzi a sok kicsit novekvo sorrendbe olvasaskor.

Milyen gyakran/gyorsan kell kiolvasni az adatokat, ill. hogyan. Kozbe is megy a gyujtes?

Azt ugye tudod, hogy nem feltetlen kell bevarnod a fileiras veget a kovetkezo sosors adat beolvasasahoz?

Amit nem lehet megirni assemblyben, azt nem lehet megirni.

> Hany Byte/sec -el kapja a soros?
Eddig 128KB/s-rol tudok es ahogy fentebb irtam max 64B meretu csomagok jonnek, de azt nem lehet tudni milyen suruseggel.

> Mennyi hely van ?
A beagyazott eszkozon ramdisk van ami 32Mb meretu, amibol kb. 10Mb szabad.

> Mennyi adatnak kell meglennie ?
A mentett adat merete nincs megadva, amennyi elfer a disken.

> Milyen gyorsan tud irni a "disk"ed ?
A disk gyors, mivel ramdisk.

>Miert nem fogod es mented ki az adatot x% onkent mondjuk kulon fileba, a fileneve meg novekszik mondjuk 1 -tol . (lehet base64 kodolni is a nevet)
A legregebbit meg torlod. (logrotate is hasonlo lenne, csak tobb atnevessel)

Gondoltam a logrotate-re is, de azt igy felhuzni legalabb anyi munka, mint megirni C++-ban.

> Milyen gyakran/gyorsan kell kiolvasni az adatokat, ill. hogyan. Kozbe is megy a gyujtes?
Persze, a gyujtes mindig folyik a kiolvasa csak read, de teljesen aszinkron, olyannyira, hogy masik gep.

> Azt ugye tudod, hogy nem feltetlen kell bevarnod a fileiras veget a kovetkezo sosors adat beolvasasahoz?
Olyannyira, hogy a kulon szal csinalna.

"ramdisk" - ugy ertsem, hogy kikapcsolaskor elveszlik a tartalma, tehat diskre iras nem azert van, hogy aram szunet eseten maradjon meg adat.

Mi kenyszerit arra, hogy filokba tegyed, milyen protokollon/csatornan keresztul kell kiolvasni ?
Nem lehet megoldani, hogy kiolvasaskor alljon elo a szoveges txt formatum ?

"Gondoltam a logrotate-re is, de azt igy felhuzni legalabb anyi munka, mint megirni C++-ban."

Akkor most minimal effort -ra optimalizalunk?
Akkor ha nem kerdezel, mar reg keszen lennel :)

Amit nem lehet megirni assemblyben, azt nem lehet megirni.

Én nem vacakolnék, sem queue -val sem FiFo -val. A közönséges file (stream) írás megteszi - akár pipe vagy átirányítás (gondolom ezek az embedded linux -on is működnek). A pufferelésről a rendszer, ill. a stream file kezelés gondoskodik. Ha nem elég akkor még mindig meg lehet írni és olyan puffert állítasz amekkorát csak kell/lehet/akarsz.
Biztos nem értem jól a kérdést!?

* Én egy indián vagyok. Minden indián hazudik.

Ezt már értem.
Viszont "nincs nagy disk" - akkor minek a fájl? Ki fogja azt olvasni?

Memória, FiFo (én láncolt listát alkalmaznék, de aki jobban ismeri ott az obstack) - mikor a rekordok száma (vagy a foglalt memória mérete) elér valamit, attól fogva első eldob, utolsónak benyom.

Ha mégis kell a fájl, az elejét (akár végig) kicsapnám lemezre, kérdés milyen időnként, esetleg szektorra optimalizálva.

* Én egy indián vagyok. Minden indián hazudik.

Ha lehet pointered, könnyű megcsinálni. Viszont neki az kellett, hogy mindig az utolsó bejegyzés legyen fizikailag is a file végén. Az meg nem túl hatékony, hogy minden egyes bejegyzéskor az egész file tartalmát egy recorddal elmozgatja. Sok CPU-idő.

tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE

Van még egy gondolatom. Ha kevés a hely a háttértáron, viszont van elég RAM, akkor a háttértáron fix méretű file-ba, körbeforgóan írnám - tehát FIFO -, aztán RAM-diskre kiírnám úgy, hogy ember számára olvasható legyen, azaz pointertől pointerig. Így bármikor megnézhető, olvasható a file, ha leállítják, akkor ez ugyan eltűnik, de a FIFO marad, így legközelebb megint el lehet olvasni, hiszen generálódik majd.

Szerk.: Sok volt itt a 'tehát', javítottam a stílushibát.

tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE

> mindig az utolsó n adatot kell megtartani.

Írhatnál pár sort az "utolsó n adat" feldolgozásról, mert ha a feldolgozásból nem adódnak követelmények, akkor bármilyen megoldási javaslat ugyanolyan jó (rossz) lesz.

> Az van a feladatkiirasban, hogy egyszeru text log-szeru formatumban legyen.

Ez valami gyakorló feladat? Nem is dolgozza fel semmi a log-ot?

Akkor egy megfelelő méretű fájlt is létre lehetne hozni, mmap() + msync() megoldja a kiírást a ramdisk-re. A log bejegyzés méretének van egy maximuma, ami rövidebb azt ki lehet egészíteni szóközökkel, hogy egyforma hosszúak legyenek a bejegyzések. A fájl tartalmát lehet gyűrű pufferként kezelni, vagy egy új tétel felvételekor egy bejegyzéssel eltolni, és mindig a végére írni az új bejegyzést.


NAME
     fifolog_create -- Initialize storage for fifolog
     fifolog_write -- Write data to fifolog
     fifolog_read -- Seek and extract data from fifolog

SYNOPSIS
     fifolog_create [-l record-size] [-r record-count] [-s size] file
     fifolog_reader [-t] [-b tstart] [-B Tstart] [-e tend] [-E Tend]
                    [-o ofile] [-R regexp] [-T timefmt] file
     fifolog_writer [-w write-rate] [-s sync-rate] [-z compression] file

DESCRIPTION
     Fifologs provide a compact round-robin circular storage for recording
     text and binary information to permanent storage in a bounded and pre-
     dictable fashion, time and space wise.

___
info

aztan ha gebasz van, akkor buktdal x meres eredmenyt :p

--
NetBSD - Simplicity is prerequisite for reliability

"a korlátos disk terület nem teszi lehetővé két file fenntartását."
Oke, itt mar elvesztettem a fonalat, pedig elolvastam a topicot.

Szerintem akarmekkora disken letre lehet hozni ketto (harom, negy, sok) fajlt, ha azok egyuttes osszmerete nem haladja meg a disk szabad teruletenek meretet (es van annyi inode).

En is olyan vonalon indulnek el, hogy memoriaban tartod az N meresi adatot, es vagy minden meresi adat utan irsz egyet, vagy csak akkor, amikor betelik a tomb, ez mar fugg attol, mennyi idod van a ket adat kozott.

Mivel ramdisk, ezert szerintem a disk iras ideje elhanyagolhato, a fo az, amit te dolgozol az irassal.

De felvetnem a kerdest, hogy ezt pontosan miert igy kell implementalni? En erre syslogot hasznalnek, mindenkinek egyszerubb, es akarmilyen gepet be lehet fogni a syslog gyujtesere.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal