PHP szkript logolása

Sziasztok!

Van egy PHP szkriptem, ami egyszerű SQL SELECT-INSERT párost végez.

Szeretném logolni, mit is csinál, értelemszerűen a /var/log alá (Debian 7).

Addig már eljutottam, hogy:

syslog(LOG_INFO, 'Gipsz Jakab bekerült a címlistába');

Azonban ez a /var/log/messages-be logol. Ez jó lenne, ha ebbe a naplóba csak ez kerülne, de természetesen nem csak ez kerül, hanem minden más is, amit a többi program logol.

Van arra megoldás, hogy a szkriptem mondjuk egy cimlista.log fájlba kerüljön, s azt rotáljam?

Láttam valami openlog function-t, ami így néz ki:

bool openlog ( string $ident , int $option , int $facility )

De itt nincs írva, mi az a function, ami saját, általam meghatározott fájlba naplóz.

Ebben valaki tud segíteni?
Köszönöm.

Hozzászólások

A PHP syslog implementacioja minimum erdekes. Normal esetben a /dev/log ala logol, amit aztan a syslog daemon dolgoz fel. Az openlog() fuggvennyel tudod szabalyozni, melyik facility, stb. Neha (foleg Apache alatt) viszont erdekes a mukodese, siman mehet az Apache logjaba is a hiba.

En eppen ezert altalaban sajat syslog handlert szoktam implementalni, pl az egyik ilyen implementacio itt

--
Pásztor János
Üzemeltető Macik

Hozz létre kézzel saját logfájlt a /var/log alatt, adj www-data-nak erre az egy fájlra írásjogot. Aztán PHP-ból fájlszinten appendeld. A rotálásra pedig például a logrotate-et lehet felkonfigolni.

Miert kene mindig, minden muvelet utan lezarni a filet, ha mondjuk egy scriptben tobb logolas is van? Performance bottleneck.
Megnyitod a filet egyszer a script elejen, irsz bele, majd lezarod a file handle-t.
Ha az a problema, hogy ez igy nem thread-safe: hasznalj flock-ot az irasi muveleteknel.

Az miért nem jutott senkinek eszébe, hogy magát a syslogot konfigurálja?
Láthatóan van a géphez hozzzáférése, ha már a varlog alatt tud turkálni, de minimum van egy rendszergazdája kézközelben (javíts ki, ha tévedek). Ehelyett PHP-ban gányoltok mindenféle egyéni megoldást rá.

/etc/rsyslog.d/50-default.conf:

.....
php.none -/var/log/syslog
....
if $programname == 'php' then /var/log/phptest.log

Ennyi az egész. Logrotate.d meg egyszerűen idomítható, hogy elrotálja ezt.
Nyilván van ennek syslog-ng megfelelője is.

Mondjuk nem szeretne, ha minden PHP-s kod ugyanoda logoljon, hanem alkalmazaskonkent mas file-ba. Ami ugyanugy az apache/php interpreter fennhatosaga alatt fut.

Olyan ez, mintha azt mondanad, hogy minden JVM processz ugyanoda logoljon.

A syslognak vannak azert elegge komoly korlatozasai.


openlog ( 'testphp' , LOG_PID | LOG_PERROR, LOG_LOCAL0 );
syslog(LOG_INFO, 'teszt logolas');
closelog();

rsyslog conf:

if $programname == 'testphp' then /var/log/phptest.log

phptest.log:

Mar 4 10:39:25 hostname testphp[23028]: teszt logolas

Akár funkciónként is tud más-más fájlba logolni.

A syslog MSG két részből áll, TAG és CONTENT. A fenti PHP függvény is így tolja be az üzenetet a syslognak és a TAG-et fogja helyettesíteni az általunk megadott értékkel, annyi, hogy ő másképp hívja (ident ~ azonosító, tag = cimke, azért némileg hajaznak egymásra). De a végeredmény ettől függetlenül jó lesz, máskülönben az rsyslog csak nézne, mint borjú az új kapura. Ez max a PHP dokumentációját minősíti, ebben a tekintetben jogos a 2 pont neked :)

"De a végeredmény ettől függetlenül jó lesz, máskülönben az rsyslog csak nézne, mint borjú az új kapura."
Mivel aluldefiniált a syslog() működése PHP-ban, ezért bármikor előfordulhat, hogy az implementáció módosul, és a TAG más lesz PHP 7-ben, 7.1-ben stb.
Nem a dokumentáció itt a lényeg, hanem a specifikációja a syslog() hívásnak PHP-ban, a dokumentációnak ezt tükröznie kéne.

Es meg jo, hogy a csodas GNU libc dokumentacio is pongyola szohasznalatot csinal itt:
"ident is an arbitrary identification string which future syslog invocations will prefix to each message. This is intended to identify the source of the message, and people conventionally set it to the name of the program that will submit the messages."
http://www.gnu.org/software/libc/manual/html_node/openlog.html#openlog

