Rsyslog - Logging to a Remote Server
Ubuntu has 'rsyslog' installed by default which contains the facility to act as a remote logging server, as well as act as a client that can log to a remote server. 'rsyslog' uses port 514 (either UDP or TCP) to log messages.
Key things to remember:
- The client and server configuration files need to be updated -- '/etc/rsyslog.conf'.
- The server's security group (firewall rules) needs to allow connections to UDP or TCP port 514 from logging clients.
- Realistically, each Apache site configuration file needs to be updated in order to log to 'syslog'.
Configuring the remote server
The 'rsyslog' configuration of the remote server needs to be changed to allow remote connections, and configure where log messages will go.
Edit the '/etc/rsyslog.conf' file so that the modules section is as below:
################# #### MODULES #### ################# module(load="imuxsock") # provides support for local system logging #module(load="immark") # provides --MARK-- message capability # provides UDP syslog reception module(load="imudp") input(type="imudp" port="514") # provides TCP syslog reception module(load="imtcp") input(type="imtcp" port="514")
This should only involve uncommenting some of the lines above.
Then underneath, add the following lines between the "GLOBAL DIRECTIVES" comment and the "Use traditional timestamp format.' comment.
Change YOUR_CLIENT_IP_ADDRESS_RANGE to an appropriate address range, e.g., '172.1.2.0/24'.
########################### #### GLOBAL DIRECTIVES #### ########################### $AllowedSender UDP, TCP, 127.0.0.1, YOUR_CLIENT_IP_ADDRESS_RANGE $template remote-incoming-logs,"/var/log/%HOSTNAME%/%PROGRAMNAME%.log" *.* ?remote-incoming-logs & ~ # # Use traditional timestamp format. # To enable high precision timestamps, comment out the following line. #
That is all that needs to be configured on the server. Restart the daemon using:
$ sudo service rsyslog restart
Optional: Logging to MySQL from Rsyslog
It is also possible and fairly simple to log to MySQL from 'rsyslog'. This can achieved in approximately four steps:
- Install MySQL/Mariadb.
- Login to MySQL/Mariadb and create an appropriate database.
- Create a MySQL user for 'rsyslog' and grant it appropriate permissoins.
- Install the 'rsyslog-mariadb' package.
Read on for more details.
First, install MySQL or Mariadb:
$ sudo apt install mariadb-server
Then, login:
$ sudo mysql MariaDB>
Paste into the MySQL the contents of the file createDb.sql, which is provided under the 'plugins' directory of the 'rsyslog' source.
Then create an appropriate user account:
MariaDB> CREATE USER 'rsyslog'@'localhost'; MariaDB> GRANT INSERT ON Syslog.* TO 'rsyslog'@'localhost';
Finally, on Unbutnu, you can simply install the 'rsyslog-mysql' package.
$ sudo apt install rsyslog-mysql
This will add the required modules; and add a configuration file at: '/etc/rsyslog.d/mysql.conf'.
For generic instructions, See the reference below [3] for generic instructions that appy to a range of operating systems and databases.
Configuring the client server
On the client, edit the '/etc/rsyslog.conf' file.
Again, between the "GLOBAL DIRECTIVES" comment and the "Use traditional timestamp format.' comment, add the following lines, replacing YOUR_SERVER_IP_ADDRESS with your server's IP address.
########################### #### GLOBAL DIRECTIVES #### ########################### *.* @YOUR_SERVER_IP_ADDRESS:514 $ActionQueueFileName queue $ActionQueueMaxDiskSpace 1g $ActionQueueSaveOnShutdown on $ActionQueueType LinkedList $ActionResumeRetryCount -1 # # Use traditional timestamp format. # To enable high precision timestamps, comment out the following line. #
Be sure to keep the '@'. Note, add an additional '@' symbol to log using TCP. For example.
*.* @@YOUR_SERVER_IP_ADDRESS:514
Configuring Apache websites
Important: for many operating system default configurations, doing the following will start also outputing error_log messages to '/var/log/syslog' on the client machine. To prevent this, on the client machine, edit '/etc/rsyslog.d/50-default.conf', and change the following line, replacing 'local6' with whatever facility you specify in your Apache configuration below:
*.*;auth,authpriv.none -/var/log/syslogto:
*.*;auth,authpriv.none;local6.none -/var/log/syslog
Note, the following seems to override any other ErrorLog or ErrorLogFormat directives. In each Apache site configuration file, add the following to an appropriate Directory element replacing 'YOUR_IDENTIFIER' with the name you want for the log file without '.log'. E.g. 'my_websiite'.
<Directory /path/to/website/> php_value error_log syslog php_admin_value syslog.ident YOUR_IDENTIFIER php_admin_value syslog.facility local6 </Directory>
If you want to continue logging to the client machine, add an 'rsyslog' configuration file - say, '/etc/rsyslog.d/70-local6.conf' - similar to below:
# Log local6 generated log messages to file local6.* /var/log/local6.log #OR for each website: :syslogtag, isequal, "YOUR_IDENTIFIER:" /var/log/YOUR_IDENTIFIER.log & stop
Configuring PHP command line programs
Important: for many operating system default configurations, doing the following will start also outputing error_log messages to '/var/log/syslog' on the client machine. To prevent this, on the client machine, edit '/etc/rsyslog.d/50-default.conf', and change the following line, replacing 'local6' with whatever facility you specify in the call to 'openlog' below:
*.*;auth,authpriv.none -/var/log/syslogto:
*.*;auth,authpriv.none;local6.none -/var/log/syslog
Using 'syslog' in PHP command line programs is relatively straight forward. Within your code you first need to initialise logging by calling the 'openlog' function. Then, whenever you want to log something, you call the 'syslog' function. Finally, before the program finishes, call the 'closelog' function.
openlog( "PROGRAM_NAME", LOG_PID | LOG_PERROR, LOG_LOCAL6 ); ... syslog( LOG_ERR, "Your log message" ); ... closelog();
Refer to the references below for details. In short:
- LOG_PID - causes the process identifier to be logged with each message.
- LOG_PERROR - causes the message to be also logged to the std out.
- LOG_LOCAL6 - causes the message to be logged to the 'local6' facility.
By default, if no configuration has been changed, log lines will usually log to '/var/log/syslog'.
The same as the Apache instructions above, to log all 'local6' log lines to one file or log a program to its own separate log file, you could add an 'rsyslog' configuration file - say, '/etc/rsyslog.d/70-local6.conf' - similar to below:
# Log local6 generated log messages to file local6.* /var/log/local6.log # Log program to its own file :programname, isequal, "PROGRAM_NAME" /var/log/MY_PROGRAM_LOGFILE_NAME.log & stop
If it is not clear, the programname you use in the PHP program, must match the value tested using 'isequal'; and the log facility you use in the PHP program, e.g., 'LOG_LOCAL6', must match the log facility used in the rsyslog configuration file, e.g., 'local6.*'.
References
The following websites were referred to while developing this content:
-
How to configure Rsyslog server on Ubuntu 22.04
https://utho.com/docs/tutorial/how-to-setup-rsyslog-server-on-ubuntu-22-04/ -
How to Set Up Remote Logging on Linux Using rsyslog
https://www.makeuseof.com/set-up-linux-remote-logging-using-rsyslog/ -
Writing syslog messages to MySQL, PostgreSQL or any other supported Database
https://www.rsyslog.com/doc/v8-stable/tutorials/database.html -
How to change configuration settings (PHP Manual)
https://www.php.net/manual/en/configuration.changes.php