From 23fc611461fb5f9026bd4bb3a4e3a0efcb8630b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lassi=20P=C3=B6l=C3=B6nen?= Date: Mon, 26 May 2025 17:57:09 +0300 Subject: [PATCH] Add metadata to pgaudit log logline (#11933) Previously we were using project-id/endpoint-id as SYSLOGTAG, which has a limit of 32 characters, so the endpoint-id got truncated. The output is now in RFC5424 format, where the message is json encoded with additional metadata `endpoint_id` and `project_id` Also as pgaudit logs multiline messages, we now detect this by parsing the timestamp in the specific format, and consider non-matching lines to belong in the previous log message. Using syslog structured-data would be an alternative, but leaning towards json due to being somewhat more generic. --- compute_tools/src/compute.rs | 25 +++++++------------ .../compute_audit_rsyslog_template.conf | 22 +++++++++++++--- compute_tools/src/rsyslog.rs | 6 +++-- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/compute_tools/src/compute.rs b/compute_tools/src/compute.rs index f494e2444a..cb857e0a3e 100644 --- a/compute_tools/src/compute.rs +++ b/compute_tools/src/compute.rs @@ -695,25 +695,18 @@ impl ComputeNode { let log_directory_path = Path::new(&self.params.pgdata).join("log"); let log_directory_path = log_directory_path.to_string_lossy().to_string(); - // Add project_id,endpoint_id tag to identify the logs. + // Add project_id,endpoint_id to identify the logs. // // These ids are passed from cplane, - // for backwards compatibility (old computes that don't have them), - // we set them to None. - // TODO: Clean up this code when all computes have them. - let tag: Option = match ( - pspec.spec.project_id.as_deref(), - pspec.spec.endpoint_id.as_deref(), - ) { - (Some(project_id), Some(endpoint_id)) => { - Some(format!("{project_id}/{endpoint_id}")) - } - (Some(project_id), None) => Some(format!("{project_id}/None")), - (None, Some(endpoint_id)) => Some(format!("None,{endpoint_id}")), - (None, None) => None, - }; + let endpoint_id = pspec.spec.endpoint_id.as_deref().unwrap_or(""); + let project_id = pspec.spec.project_id.as_deref().unwrap_or(""); - configure_audit_rsyslog(log_directory_path.clone(), tag, &remote_endpoint)?; + configure_audit_rsyslog( + log_directory_path.clone(), + endpoint_id, + project_id, + &remote_endpoint, + )?; // Launch a background task to clean up the audit logs launch_pgaudit_gc(log_directory_path); diff --git a/compute_tools/src/config_template/compute_audit_rsyslog_template.conf b/compute_tools/src/config_template/compute_audit_rsyslog_template.conf index 9ca7e36738..48b1a6f5c3 100644 --- a/compute_tools/src/config_template/compute_audit_rsyslog_template.conf +++ b/compute_tools/src/config_template/compute_audit_rsyslog_template.conf @@ -2,10 +2,24 @@ module(load="imfile") # Input configuration for log files in the specified directory -# Replace {log_directory} with the directory containing the log files -input(type="imfile" File="{log_directory}/*.log" Tag="{tag}" Severity="info" Facility="local0") +# The messages can be multiline. The start of the message is a timestamp +# in "%Y-%m-%d %H:%M:%S.%3N GMT" (so timezone hardcoded). +# Replace log_directory with the directory containing the log files +input(type="imfile" File="{log_directory}/*.log" + Tag="pgaudit_log" Severity="info" Facility="local5" + startmsg.regex="^[[:digit:]]{{4}}-[[:digit:]]{{2}}-[[:digit:]]{{2}} [[:digit:]]{{2}}:[[:digit:]]{{2}}:[[:digit:]]{{2}}.[[:digit:]]{{3}} GMT,") + # the directory to store rsyslog state files global(workDirectory="/var/log/rsyslog") -# Forward logs to remote syslog server -*.* @@{remote_endpoint} +# Construct json, endpoint_id and project_id as additional metadata +set $.json_log!endpoint_id = "{endpoint_id}"; +set $.json_log!project_id = "{project_id}"; +set $.json_log!msg = $msg; + +# Template suitable for rfc5424 syslog format +template(name="PgAuditLog" type="string" + string="<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% - - - - %$.json_log%") + +# Forward to remote syslog receiver (@@:;format +local5.info @@{remote_endpoint};PgAuditLog diff --git a/compute_tools/src/rsyslog.rs b/compute_tools/src/rsyslog.rs index c873697623..3bc2e72b19 100644 --- a/compute_tools/src/rsyslog.rs +++ b/compute_tools/src/rsyslog.rs @@ -84,13 +84,15 @@ fn restart_rsyslog() -> Result<()> { pub fn configure_audit_rsyslog( log_directory: String, - tag: Option, + endpoint_id: &str, + project_id: &str, remote_endpoint: &str, ) -> Result<()> { let config_content: String = format!( include_str!("config_template/compute_audit_rsyslog_template.conf"), log_directory = log_directory, - tag = tag.unwrap_or("".to_string()), + endpoint_id = endpoint_id, + project_id = project_id, remote_endpoint = remote_endpoint );