Ahelyett, hogy leirna, hogy ez lesz a syslog uzenet TAG mezoje. Az egyertelmu legalabb, foleg mivel a Syslogot definialo RFC is ezt a szohasznalatot alkalmazza.
"The MSG part has two fields known as the TAG field and the CONTENT field. The value in the TAG field will be the name of the program or process that generated the message."
http://www.ietf.org/rfc/rfc3164.txt

Update: a POSIX is csodalatos itt.
" The ident argument is a string that is prepended to every message. "
http://pubs.opengroup.org/onlinepubs/9699919799/functions/openlog.html

unixengineering.

Update 2:
Itt azert elteres van akozott, hogy mi a syslog.
Ugyanis a POSIX syslog hivasok csoportja (igy az openlog lib call sem) irja elo, hogy a system logger syslog-kompatibilis legyen az RFC3164 szerint.
Azaz nem tudhatod, hogy a syslog hivas masik oldalan mi all.
Igy mar jogos az ident nev hasznalata, de nem jogos az, hogy azt mondod, hogy mivel a PHP openlog() hivas eppen a te rendszereden egy syslog-kompatibilis loggerbe logolodik, ezert elegendo az rsyslog/syslog-ng konfiguralasa. Ez nem igaz.
Hiszen specifikacio szerint rendszerfuggo, hogy az openlog() hova fog logolni.

Igen, a PHP mindig is naaaaagyon vekony reteget huzott az oprendszer cuccai fole. Nem implementaltak sajat logging API-t, az inkabb a Java-fele irany. Viszont pl. Windowson PHP-t futtatni... minimum bator. Egy csomo lib nem fog mukodni.

Nem azt mondtam, hogy ez feltetlenul jo, ez mindenkeppen vita targya lehet, de a tenyallason nem valtoztat. A PHP-s API es dokumentacio *NIX-jellegu rendszerekbol, es leginkabb Linuxbol indul ki.

--
Pásztor János
Üzemeltető Macik

Ki kell próbálni, hogy MS alatt hova és miképpen megy be egy ilyetén felparaméterezett syslog hívás. El tudom képzelni, hogy a Win verzió a megfelelő helyre tolja az üzenetet a megfelelő transzformációval.
Károly viszont a /var/log útvonallal egyértelműen specifikálta a cél OS-t, ergo neki elég volt az rsyslog konfigurálása. Aki meg Winen akarja, az az ottani megfelelő eszközzel fogja ezt megtenni (biztosra veszem, hogy MS alatt is lehet a logokat szűrni, parse-olni. Ha a gyári logger nem tudja, akkor tudni fogja harmadik gyártó cucca.).

Na az az a kb. 50%, amivel nincs baj :D

https://bbs.archlinux.org/viewtopic.php?id=187063

Az ilyen szintű balfaszkodásuk miatt gondolom azt, hogy ezek a PHP-s arcok teljes mértékben alkalmatlanok egy programozási nyelv tutujgatására. Többedszerre derül ki, hogy amikor évekkel ezelőtt valami feature-nél default értéket kellett választani, akkor ők a nem biztonságost választották. Majd idővel körmükre égett a dolog. Menjenek, tenyésszenek inkább nyulakat.

Feltéve, hogy ilyen konfigurábilis syslog-ja van. És a rendszergazdája jónak látja, hogy minden lelkes kezdő a syslog-ot használja.
Ha ezek valamelyik nem teljesül, akkor mégis egyszerűbb az, hogy

file_put_contents ('/home/tester/naplom', sprintf ("%d %s", $foo, $bar), FILE_APPEND);

Azert a syslogba php logolas messze van a "helyes" uttol, barmennyire is nehez az-ultimate-megoldast megtalalni.
Miert nem javasolt senki valami logger frameworkot, mondjuk log4phpt (http://logging.apache.org/log4php/)? Lehet, hogy agyuval verebre ebben az esetben, megis valami standardizalt megoldas, a syslogba hanyas nelkul.

Ezzel az erővel mondhatjuk azt is, hogy a mail se logoljon oda, hiszen mondjuk egy postfix sem a rendszer része, logoljon ő is egyénileg. Ugyanakkor egy syslog-ng vagy rsyslog sem alapvető (annyi, hogy a disztrók felteszik neked előre), ergo ugyanannyi, mint egy framework. Azt gondolom, hogy ha már van egy ilyen belőtt eszköz rá, akkor felesleges még egy harmadik utas megoldást is implementálni.

Használj egy normális logging frameworköt, mondjuk log4php-t. Ha pedig még több okosságot akarsz és/vagy váltanál később másra, akkor csapd hozzá az lf4php-t (ez itt a reklám helye).