Existuje nějaký přímočarý způsob, jak logovat svou uživatelskou aplikaci homogenně s tím jak loguje systemd, tj aby k jejím logům šlo přistoupit přes ten journalctl ?
Byl jsem zvyklý prostě založit adresář /var/log/moje_sranda/ a cpát to tam textově, a nastavit si na to logrotate. Chci ale jít s dobou, jak to tedy přidat do systemd, aby mi to logoval a rotoval?
Nechci to ovšem cpát do syslogu, kde se to bude míchat s tunama jiných věcí...
Použijte Journal API. A nebo pokud vám stačí textový výstup (nepotřebujete logovat strukturované zprávy), posílejte to z aplikace normálně na standardní výstup – journald si to přesměruje do logu. Já osobně preferuju druhou variantu, protože je to jednoduché, na ničem dalším to nezávisí, aplikaci můžu snadno spouštět ve vývojovém prostředí nebo na popředí a rovnou vidím její výstup, a když ji pak spustím pod systemd, budu mít s tím samým kódem ten samý výstup v logu.
V mém komentáři byly rady dvě. Pokud chce někdo poradit něco modernějšího, než syslog, asi mu nebudu radit, že má použít syslog. Pokud víte o nějakém jiném API pro logování, sem s ním. Pokud byste měl pocit, že Syslog je dostatečně moderní API, tak mně na něm nevyhovuje například to, že v systému může běžet až závratných dvacet služeb, z nichž 14 je pevně daných. Takže až na svém serveru budu provozovat UUCP, USENET, FTP a jehličkovou tiskárnu, bude Syslog můj favorit pro logování.
Dotaz byl, jaké použít API. Vy se teď ptáte na to, jakou použít implementaci logovacího démona, který podporuje Journal API. No já bych doporučil journald, je to v současnosti jediná implementace, o které vím. A myslím, že by neměl být problém portovat ji na jiné POSIX platformy, protože si nemyslím, že by měla nějaké komplikované závislosti.
<cite>Tak můžete prosím vysvětlit, když pošlu přes Journal API data, co je teda přijme, když to nebude aplikace?</cite>
Ale to právě plyne z toho nepochopení rozdílu mezi API a implementací. Z dovolením Vám to tedy vysvětlím na struktuře programu v jazyce C:
Příklad A: Váš program v případě, že používá journald (API i službu):
1. API definuje prototyp funkce pomocí hlavičkového souboru (#include <systemd/sd-journal.h>)
2. V případě použití journald musíte krom #include také přidat implementaci té funkce slinkováním s libsystemd (např. gcc -lsystemd)
Vaše aplikace potom zavolá přikompilovanou funkci , která něco někam pošle (nedůležité pro Vás jako vývojáře aplikace) a ono se to objeví v journald.
Příklad B: Váš program používající API journald bez journald
1. API a hlavičkový soubor jsou stále přítomny (#include <systemd/sd-journal.h>)
2. Napíšete vlastní triviální (fakt) implementaci funkce sd_journal_print (a těch ostatních), které vezmou argumenty a pošlou je do souboru, na syslog, na web kamkoliv.. třeba jako JSON (když už logujete strukturovaně)
2B. Pokud už tu implementaci API napsal někdo za Vás, opět jen jednoduše použijete vhodné linker argumenty (-laltjournaldjsonsyslog) a spojíte Vaši aplikaci s touto jinou implementací místo libsystemd.
Výsledek? Zdrojový kód aplikace je v případech A a B úplně stejný, ale log je nakonec poslán jinam. Kam, to už není starost aplikačního zdrojového kódu, ale linkeru, implementace API a případně nějaké (úplně libovolné) služby.
Je proto opravdu potřeba rozlišovat službu journald a API journald. Vaše aplikace nepoužívá totiž službu journald, ale jednu konkrétní přilinkovanou implementaci journald API.
Je to změna? Je. Ale syslog strukturované logování neumí, takže se změně stejně nevyhnete.
Je to pevně svázané se systemd/journald? Na úrovní .c zdrojáků ne, na úrovni binárek ano, ale jen pokud chcete.
Vysvětlovat to mi (programátorovi), je zbytečná práce. Já tyhle věci vím. Akorát mi pořád není jasné, jak to použiju jinde, jak tady někteří tvrdí, že to jde, protože podle mě, když je implementace Journal API jediná a sice pouze v systemd, který je pouze pod Linuxem, tak to prostě jinde (jiné *nix like OS, Windows ap.) nefunguje. Bohužel jsou tu jedinci, kteří tvrdí, že to používat jde, ale odpovědi jak se to udělá, když to jinde neexistuje jsme se stále nedobrali.
> Vysvětlovat to mi (programátorovi), je zbytečná práce.
Očividně není..
> Bohužel jsou tu jedinci, kteří tvrdí, že to používat jde, ale odpovědi jak se to udělá, když to jinde
> neexistuje jsme se stále nedobrali.
No překvapivě se ta implementace napíše. Neumíte implementovat interface o 5 primitivních funkcích? Klidně to pak můžete zveřejnit pro ostatní, určitě Vám poděkují.
> když je implementace Journal API jediná a sice pouze v systemd, který je pouze pod Linuxem,
> tak to prostě jinde (jiné *nix like OS, Windows ap.) nefunguje
Protože tu implementaci o možná 100 řádcích C, kterou na ostatních platformách pošlete třeba JSON do syslogu ještě prostě nikdo nenapsal. To, že systemd je jen pod linuxem je úplně nepodstatné. Tomu hlavičkovému souboru je to jedno a víc nepotřebujete.
Journal API potřebujete používat jen (a pouze), pokud chcete logovat strukturovaně. Což nejde ani s tím všudypřítomným syslogem. Tak jako tak byste si to musel napsat. Z toho mi plyne, že fakt, že tvůrcem Journal API je Lennart & spol, je zrovna tady naprosto irrelevantní.
Btw, znáte třeba vztah Slf4j, Log4j a Logback? V Javě je totiž už mnoho let úplně běžné kompilovat proti abstraktní log vrstvě a implementaci dodat až na konkrétní platformě (vložením správného JARu a konfigurace do classpath).
Ano přesně tady jsem vás chtěl dostat, děkuji, že jste se nakonec odhalil.
Abych tedy shrnul vaši radu: Abych mohl naprogramovat aplikaci, ve které chci "moderně" logovat, musím si k tomu napsat i pro každý systém mimo Linuxu i logovacího démona, který bude implementovat Poetteringovo API. :-D
Přiznejte se, že jste byl toto léto moc dlouho na sluníčku.
PS: A když je to tak mega super cool věc, jak to že ještě nejsou hromady implementací toho API na všech možných i nemožných OS, aby se s tím každý programátor nemusel mrcasit sám?
A přesně tohle jsem zase chtěl vidět já. Očividně neumíte rozlišit kompilační, linker a runtime závislosti.
Nerozlišujete totiž API pro dynamickou knihovnu a logovacího daemona se kterým se jedna taková knihovna baví. To jsou totiž dvě zcela rozdílné komponenty a Journal API naprosto nic neříká o tom, že by se muselo něco posílat journald kompatibilním způsobem. Implementace Journal API může klidně mluvit přímo se Syslogem nebo psát do souboru - bez journald.
Tu poznámku o (ne-)podpoře struktury v syslog API ani ten odkaz na Slf4j jste taky nepochopil. A podle všeho zcela úmyslně (a špatně) trollujete.
Jj jasně, tonoucí se stébla chytá. Na některých OS bude stačit knihovna na jiném bude nutný i daemon. Slovíčkaříte a uchází vám podstatná pointa. Takhle to mají puberťáci, že bazírují na kravinách a podstata jim uniká.
PS: A k čemu bych posílal strukturovaná logovací data přes nějakou zvláštní novou knihovnu do syslogu, který strukturu nemá místo toho, abych to posílal syslogu přímo na všech *nix like platformách, to už mi asi taky nevysvětlíte, ale hlavně že je nutné dělat vlastní implementaci API, které na dané platformě neexistuje. :D
Ehm.. argumentace kruhem? Chceme modernější logování (na začátku vlákna), ale vlastně žádné nepotřebujeme, protože už máme syslog, který ho neumí, tak je to přece celé zbytečné.
Ale hlavně, že se bavíte a jste programátor. Ad hominem už taky umíte, gratuluji. Obávám se totiž, že podstata uniká vám. **Journal API není, nerovná se a nezávisí na journald ani linuxu**.
Na službě journald závisí pouze knihovna libsystemd, což je v tuto chvíli opravdu jediná rozšířená implementace Journal API. Nicméně to API má pouhých 5 funkcí, které se víceméně liší jen způsobem předávání parametrů.
Syslog strukturu mít může (na CEE už tu odkaz zazněl, ale jinak třeba http://www.rsyslog.com/tag/cee-enhanced/) a Vaše aplikace může používat strukturované logy i když neví nic o jejich dalším zpracování. Platformy, které je umí, v nich umožní vyhledávat, platformy co ne je prostě jen uloží (nebo předají dál).
Jako další samostudium Vám doporučuji si nastudovat architekturu jiného pokusu o univerzální logovací API, který se uchytil: Slf4j. Je to totiž úplně ten samý případ a přístup jako Journal API. Na platformě, backendu nezávislý interface bez předepsané implementace.
Tak se podívejte pořádně. Já žádné strukturované logování nechtěl, mě bylo nuceno a když jsem se zeptal, proč je to tak super skvělé, tak jsem se dověděl, že proto, že si musím na všech ostatních platformách kromě Linuxu se systemd naimplementovat vlastní a když to udělám, tak na hromadě platforem to stejně jen převedu ze struktury do textu. Rada jak noha :D
Tak si to sám vyzkoušejte. Napište si jednoduchou Hello World aplikaci a přidejte si do ní logování přes Journal API. Přidáte #include <systemd/sd-journal.h>, zavoláte sd_journal_print. Aplikaci přeložíte.
Co jste právě udělal? Naprogramoval jste aplikaci, která loguje přes Journal API. Musel jste naprogramovat logovacího démona pro každý systém mimo Linux? Nemusel. Takže buď umíte zázraky, nebo jste právě předvedl protipříklad ke svému tvrzení.
Normálně uvažující lidi mají nejprve nějaký problém (např. potřebuji logovat strukturované zprávy) a k němu hledají řešení (použiju Journal API). Vy jste se nejprve rozhodl, že použijete Journal API, a teď zoufale hledáte nějaký důvod, proč jste se tomu vlastně rozhodl.
Mám pro vás takový radikální návrh. Když nevíte, proč byste něco používal, tak to nepoužívejte.
Co mi to vkládáte do úst? Já vůbec Journal API nechtěl používat. Já naopak na začátku říkal, že journald a jeho API je vlastně k ničemu. Ale byl jsem přesvědčován, jak je to super věc a když jsem se zeptal proč, tak jsem se dověděl, že proto, že si ho můžu všude možně na různých platformách naimplementovat :D
Vy jste možná nechtěl, ale reagoval jste na někoho kdo chtěl: http://www.root.cz/clanky/nebojte-se-systemd-dalsi-komponenty/nazory/883074/
> Ale byl jsem přesvědčován, jak je to super věc a když jsem se zeptal proč, tak jsem se dověděl,
> že proto, že si ho můžu všude možně na různých platformách naimplementovat :D
Opravdu? Já jsem si celkem jistý, že se v prvních odpovědích na Vaše výpady mluvilo o strukturovaném logování. http://www.root.cz/clanky/nebojte-se-systemd-dalsi-komponenty/nazory/883132/ a o logování na standardní výstup: http://www.root.cz/clanky/nebojte-se-systemd-dalsi-komponenty/nazory/883143/
Snaha o vysvětlení pojmu API přišla až později, když jste demonstroval naprostou neochotu akceptovat, že to někdo opravdu chce používat a vymyslel si argument s multiplatformitou. Bohužel nepadla na úrodnou půdu... pořád si stojíte na vedení.
Nic proti, ale po tom co jsi tady napsal je potřeba úspěšně pochybovat o tom, že jsi programátor. Každy slušný projekt přesahující jakousi minimální hranici (definujme ji například cca 1000+ SLOC) loguje buď na standardní výstup/error výstup pokud nemá extra potřeby (třeba i kvůli Dockeru) nebo používá nějakou slušnou logovací multiplatformní knihovnu (pro každý jazyk jich bývá přehršel). A v těchto knihovnách si jednoduše nakonfigurujete, kam všude to má jít. Není jen standardní výstup/soubor/syslog/rsyslog, loguje se do logstashe/graylogu/fluentd, existují mraky cloudových logovacích služeb (ani nebudu vyjmenovávat). Takža kam se loguje je otázka změny konfigurace. Normální programátor neřeší API logovacích knihoven.
Na mne tyhle diskuse dělají dojem, že si tady honí trika správci ojedinělých serverů, občas o sobě prohlašující, že jsou programátoři. Opravdový programátor nebo správce opravdu rozlehlé sítě by nikdy něco takovéhohle nemohl napsat.
Ano to je taky přesně ta věc, co mi vadí. Proč bych měl měnit hromady aplikací, když taková věc má být konfigurací té komponenty, která ji má v systému na starost (v *nix like systémech syslog)? Poettering vyrobí novou (nespolehlivou) službu a nutí takhle ostatní, aby ji používali a to tímhle způsobem. Takhle se to podle mě nedělá.
Příklad nucení ostatních do změn je v poslední době v rozbití funkčnosti screen, tmux ap. a pak vysvětlování jeho nohsledů v diskuzi tuším právě u tmuxu, že to mají opravit oni. Mám obavu, že tohle není poslední věc, kterou budou autoři systemd tímto způsobem tlačit a problémy ohledně nové logovací služby to podle mě dokazují.
Normální programátor neřeší API logovacích knihoven.
Ano a to je v podstatě ten problém, na který jsem upozorňoval. Běžný (osobně se mi vaše dělení na normální a nenormální nezdá) programátor to nemá co řešit. A proto se mi to nabízené řešení v podobě toho, že si to má sám naimplementovat nelíbí.
PS: Vaše pochyby směrem ke mě rozebírat nebudu.
Výborně. To je na úrovni aplikace. Kde potom najdu definici API, která mi umožní napsat vlastní alternativu k journald tak, aby aplikace slinkovaná s libsystemd posílala data mě ? A abych samozřejmě nemusel mít jorunald vůbec spuštěný (chci ho nahradit vlastním podobně, jako už mám nahrazený běžný syslog).
API je definováno mezi logující aplikací a libsystemd (je to Journal API), nikoli mezi libsystemd a journald (tam je to implementační záležitost). Když chcete nahradit journald, napíšete vlastní implementaci Journal API, a aplikace nepoběží s implementací Journal API z libsystemd ale s implementací z vaší knihovny. A ta vaše knihovna třeba vůbec nemusí komunikovat s dalším běžící procesem, ale může rovnou zapisovat na disk.
Víte. Možná byste neměl odpovídat na dotazy, které Vám nebyly položeny. Pokud máte potřebu plácat, tak ji prosím ventilujte jinde. Otázka nezněla, jak napsat vlastní implementaci Journal API a potom pomocí LD_PRELOAD a podobných věcí nahrazovat libsystemd. Otázka zněla, co je třeba implementovat aby bylo možné nahradit v systému journald (tak jako lze nahradit ntpd, syslog a další komponenty) a aby programy s podporou journald API slinkované proti libsystemd mohly normálně logovat. Kvalitní odpověď jsem o něco níže dostal od toho koho jsem se ptal.
To už je o něco složitější, protože nejde o API, ale komunikační protokol.
První dva odkazy z google na "journald protocol":
https://www.freedesktop.org/software/systemd/man/systemd-journal-remote.html
https://lists.freedesktop.org/archives/systemd-devel/2012-November/007359.html
Oba jsou relevantní.
Tak to API na journald zavisi tim, ze je to jeho jedina implementace.
To ovšem nechápete význam zkratky API. To, kolik je implementací, není věcí autorů API.
A vzhledem k tomu, ze Poetterig to API jeste treba 20x zmeni, tak se do alternativni implementace asi nikdo nepozene.
To jsou akorát vaše ničím nepodložené kecy.
LOL!
Otázka: Jak použiju Journal API jinde než v Linuxu a systemdd?
Odpověď Jirsáka: Úplně normálně, API je API a můžete to použít třeba i na WIndows
Otázka: Ale když to jinde než v Linuxu a SystemD neexistuje, jak to teda použiju?
Odpověď Jirsáka: To ovšem nechápete význam zkratky API. To, kolik je implementací, není věcí autorů API.
To už je na Chocholouška toto :D. A prej neexistující problém jak je výše psáno. Jasně, hned jdu do Windows programovat pomocí Journal API, které Windows nepodporují :D :D :D
Systemd má mouchy, JournalD nemám moc rád, ale tohle už je chytání se stébla a ukázka argumentace s jediným cílem a bez ohledu na fakta. Syslog totiž na Windows taky nativně není, ale u něj Vám to očividně nevadí.
Windows nic totiž podporovat nemusí, prostě si ve Vašem programu za #ifndef sd_journal_print napište 5 primitivních funkcí, které přeloží argumenty třeba do správného ReportEvent volání ve Windows.
A hle, multiplatformní aplikace je na světě. To samé už někdo udělal za Vás v případě těch několika implementací syslogů pro Win co jsem našel. Občas prostě musíte být první, přestat žvanit a těch pár řádku pro ostatní napsat.
To, že nechápete pojem API, není zas taková tragédie, rozhodně to není na Chocholouška. Na Chocholouška je to, že místo abyste si to zjistil, píšete pořád různé nesmysly založené na nesmyslných představách o tom, co je API.
Zkusím to ještě jednou. API je rozhraní mezi dvěma softwarovými komponentami. Použití API znamená, že dokážete zavolat funkce poskytované tím API. API může mít nějaké podmínky použití a závislosti – např. pokud bude funkce vyvolána zasláním zprávy dbus, je takové API závislé na dbus. Pokud se funkce vyvolává zasláním zprávy vytvořené přes funkci CreateEvent Win32 API, bude to API závislé na Win32 API. Journal API je tvořené pouze voláním C funkcí, takže nemá žádné závislosti a je multiplatformní.
Jako programátor Journal API použijete tak, že do svého zdrojáku includujete příslušný hlavičkový soubor a zavoláte funkce v něm deklarované. V závislostech své aplikace pak uvedete, že k běhu potřebuje (volitelně nebo povinně, záleží jak jste to implementoval) implementaci Journal API. Tím to pro vás končí, neřešíte, kde je jaká implementace, stejně jako neřešíte, kde vaše aplikace sebere implementaci funkce fopen nebo SSL_accept.
Když pak někdo chce vaši aplikaci použít, musí nejprve splnit všechny její závislosti. Když bude potřebovat implementaci SSL_accept, použije třeba LibreSSL – a to přesto, že v době, kdy jste psal ten program, LibreSSL ještě vůbec nemusela existovat a jediná implementace SSL_accept byla v OpenSSL. Úplně stejně je to s Journal API. Vy dneska napíšete aplikaci používající Journal API, a vůbec vás při programování nemusí zajímat, jaké existují implementace. Ten váš program může zítra někdo vzít a spustit s implementací, o které jste ani nevěděl. Dokonce ten program můžete napsat i tehdy, když neexistuje vůbec žádná implementace toho API. A v tom je právě celá výhoda API a jeho smysl – vy jako programátor se nestaráte o konkrétní implementace, je vám jedno, jestli není žádná, je jedna nebo jich je padesát, je vám jedno jestli zítra přibyde dalších dvacet implementací, protože pro vás se tím nic nemění, vy píšete pořád proti tomu jednomu API.
Z toho je mimo jiné patrné, že vaše věta „Windows nepodporují Journal API“ je nesmyslná. Žádná podpora Windows není potřeba. Když někdo napíše implementaci Journal API pro Windows, můžete pod Windows Journal API klidně používat – na Windows samotných se přitom nic nezmění, v Redmondu nebudou muset hnout ani prstem, aby Windows nějak začaly podporovat Journal API. To, zda můžete nějaké API v daný okamžik někde použít, je totiž závislé pouze na jeho závislostech a na dostupných implementacích. Pro použití API nepotřebujete žádnou podporu operačního systému.
Tolik k původní otázce autora programu, jaké multiplatformní API může použít. Vedle ní je také možné položit otázku uživatele: mám aplikaci vyžadující implementaci Journal API. Jakou implementaci Journal API mám použít? Což je ovšem jiná otázka, než ta, která byla na začátku tohohle vlákna.