Go - Logging to the System Log Service

发布时间 2023-09-30 08:26:33作者: ZhangZhihuiAAA

Problem: You want to log in to the system log instead of your logfiles.


Solution: Use the log/syslog package to write to syslog.

 

Syslog is a standard network - based logging protocol. It has long been the de facto standard for logging system events and was created by Eric Allman in the 1980s as part of the Sendmail project. The protocol was documented in RFC 3164 by the Internet Engineering Task Force (IETF). Subsequently, IETF standardized it in RFC 5424.
A syslog message (as in RFC 3164) consists of three parts:

Priority
• Includes the facility and the severity
Header
• Includes the timestamp and the hostname or IP address of the machine
Message
• Includes the tag and the content

The facility describes the type of system that sends the log message. It allows log messages from different facilities to be handled differently. There are 24 facilities defined by the RFCs; here are a few:
• 0 (kernel)
• 1 (user - level)
• 2 (mail)
• 3 (system daemons)
• 4 (security/authorization messages)

The severity level is similar to the log level. Syslog defines eight different levels, with 0 being the highest and 7 being the lowest:
• 0 (Emergency)
• 1 (Alert)
• 2 (Critical)
• 3 (Error)
• 4 (Warning)
• 5 (Notice)
• 6 (Informational)
• 7 (Debug)
The timestamp and the hostname or IP address are self - explanatory. The tag is the name of the program that generated the message, while the content is the details of the log message.

Syslog is not implemented uniformly in different operating systems. A popular implementation of syslog is rsyslog, the default syslog implementation in many Linux variants including Debian, Ubuntu, openSUSE, and others.

Go provides a log/syslog package as part of the standard library to interface with syslog. However, it doesn’t work on all systems. For example, it doesn’t work with Windows because it’s not implemented on Windows.
The example in this recipe is based on running against rsyslog on Ubuntu 20.04, and it should work on systems with rsyslog. However, I have not tried it on all systems and implementations.
Before we start on the Go code, you need to set up rsyslog to show the priority, header, and message parts. In rsyslog this is done using a template in the rsyslog configuration file.
Start by editing the /etc/rsyslog.conf configuration file:

$  sudo  vi  /etc/rsyslog.conf

Add the template configuration after this line — $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat in the configuration file:

$template  gosyslogs,"%syslogseverity - text%  %syslogfacility - text%  %hostname% %timegenerated%  %syslogtag%  %msg%\n"
$ActionFileDefaultTemplate  gosyslogs

In this configuration, you name the template gosyslogs . You set it to show the severity first, followed by the facility, then the hostname and the timestamp, and finally, the tag and message.
Once you save this file, restart rsyslog:

sudo  service  rsyslog  restart

Now that you have set up rsyslog, you can look at the code. Sending log messages to syslog using the syslog package is relatively straightforward:

var   logger   * log . Logger 

func   init ()   { 
      var   err   error 
      logger ,   err   =   syslog . NewLogger ( syslog . LOG_USER | syslog . LOG_NOTICE ,   0 ) 
      if   err   !=   nil   { 
         log . Fatal ( "cannot  write  to  syslog:  " ,   err ) 
      } 
} 

func   main ()   { 
      logger . Print ( "hello  syslog!" ) 
}

You use the NewLogger function to create a logger, passing the syslog priority flags you want to set. The syslog package provides flags for the facility and the severity levels. You can or them together to send the facility code and the severity level. For the case of the preceding code, you send in syslog.LOG_USER indicating the user facility code, and syslog.LOG_NOTICE indicating the notice severity level.
Run the code first in the file named main.go :
$ go run main.go
Now check the syslogs. Run this on the command line:

$ sudo tail /var/log/syslog

You should see a bunch of log messages, but somewhere at the bottom, you should see something like this:

notice user myhostname Jan 26 15:30:08 /tmp/go - build2223050573/b001/exe/
main[163995]:
hello syslog!

The first field is notice , the severity level, followed by user , which is the facility code. Next is myhostname , which is the hostname, followed by the timestamp.
The next field is the tag , which is the /tmp/go - build2223050573/b001/exe/main[163995] field in the log message. Why is it indicating that it’s in the /tmp directory? That’s because you’re using go run . It will look different if you compile the code and run the binary file. The final field in the log message is the details of the log, which you print out using logger .