![]() |
General Programming »
Internet / Network »
General
Intermediate
Simple syslog clientBy Gisle VanemA BSD-compatible syslog client |
VC6, VC7, VC7.1Win2K, WinXP, Win2003, Visual Studio, MFC, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||
This article describes a simple BSD-compatible syslog client. The client will log one-line messages to a .log-file and/or logging daemon. There are probably several other similar clients around, but I decided to make my own. This client will work fine in a Unix environment where typically a server collects status information from several machines.
I decided not to make this into a static library or a .DLL. Using it in your own application is as easy as including 4 files into our project (syslog.[ch] and printk.[ch])
The syslog()facility (as defined by the syslog.h header-file) is a rather difficult and clumsy API. E.g. the authors defined the higher log-priorities as lower numbered values. This implementation is not fully POSIX compatible; E.g. it does not honour the LOG_ODELAY or LOG_NOWAIT options. But then again these seems to be deprecated in current BSD OS'es. See the POSIX syslog-spec for a comparision.
The client is initialised by calling the openlog() function. This will cause all syslog() messages to be written to a .log-file and optionally to be sent to a local syslog-daemon (at localhost/127.0.0.1). The default .log-file is deducted from the application using the client; E.g. c:\temp\foo.exe will open c:\temp\foo.log and append to that file. A line written to the .log-file could look like this:
<150>2003-09-03 21:00:39 demo[1604]: syslog client at 10.0.0.6 started.
(1) (2) (3) (4) (5)
LOG_EMERG - LOG_DEBUG) and facility value (LOG_KERN - LOG_LOCAL7) OR'ed together. This field cannot be supressed. The priority is in the lower 4 bits and facility value in the rest. Use the LOG_PRI() macro to extract the priority. And use the LOG_FAC() macro to extract the facility.
openlog() or setlogtag().
LOG_PID was given in openlog().
syslog() or vsyslog()The UDP port used is 514 unless specified differently in %SystemRoot%\system32\drivers\etc\services. A line like this should be used:
syslog 514/udp
Note that lines written to syslog log-file at the daemon side is different; The date/time is
first. Then the IP-address from where the message was received, then fields (3) to (5).
This function must be called before syslog(). The ident determines the 3rd (demo) parameter on the syslog line. options is a combination of OR'ed values;
LOG_PID - The process identifier should be included in log-line.
LOG_CONS - Log to console (stdout) for LOG_ERR messages.
LOG_PERROR - Log to console (stderr) as well.
LOG_NDELAY - log file/connection should be opened immediately.
LOG_ODELAY, LOG_NOWAIT - These are ignored. logfac is the facility to log to (LOG_KERN - LOG_LOCAL7).
Returns -1 if failed to open .log-file for writing or failed to connect to the syslog-daemon.
Close the log-file and/or UDP connection to the syslog-daemon. It's not necessary to call closelog() prior to exit as it is registered as an atexit() function.
If mask is non-zero, sets a new priority logmask and returns the previous value. Default is to log everything (logMask = 0xFF).
Sets up the var-arg list and calls vsyslog().
The main logging function. Handle the message if pri is above current priority. See <syslog.h> for the priority codes. Prints message to stderr if LOG_PERROR was specified in openlog(). Or if sendto() fails and LOG_CONS was specified in openlog().
Returns 0 if message is not handled or is written okay. Otherwise use syslog_strerror() to get the error-text of last error.
Specifies the host to send messages to. A hostname or dotted IPv4-address is accepted. Use 0.0.0.0 to disable sending to syslog-daemon. Or use 255.255.255.255 to send to any daemon that's setup to receive broadcast messages. It must be on your local network as broadcast doesn't reach beyond a router. This function should be called prior to openlog() if the default 127.0.0.1 destination is not wanted.
Returns NULL if unable to resolve the host to an IP-address.
Returns the name of current .log-file.
Returns an error-string for last failed operation.
syslog() and vsyslog() supports a limited sub-set of formats compared to the printf() family of functions. E.g. floating-point formats and long modifier (%lu) are not supported at this time. These special formats are also supported:
%I - Prints the corresponding argument as an IP-address on network order.
%t - Prints the local date and time (ISO-9601).
%m - Prints the error-string for current errno.
%M - Prints the error-string for current GetLastError().
%S - Prints the name of a signal in the argument list. As you see the %S is reserved for printing a signal-name. So printing wide-character strings are not possible using syslog().
sendto() on UDP messages gives rather limited error messages compared to BSD or Linux, my implementation uses some tricks;
setsockopt() with SO_BROADCAST is called.
sendto(). The only accepted error is WSAEMSGSIZE, otherwise the socket is closed. Truncating a message is IMHO acceptable. WSAECONNRESET (ICMP port unreachable) on a subsequent call to sendto(). This doesn't seem to be true in my case (Win-XP). And even worse; sending to a non-existant host (on the LAN) does not give a WSAEHOSTUNREACH either. Sigh. So this client will transmit and generate an ICMP error for every message sent unless there is a syslog-daemon at the destination address (ignoring ICMP rate limiting of the destination host). But syslog messages should be used sparingly. Don't write all kind of debug-messages to syslogd. It's better to use some local file for that.
To receive syslog messages over the network (or the loopback interface), you off-course need a syslog daemon (server). I highly recommend Herbert Hanewinkel's syslog-daemon for Windows. Look at http://www.hanewin.de/syslog-e.htm. This is a light-weight, no frills and stable little syslog-daemon. A minor drawback is that it doesn't handle fragmented messages; I.e. will only log messages that fits in one MTU.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 3 Sep 2003 Editor: Nishant Sivakumar |
Copyright 2003 by Gisle Vanem Everything else Copyright © CodeProject, 1999-2009 Web09 | Advertise on the Code Project |