Thread: Re: Truncate logs by max_log_size

Re: Truncate logs by max_log_size

From
"Euler Taveira"
Date:
On Thu, Sep 26, 2024, at 3:30 PM, diPhantxm wrote:
I would like to suggest a patch to truncate some long queries. I believe sometimes there is no need to log a query containing some gigabytes of blob, for example. In patch a new parameter, named max_log_size, is introduced. It defines the maximum size of logged query, in bytes. Everything beyond that size is truncated.

I don't know how useful is this proposal. IMO the whole query is usually
crucial for an analysis. Let's say you arbitrarily provide max_log_size = 100
but it means you cannot see a WHERE clause and you have a performance issue in
that query. It won't be possible to obtain the whole query for an EXPLAIN. It
would break audit systems that requires the whole query. I don't know if there
are some log-based replication systems but it would break such tools too.

There are other ways to avoid logging such long queries. The GRANT ... ON
PARAMETER and SET LOCAL commands are your friends. Hence, you can disable
specific long queries even if you are not a superuser.

If your main problem is disk space, you can adjust the rotation settings or have
an external tool to manage your log files (or even use syslog).


--
Euler Taveira

Re: Truncate logs by max_log_size

From
"Andrey M. Borodin"
Date:

> On 27 Sep 2024, at 03:30, Euler Taveira <euler@eulerto.com> wrote:
>
> Let's say you arbitrarily provide max_log_size = 100

Consider max_log_size = 10Mb. The perspective might look very different. It’s not about WHERE anymore. It's a guard
againstheavy abuse. 

The feature looks very important for me.


Best regards, Andrey Borodin.


Re: Truncate logs by max_log_size

From
Jim Jones
Date:
On 27.09.24 12:36, Andrey M. Borodin wrote:
> Consider max_log_size = 10Mb. The perspective might look very different.
>  It’s not about WHERE anymore. It's a guard against heavy abuse.
>
> The feature looks very important for me.
I have the same opinion. As a fail safe it sounds very useful to me.

Unfortunately, the patch does not apply:

$ git apply
~/patches/max_log_query/0001-parameter-max_log_size-to-truncate-logs.patch
-v
Checking patch src/backend/utils/error/elog.c...
error: while searching for:
char       *Log_destination_string = NULL;
bool            syslog_sequence_numbers = true;
bool            syslog_split_messages = true;

/* Processed form of backtrace_symbols GUC */
static char *backtrace_symbol_list;

error: patch failed: src/backend/utils/error/elog.c:114
error: src/backend/utils/error/elog.c: patch does not apply
Checking patch src/backend/utils/misc/guc_tables.c...
Hunk #1 succeeded at 3714 (offset 247 lines).
Checking patch src/backend/utils/misc/postgresql.conf.sample...
Hunk #1 succeeded at 615 (offset 23 lines).
Checking patch src/bin/pg_ctl/t/004_logrotate.pl...
error: while searching for:
check_log_pattern('csvlog',  $new_current_logfiles, 'syntax error', $node);
check_log_pattern('jsonlog', $new_current_logfiles, 'syntax error', $node);

$node->stop();

done_testing();

error: patch failed: src/bin/pg_ctl/t/004_logrotate.pl:135
error: src/bin/pg_ctl/t/004_logrotate.pl: patch does not apply
Checking patch src/include/utils/elog.h...
Hunk #1 succeeded at 502 (offset 1 line).

Does it truncate only single queries or also a transaction with many
statements?

Thanks!

Best, Jim



Re: Truncate logs by max_log_size

From
Greg Sabino Mullane
Date:
On Fri, Sep 27, 2024 at 6:37 AM Andrey M. Borodin <x4mmm@yandex-team.ru> wrote:
Consider max_log_size = 10Mb. The perspective might look very different. It’s not about WHERE anymore. It's a guard against heavy abuse.

Can you elaborate on this? Do you mean someone purposefully writing large entries to your log file?
 

Re: Truncate logs by max_log_size

From
Jim Jones
Date:

On 01.10.24 17:46, Kirill Gavrilov wrote:
>  My apologies, attached patch should work on master branch.

Nice.

I tested the feature and it does what it is intended to.

postgres=# SHOW max_log_size;
 max_log_size
--------------
 10
(1 row)

postgres=# INSERT INTO t VALUES (1,2,3,4,5,6,7,8,9,0);
ERROR:  relation "t" does not exist
LINE 1: INSERT INTO t VALUES (1,2,3,4,5,6,7,8,9,0);

Log file:

2024-10-02 00:57:13.618 CEST [1975926] ERROR:  relation "t" does not
exist at character 13
2024-10-02 00:57:13.618 CEST [1975926] STATEMENT:  INSERT INT

A few observations:

1) You missed a const qualifier in elog.c:

elog.c: In function ‘EmitErrorReport’:
elog.c:1699:29: warning: initialization discards ‘const’ qualifier from
pointer target type [-Wdiscarded-qualifiers]
 1699 |                 char* str = debug_query_string;
      |                             ^~~~~~~~~~~~~~~~~~

2) The new parameter cannot be set within a session with SET. Is it
supposed to be like this? IMHO it would be nice to able to temporarily
set this parameter without having to reload the postgresql.conf

postgres=# SET max_log_size TO 100;
ERROR:  parameter "max_log_size" cannot be changed now

3) I personally find -1 more intuitive than 0 to disable a parameter,
but I have no strong opinion about it.

4) It still lacks documentation.

-- 
Jim