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.
jó minőségű serial cuccal akár 1.382.400 bps-t is elérhetsz (igen, 1,3Mbps).
ne a 9600-as egyszerű eszközökből indulj ki.
--
"SzAM-7 -es, tudjátok amivel a Mirage-okat szokták lelőni" - Robi.
Vagy akár 3 Mbit/sec-et is.
Fuszenecker Róbert
persze, maga a protokoll az fuggetlen a sebessegtol. kerdes hogy a gyakorlatban (ill a kollega altal felvetett temaban) mi a helyzet.
É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
Nem rossz otlet, de sajnos barki altal olvashato text file-ba kell menteni:(
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
"barki altal olvashato text file-ba kell menteni"
Miert ? A "disk"et az eszkozbol kiveve kell kiolvasni ?
Amit nem lehet megirni assemblyben, azt nem lehet megirni.
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.
> Milyen gyorsan tud irni a "disk"ed ?
A disk gyors, mivel ramdisk.
akkor mi a francnak írod ki arra a virtuális diszkre?
tartsa a program memóriában, és kész. az pont ugyanannyi, mint a ramdisk.
É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.
Az a gondja, hogy nem hízhat végtelen nagyra a logja. Mindig csak az utolsó n elemre van szüksége.
tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE
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. Vagyis datum, esemeny
> 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.
___
info
Ez tetszik, koszi:)
aztan ha gebasz van, akkor buktdal x meres eredmenyt :p
--
NetBSD - Simplicity is prerequisite for reliability
mint a sajat programommal is.
"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.
--