Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of pgaudit.log_rotation_size option #45

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ Number of minutes after which the audit file will be rotated.
- If _log_rotation_age < 60_ the rotation background worker will wake up every 10 seconds.
- If _log_rotation_age > 60_ the rotation background worker will wake up every 1 minute.

### pgaudit.log_rotation_size
This parameter determines the maximum size of an individual log file. Turns on only when the parameter is explicitly specified and adds microseconds to the end of the file name, so the 'pgaudit-%Y-%m-%d_%H%M%S.log' pattern is preferred.

**Scope**: System

**Default**: 0

### pgaudit.log_connections
Intercepts server log messages emited when log_connections is on

Expand Down
6 changes: 6 additions & 0 deletions logtofile.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ void _PG_init(void)
INT_MAX / SECS_PER_MINUTE, PGC_SIGHUP,
GUC_NOT_IN_SAMPLE | GUC_UNIT_MIN | GUC_SUPERUSER_ONLY, NULL, NULL, NULL);

DefineCustomIntVariable(
"pgaudit.log_rotation_size",
"Automatic rotation of logfiles will happen after that much log output", NULL,
&guc_pgaudit_ltf_log_rotation_size, 0, 0, INT_MAX / 1024, PGC_SIGHUP,
GUC_NOT_IN_SAMPLE | GUC_SUPERUSER_ONLY | GUC_UNIT_KB, NULL, NULL, NULL);

DefineCustomBoolVariable(
"pgaudit.log_connections",
"Intercepts log_connections messages", NULL,
Expand Down
3 changes: 3 additions & 0 deletions logtofile_bgw.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ void PgAuditLogToFileMain(Datum arg)
int sleep_ms = SECS_PER_MINUTE * 1000;
MemoryContext PgAuditLogToFileContext = NULL;

pgaudit_ltf_shm->worker_latch = &MyProc->procLatch;
pqsignal(SIGHUP, pgauditlogtofile_sighup);
pqsignal(SIGINT, SIG_IGN);
pqsignal(SIGTERM, pgauditlogtofile_sigterm);
Expand Down Expand Up @@ -101,6 +102,8 @@ void PgAuditLogToFileMain(Datum arg)
PgAuditLogToFile_calculate_current_filename();
PgAuditLogToFile_set_next_rotation_time();
ereport(DEBUG3, (errmsg("pgauditlogtofile bgw loop new filename %s", pgaudit_ltf_shm->filename)));
pgaudit_ltf_shm->size_rotation_flag = false;
pgaudit_ltf_shm->total_written_bytes = 0;
}
}

Expand Down
33 changes: 33 additions & 0 deletions logtofile_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "logtofile_guc.h"
#include "logtofile_shmem.h"
#include "logtofile_vars.h"
#include "logtofile_filename.h"

#include <access/xact.h>
#include <lib/stringinfo.h>
Expand All @@ -30,6 +31,7 @@
#include <storage/proc.h>
#include <tcop/tcopprot.h>
#include <utils/ps_status.h>
#include <utils/wait_event.h>

#include <pthread.h>
#include <time.h>
Expand Down Expand Up @@ -136,9 +138,28 @@ bool pgauditlogtofile_is_enabled(void)
bool pgauditlogtofile_record_audit(const ErrorData *edata, int exclude_nchars)
{
bool rc;
int deviation;

ereport(DEBUG5, (errmsg("pgauditlogtofile record audit in %s (shm %s)",
filename_in_use, pgaudit_ltf_shm->filename)));

if(!(MyProc == NULL && IsUnderPostmaster) && guc_pgaudit_ltf_log_rotation_size > 0)
{
deviation = (int)(guc_pgaudit_ltf_log_rotation_size * 1024L * 0.0009);
LWLockAcquire(pgaudit_ltf_shm->lock, LW_EXCLUSIVE);
if (pgaudit_ltf_shm->total_written_bytes + deviation >= guc_pgaudit_ltf_log_rotation_size * 1024L)
{
pgaudit_ltf_shm->total_written_bytes = 0;
LWLockRelease(pgaudit_ltf_shm->lock);
pgaudit_ltf_shm->size_rotation_flag = true;
ereport(DEBUG3, (errmsg("pgauditlogtofile the log file size limit has been reached - file update. Current file: %s", pgaudit_ltf_shm->filename)));
SetLatch(pgaudit_ltf_shm->worker_latch);
}
else
{
LWLockRelease(pgaudit_ltf_shm->lock);
}
}
/* do we need to rotate? */
if (strcmp(filename_in_use, pgaudit_ltf_shm->filename) != 0)
{
Expand Down Expand Up @@ -313,6 +334,18 @@ bool pgauditlogtofile_write_audit(const ErrorData *edata, int exclude_nchars)
errno = save_errno;
}

if (rc > 0 && guc_pgaudit_ltf_log_rotation_size > 0)
{
if(!(MyProc == NULL && IsUnderPostmaster)){
LWLockAcquire(pgaudit_ltf_shm->lock, LW_EXCLUSIVE);
pgaudit_ltf_shm->total_written_bytes += rc;
LWLockRelease(pgaudit_ltf_shm->lock);
}
else{
pgaudit_ltf_shm->total_written_bytes += rc;
}
}

return rc == buf.len;
}

Expand Down
90 changes: 85 additions & 5 deletions logtofile_shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <storage/pg_shmem.h>
#include <storage/shmem.h>
#include <utils/timestamp.h>
#include <sys/time.h>

#include <time.h>

Expand Down Expand Up @@ -137,6 +138,11 @@ void PgAuditLogToFile_shmem_startup(void)
pgaudit_ltf_shm->lock = &(GetNamedLWLockTranche("pgauditlogtofile"))->lock;
PgAuditLogToFile_calculate_current_filename();
PgAuditLogToFile_set_next_rotation_time();

