Sending syslog Messages

From Nutwiki
Jump to: navigation, search

Description

This example demonstrates how to use the syslog functions of Nut/OS to easily log messages from your application.

Syslog is generally useful but comes in especially handy if your application requires the serial interface for other things (like connections to a machine that communicates via RS232).

Source Code

<source lang="c">

  1. include <io.h>
  2. include <stdio.h>
  3. include <string.h>
  1. include <dev/board.h>
  1. include <sys/socket.h>
  2. include <sys/confnet.h>
  3. include <sys/syslog.h>
  4. include <sys/version.h>
  1. include <arpa/inet.h>
  1. include <net/route.h>
  2. include <netinet/in.h>
  1. include <pro/dhcp.h>
  1. define MY_SYSLOG "192.168.192.161"

int main(void) {

   u_long baud = 115200;
   NutRegisterDevice(&DEV_DEBUG, 0, 0);
   freopen(DEV_DEBUG_NAME, "w", stdout);
   _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
   puts("\nNut/OS Syslog Message example ");
   if (NutRegisterDevice(&DEV_ETHER, 0, 0)) {
       puts("Registering " DEV_ETHER_NAME " failed.");
   }
   else if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000)) {
       puts("Configuring " DEV_ETHER_NAME " failed.");
   }
   openlog("Nut/OS Test Node", 0, LOG_USER);
   setlogserver(inet_addr(MY_SYSLOG), 0);
   syslog(LOG_INFO, "The example started on Nut/OS %s", NutVersionString());
   NutSleep(3000);
   for (;;) {
       syslog(LOG_DEBUG, "This is a debug level message."
                         "You can use me to output debug"
                         "information for your program.");
       syslog(LOG_INFO, "This is an info level message."
                        "I can tell your users stuff"
                        "they might want to know.");
       syslog(LOG_NOTICE,
              "This is a notice level message. You should"
              "use me when you want to signal key events"
              "in your software.");
       syslog(LOG_WARNING,
              "This is a warning level message. I tell your"
              "users about errors that should be avoided but"
              "are not critical.");
       syslog(LOG_CRIT, "This is a critical level message."
                        "Use me to send warnings about"
                        "situations that are really undesirable.");
       syslog(LOG_ALERT,
              "This is an alert level message. I ring the"
              "bells when things are going wrong and someone"
              "has to take action immediately.");
       syslog(LOG_EMERG,
              "This is an emergency level message. If you use"
              "me, your software is most probably already FUBAR"
              "and requires immediate admin intervention.");
       NutSleep(10000);
   }
   return 0;

} </source>

Details

<source lang="c">

   u_long baud = 115200;
   NutRegisterDevice(&DEV_DEBUG, 0, 0);
   freopen(DEV_DEBUG_NAME, "w", stdout);
   _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
   puts("\nNut/OS Syslog Message example ");
   if (NutRegisterDevice(&DEV_ETHER, 0, 0)) {
       puts("Registering " DEV_ETHER_NAME " failed.");
   }
   else if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000)) {
       puts("Configuring " DEV_ETHER_NAME " failed.");
   }

</source>

We initialize our debug device and configure the ethernet interface via DHCP or a stored configuration.

<source lang="c">

   openlog("Nut/OS Test Node", 0, LOG_USER);
   setlogserver(inet_addr(MY_SYSLOG), 0);

</source>

This is all that is required to initialize the syslog output. The openlog call allocates all required resources to begin syslogging. It takes 3 parameters, the first is a string containing the name that our board should use in the syslog, the second specifies additional parameters that have to be OR'ed together (see the help file for more details on this) and the third parameter sets the output facility. In case you want to integrate your syslog messages with some network systems that have to be monitored, you may want to choose a special facility here. For standalone applications the default (LOG_USER) is usually the best choice.

The setlogserver call does exactly what it says on the tin: It sets the log server. Since syslog uses UDP, there is no actual connection to the server being made nor does the application check back if the server really exists. Making sure that the server address is correct is the user's responsibility. The second parameter may be used to specify a certain port for syslog messages, 0 will choose the default port.

<source lang="c"> syslog(LOG_INFO, "The example started on Nut/OS %s", NutVersionString()); </source>

Before entering the main application loop we send a syslog message to signal the succesful start of our example application. The first parameter specifies the message level, which indicates how important and/or severe the message is. Syslog messages may be used for anything from debug messages over user notifications to reporting system critical conditions so choosing the right level should be a no-brainer. The second parameter is the actual message to be sent. As you can see, it supports printf-like string formatting to let you easily embed your own data into the messages.

<source lang="c">

       syslog(LOG_DEBUG, "This is a debug level message."
                     "You can use me to output debug"
                     "information for your program.");
   syslog(LOG_INFO, "This is an info level message."
                    "I can tell your users stuff"
                    "they might want to know.");
   syslog(LOG_NOTICE,
          "This is a notice level message. You should"
          "use me when you want to signal key events"
          "in your software.");
   syslog(LOG_WARNING,
          "This is a warning level message. I tell your"
          "users about errors that should be avoided but"
          "are not critical.");
   syslog(LOG_CRIT, "This is a critical level message."
                    "Use me to send warnings about"
                    "situations that are really undesirable.");
   syslog(LOG_ALERT,
          "This is an alert level message. I ring the"
          "bells when things are going wrong and someone"
          "has to take action immediately.");
   syslog(LOG_EMERG,
          "This is an emergency level message. If you use"
          "me, your software is most probably already FUBAR"
          "and requires immediate admin intervention.");

</source>

Here you can see all the different severity levels applied. Depending on the server software you are using these may be displayed to users or automatically e-mail the network admin, so be careful to choose a fitting level.

You may never need it since most applications rarely have a reason to close their logs when logging to a syslog server but there is also a way to close the syslog and release the occupied resources: <source lang="c"> closelog() </source>

It takes no parameters.

Output

In order to be able to see the output of this example, you'll need a syslog server listening for incoming log messages. Tftpd32 - which some of you may already be using for their boards anyway - comes with an extremely light-weight, built-in syslog server that lets you see the syslog messages the example sends to it. It does not display the different severity levels, though.

Don't forget to adjust the server address defined at the beginning of the source or you won't get any messages!

If you happen to be running this example with a more involved syslog server, you may want to replace the output above so that the severity levels will be displayed as well.

See also