// Initial worker latch
pgaudit_ltf_shm->worker_latch = NULL;
// Initial global log file memory counter
pgaudit_ltf_shm->total_written_bytes = 0;
}
LWLockRelease(AddinShmemInitLock);

Expand Down Expand Up @@ -185,10 +191,78 @@ void PgAuditLogToFile_calculate_current_filename(void)
return;
}

LWLockAcquire(pgaudit_ltf_shm->lock, LW_EXCLUSIVE);
memset(pgaudit_ltf_shm->filename, 0, sizeof(pgaudit_ltf_shm->filename));
strcpy(pgaudit_ltf_shm->filename, filename);
LWLockRelease(pgaudit_ltf_shm->lock);
if(guc_pgaudit_ltf_log_rotation_size > 0)
{
char *last_dot = NULL;
size_t prefix_len;

last_dot = strrchr(filename, '.');
if (last_dot != NULL)
{
prefix_len = last_dot - filename;
}
else
{
last_dot = filename;
prefix_len = sizeof(filename);
}

LWLockAcquire(pgaudit_ltf_shm->lock, LW_EXCLUSIVE);
if (strncmp(filename, pgaudit_ltf_shm->filename, prefix_len) == 0)
{
struct timeval tv;
int microseconds;

gettimeofday(&tv, NULL);

microseconds = tv.tv_usec;

if (last_dot != NULL)
{
char new_filename[MAXPGPATH];

strncpy(new_filename, filename, prefix_len);
new_filename[prefix_len] = '\0';

snprintf(new_filename + prefix_len, sizeof(new_filename) - prefix_len, "_%d%s", microseconds, last_dot);

memset(pgaudit_ltf_shm->filename, 0, sizeof(pgaudit_ltf_shm->filename));
strcpy(pgaudit_ltf_shm->filename, new_filename);
}
else
{
snprintf(pgaudit_ltf_shm->filename, sizeof(pgaudit_ltf_shm->filename), "%s_%d", filename, microseconds);

}
}
else
{
if (last_dot != NULL)
{
char new_filename[MAXPGPATH];

strncpy(new_filename, filename, prefix_len);
new_filename[prefix_len] = '\0';

snprintf(new_filename + prefix_len, sizeof(new_filename) - prefix_len, "_%d%s", 0, last_dot);

memset(pgaudit_ltf_shm->filename, 0, sizeof(pgaudit_ltf_shm->filename));
strcpy(pgaudit_ltf_shm->filename, new_filename);
}
else
{
snprintf(pgaudit_ltf_shm->filename, sizeof(pgaudit_ltf_shm->filename), "%s_%d", filename, 0);
}
}
LWLockRelease(pgaudit_ltf_shm->lock);
}
else
{
LWLockAcquire(pgaudit_ltf_shm->lock, LW_EXCLUSIVE);
memset(pgaudit_ltf_shm->filename, 0, sizeof(pgaudit_ltf_shm->filename));
strcpy(pgaudit_ltf_shm->filename, filename);
LWLockRelease(pgaudit_ltf_shm->lock);
}

pfree(filename);
}
Expand All @@ -200,14 +274,20 @@ void PgAuditLogToFile_calculate_current_filename(void)
*/
bool PgAuditLogToFile_needs_rotate_file(void)
{
pg_time_t now;
pg_time_t now;

if (UsedShmemSegAddr == NULL || pgaudit_ltf_shm == NULL)
return false;

if (guc_pgaudit_ltf_log_rotation_age < 1)
return false;

if((guc_pgaudit_ltf_log_rotation_size > 0) && pgaudit_ltf_shm->size_rotation_flag)
{
ereport(DEBUG3, (errmsg("pgauditlogtofile needs to rotate file %s", pgaudit_ltf_shm->filename)));
return true;
}

now = (pg_time_t) time(NULL);
if (now >= pgaudit_ltf_shm->next_rotation_time)
{
Expand Down
1 change: 1 addition & 0 deletions logtofile_vars.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ char *guc_pgaudit_ltf_log_directory = NULL;
char *guc_pgaudit_ltf_log_filename = NULL;
char *guc_pgaudit_log_last_rotation = NULL;
int guc_pgaudit_ltf_log_rotation_age = HOURS_PER_DAY * MINS_PER_HOUR; // Default: 1 day
int guc_pgaudit_ltf_log_rotation_size = 0;
bool guc_pgaudit_ltf_log_connections = false; // Default: off
bool guc_pgaudit_ltf_log_disconnections = false; // Default: off
int guc_pgaudit_ltf_auto_close_minutes = 0; // Default: off
Expand Down
5 changes: 5 additions & 0 deletions logtofile_vars.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
#include <port/atomics.h>
#include <storage/ipc.h>
#include <storage/lwlock.h>
#include <storage/latch.h>

#include <pthread.h>

// Guc
extern char *guc_pgaudit_ltf_log_directory;
extern char *guc_pgaudit_ltf_log_filename;
extern int guc_pgaudit_ltf_log_rotation_age;
extern int guc_pgaudit_ltf_log_rotation_size;
extern bool guc_pgaudit_ltf_log_connections;
extern bool guc_pgaudit_ltf_log_disconnections;
extern int guc_pgaudit_ltf_auto_close_minutes;
Expand Down Expand Up @@ -58,6 +60,9 @@ typedef struct pgAuditLogToFileShm
size_t num_prefixes_disconnection;
char filename[MAXPGPATH];
pg_time_t next_rotation_time;
int total_written_bytes;
bool size_rotation_flag;
Latch *worker_latch;
} PgAuditLogToFileShm;

// Shared Memory
Expand Down