Thread

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Fix log_statement_max_length test with verbose logs

  2. Add log_statement_max_length GUC to limit logged statement text

  3. Improve user control over truncation of logged bind-parameter values.

  1. Truncate logs by max_log_size

    Kirill Gavrilov <diphantxm@gmail.com> — 2024-09-26T18:30:08Z

    Hi hackers,
    
    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.
    
    Best regards,
    Kirill Gavrilov
    
  2. Re: Truncate logs by max_log_size

    Euler Taveira <euler@eulerto.com> — 2024-09-27T00:30:05Z

    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
    EDB   https://www.enterprisedb.com/
    
  3. Re: Truncate logs by max_log_size

    Andrey Borodin <x4mmm@yandex-team.ru> — 2024-09-27T10:36:58Z

    
    > 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 against heavy abuse.
    
    The feature looks very important for me.
    
    
    Best regards, Andrey Borodin.
    
    
    
  4. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2024-10-01T11:46:44Z

    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
    
    
    
    
  5. Re: Truncate logs by max_log_size

    Greg Sabino Mullane <htamfids@gmail.com> — 2024-10-01T12:43:20Z

    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?
    
  6. Re: Truncate logs by max_log_size

    Kirill Gavrilov <diphantxm@gmail.com> — 2024-10-01T15:46:32Z

    On Tue, Oct 1, 2024 at 2:46 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    
    >
    > 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
    >
    
     My apologies, attached patch should work on master branch.
    It truncates single queries and a statement in transaction that occurred an
    error.
    
  7. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2024-10-01T23:08:43Z

    
    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
    
    
    
    
    
  8. Re: Truncate logs by max_log_size

    Kirill Reshke <reshkekirill@gmail.com> — 2024-11-25T16:52:17Z

    On Tue, 1 Oct 2024 at 20:46, Kirill Gavrilov <diphantxm@gmail.com> wrote:
    >
    > On Tue, Oct 1, 2024 at 2:46 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    >>
    >>
    >> 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
    >
    >
    >  My apologies, attached patch should work on master branch.
    > It truncates single queries and a statement in transaction that occurred an error.
    >
    
    Hello! Please deliver the most recent patch version and fix the issues
    Jim identified [0] as the current commitfest draws to a close.
    Do not forget to include both parts of this patch (This was actually
    developed off-list, and we are now using this on our cloud PostgreSQL
    distribution on versions 12–17).
    
    [0] https://www.postgresql.org/message-id/35096a36-04d4-480b-a7cd-a2d8151fb737%40uni-muenster.de
    
    -- 
    Best regards,
    Kirill Reshke
    
    
    
    
  9. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2024-11-28T14:22:55Z

    
    On 25.11.24 17:52, Kirill Reshke wrote:
    > Hello! Please deliver the most recent patch version and fix the issues
    > Jim identified [0] as the current commitfest draws to a close.
    > Do not forget to include both parts of this patch (This was actually
    > developed off-list, and we are now using this on our cloud PostgreSQL
    > distribution on versions 12–17).
    >
    > [0] https://www.postgresql.org/message-id/35096a36-04d4-480b-a7cd-a2d8151fb737%40uni-muenster.de
    
    In addition to these points, this feature seems to fail with queries
    containing special characters (more than one byte):
    
    With this "max_log_size"..
    
    postgres=# SHOW max_log_size;
     max_log_size
    --------------
     20
    (1 row)
    
    ... and this query ..
    
    postgres=# SELECT "ÄÜÖ" FROM t;
    ERROR:  relation "t" does not exist
    LINE 1: SELECT "ÄÜÖ" FROM t;
    
    .. this is the [truncated] log entry we get ..
    
    2024-11-28 14:58:57.912 CET [2258876] ERROR:  relation "t" does not
    exist at character 19
    2024-11-28 14:58:57.912 CET [2258876] STATEMENT:  SELECT "ÄÜÖ" FROM
    
    ... although the query originally had exactly 20 characters:
    
    postgres=# SELECT length('SELECT "ÄÜÖ" FROM t;');
     length
    --------
         20
    (1 row)
    
    
    postgres=# SELECT length('ÄÜÖ'::bytea), length('AUO'::bytea);
     length | length
    --------+--------
          6 |      3
    (1 row)
    
    If it is supposed to be like this, it should be clearly stated so in the
    docs.
    
    -- 
    Jim
    
    
    
    
    
  10. Re: Truncate logs by max_log_size

    Kirill Gavrilov <diphantxm@gmail.com> — 2024-11-28T19:20:42Z

    On Thu, Nov 28, 2024 at 5:23 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    
    >
    >
    > On 25.11.24 17:52, Kirill Reshke wrote:
    > > Hello! Please deliver the most recent patch version and fix the issues
    > > Jim identified [0] as the current commitfest draws to a close.
    > > Do not forget to include both parts of this patch (This was actually
    > > developed off-list, and we are now using this on our cloud PostgreSQL
    > > distribution on versions 12–17).
    > >
    > > [0]
    > https://www.postgresql.org/message-id/35096a36-04d4-480b-a7cd-a2d8151fb737%40uni-muenster.de
    >
    > In addition to these points, this feature seems to fail with queries
    > containing special characters (more than one byte):
    >
    > With this "max_log_size"..
    >
    > postgres=# SHOW max_log_size;
    >  max_log_size
    > --------------
    >  20
    > (1 row)
    >
    > ... and this query ..
    >
    > postgres=# SELECT "ÄÜÖ" FROM t;
    > ERROR:  relation "t" does not exist
    > LINE 1: SELECT "ÄÜÖ" FROM t;
    >
    > .. this is the [truncated] log entry we get ..
    >
    > 2024-11-28 14:58:57.912 CET [2258876] ERROR:  relation "t" does not
    > exist at character 19
    > 2024-11-28 14:58:57.912 CET [2258876] STATEMENT:  SELECT "ÄÜÖ" FROM
    >
    > ... although the query originally had exactly 20 characters:
    >
    > postgres=# SELECT length('SELECT "ÄÜÖ" FROM t;');
    >  length
    > --------
    >      20
    > (1 row)
    >
    >
    > postgres=# SELECT length('ÄÜÖ'::bytea), length('AUO'::bytea);
    >  length | length
    > --------+--------
    >       6 |      3
    > (1 row)
    >
    > If it is supposed to be like this, it should be clearly stated so in the
    > docs.
    >
    > --
    > Jim
    >
    >   Here is version 3 of this patch. I found another place where this
    setting can be applied.
      Also added some documentation and specified that this setting truncates
    queries by size in bytes.
    
  11. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2024-11-29T00:24:24Z

    
    On 28.11.24 20:20, Kirill Gavrilov wrote:
    >   Here is version 3 of this patch. I found another place where this
    > setting can be applied. 
    >   Also added some documentation and specified that this setting
    > truncates queries by size in bytes.
    
    Thanks. It is now possible to change the parameter using SET
    
    postgres=# SET max_log_size TO 15;
    SET
    postgres=# SHOW max_log_size ;
     max_log_size
    --------------
     15
    (1 row)
    
    
    In the postgresql.conf the default value is set to 0
    
    #max_log_size = 0
    
    But if we take a look at the parameter it shows something else
    
    postgres=# SHOW max_log_size ;
     max_log_size
    --------------
     5242880
    (1 row)
    
    Perhaps it would be best to keep the default value in the
    postgresql.conf consistent with the documentation and the actual
    max_log_size value. IMHO 0 (or -1) should disable it.
    
    There are also several compilation issues:
    
    postgres.c: In function ‘exec_simple_query’:
    postgres.c:1040:9: warning: ISO C90 forbids mixed declarations and code
    [-Wdeclaration-after-statement]
     1040 |         bool copied = false;
          |         ^~~~
    elog.c: In function ‘EmitErrorReport’:
    elog.c:1697:9: warning: ISO C90 forbids mixed declarations and code
    [-Wdeclaration-after-statement]
     1697 |         const char* old_query_string = debug_query_string;
          |         ^~~~~
    elog.c:1744:23: warning: passing argument 1 of ‘pfree’ discards ‘const’
    qualifier from pointer target type [-Wdiscarded-qualifiers]
     1744 |                 pfree(debug_query_string);
          |                       ^~~~~~~~~~~~~~~~~~
    In file included from ../../../../src/include/postgres.h:47,
                     from elog.c:55:
    ../../../../src/include/utils/palloc.h:86:25: note: expected ‘void *’
    but argument is of type ‘const char *’
       86 | extern void pfree(void *pointer);
          |                   ~~~~~~^~~~~~~
    elog.c: In function ‘build_query_log’:
    elog.c:3798:9: warning: ISO C90 forbids mixed declarations and code
    [-Wdeclaration-after-statement]
     3798 |         size_t query_len = strlen(query);
          |         ^~~~~~
    elog.c:3801:24: warning: return discards ‘const’ qualifier from pointer
    target type [-Wdiscarded-qualifiers]
     3801 |                 return query;
          |                        ^~~~~
    elog.c:3805:9: warning: ISO C90 forbids mixed declarations and code
    [-Wdeclaration-after-statement]
     3805 |         size_t query_log_len = pg_mbcliplen(query, query_len,
    max_log_size);
          |         ^~~~~~
    
    and there is a trailing whitespace at:
    
    + *    If query needs to be truncated, copied will be set to true
    
    /home/jim/patches/max_log_query/V3-0001-parameter-max_log_size-to-truncate-logs.patch:141:
    trailing whitespace.
     *      If query needs to be truncated, copied will be set to true
    Checking patch doc/src/sgml/config.sgml...
    Hunk #1 succeeded at 7865 (offset -48 lines).
    Checking patch src/backend/tcop/postgres.c...
    Hunk #1 succeeded at 71 (offset 1 line).
    Hunk #2 succeeded at 1031 (offset 1 line).
    Hunk #3 succeeded at 1083 (offset 1 line).
    Hunk #4 succeeded at 1382 (offset 1 line).
    Hunk #5 succeeded at 1393 (offset 1 line).
    Checking patch src/backend/utils/error/elog.c...
    Hunk #4 succeeded at 3781 (offset -3 lines).
    Checking patch src/backend/utils/misc/guc_tables.c...
    Hunk #1 succeeded at 3714 (offset -10 lines).
    Checking patch src/backend/utils/misc/postgresql.conf.sample...
    Hunk #1 succeeded at 615 (offset -2 lines).
    Checking patch src/bin/pg_ctl/t/004_logrotate.pl...
    Checking patch src/include/utils/elog.h...
    Applied patch doc/src/sgml/config.sgml cleanly.
    Applied patch src/backend/tcop/postgres.c cleanly.
    Applied patch src/backend/utils/error/elog.c cleanly.
    Applied patch src/backend/utils/misc/guc_tables.c cleanly.
    Applied patch src/backend/utils/misc/postgresql.conf.sample cleanly.
    Applied patch src/bin/pg_ctl/t/004_logrotate.pl cleanly.
    Applied patch src/include/utils/elog.h cleanly.
    warning: 1 line adds whitespace errors.
    
    -- 
    Jim
    
    
    
    
    
  12. Re: Truncate logs by max_log_size

    Kirill Gavrilov <diphantxm@gmail.com> — 2024-11-29T11:05:01Z

    On Fri, Nov 29, 2024 at 3:24 AM Jim Jones <jim.jones@uni-muenster.de> wrote:
    
    >
    >
    > On 28.11.24 20:20, Kirill Gavrilov wrote:
    > >   Here is version 3 of this patch. I found another place where this
    > > setting can be applied.
    > >   Also added some documentation and specified that this setting
    > > truncates queries by size in bytes.
    >
    > Thanks. It is now possible to change the parameter using SET
    >
    > postgres=# SET max_log_size TO 15;
    > SET
    > postgres=# SHOW max_log_size ;
    >  max_log_size
    > --------------
    >  15
    > (1 row)
    >
    
    > In the postgresql.conf the default value is set to 0
    >
    > #max_log_size = 0
    >
    > But if we take a look at the parameter it shows something else
    >
    > postgres=# SHOW max_log_size ;
    >  max_log_size
    > --------------
    >  5242880
    > (1 row)
    >
    > Perhaps it would be best to keep the default value in the
    > postgresql.conf consistent with the documentation and the actual
    > max_log_size value. IMHO 0 (or -1) should disable it.
    >
    > There are also several compilation issues:
    >
    > postgres.c: In function ‘exec_simple_query’:
    > postgres.c:1040:9: warning: ISO C90 forbids mixed declarations and code
    > [-Wdeclaration-after-statement]
    >  1040 |         bool copied = false;
    >       |         ^~~~
    > elog.c: In function ‘EmitErrorReport’:
    > elog.c:1697:9: warning: ISO C90 forbids mixed declarations and code
    > [-Wdeclaration-after-statement]
    >  1697 |         const char* old_query_string = debug_query_string;
    >       |         ^~~~~
    > elog.c:1744:23: warning: passing argument 1 of ‘pfree’ discards ‘const’
    > qualifier from pointer target type [-Wdiscarded-qualifiers]
    >  1744 |                 pfree(debug_query_string);
    >       |                       ^~~~~~~~~~~~~~~~~~
    > In file included from ../../../../src/include/postgres.h:47,
    >                  from elog.c:55:
    > ../../../../src/include/utils/palloc.h:86:25: note: expected ‘void *’
    > but argument is of type ‘const char *’
    >    86 | extern void pfree(void *pointer);
    >       |                   ~~~~~~^~~~~~~
    > elog.c: In function ‘build_query_log’:
    > elog.c:3798:9: warning: ISO C90 forbids mixed declarations and code
    > [-Wdeclaration-after-statement]
    >  3798 |         size_t query_len = strlen(query);
    >       |         ^~~~~~
    > elog.c:3801:24: warning: return discards ‘const’ qualifier from pointer
    > target type [-Wdiscarded-qualifiers]
    >  3801 |                 return query;
    >       |                        ^~~~~
    > elog.c:3805:9: warning: ISO C90 forbids mixed declarations and code
    > [-Wdeclaration-after-statement]
    >  3805 |         size_t query_log_len = pg_mbcliplen(query, query_len,
    > max_log_size);
    >       |         ^~~~~~
    >
    > and there is a trailing whitespace at:
    >
    > + *    If query needs to be truncated, copied will be set to true
    >
    >
    > /home/jim/patches/max_log_query/V3-0001-parameter-max_log_size-to-truncate-logs.patch:141:
    > trailing whitespace.
    >  *      If query needs to be truncated, copied will be set to true
    > Checking patch doc/src/sgml/config.sgml...
    > Hunk #1 succeeded at 7865 (offset -48 lines).
    > Checking patch src/backend/tcop/postgres.c...
    > Hunk #1 succeeded at 71 (offset 1 line).
    > Hunk #2 succeeded at 1031 (offset 1 line).
    > Hunk #3 succeeded at 1083 (offset 1 line).
    > Hunk #4 succeeded at 1382 (offset 1 line).
    > Hunk #5 succeeded at 1393 (offset 1 line).
    > Checking patch src/backend/utils/error/elog.c...
    > Hunk #4 succeeded at 3781 (offset -3 lines).
    > Checking patch src/backend/utils/misc/guc_tables.c...
    > Hunk #1 succeeded at 3714 (offset -10 lines).
    > Checking patch src/backend/utils/misc/postgresql.conf.sample...
    > Hunk #1 succeeded at 615 (offset -2 lines).
    > Checking patch src/bin/pg_ctl/t/004_logrotate.pl...
    > Checking patch src/include/utils/elog.h...
    > Applied patch doc/src/sgml/config.sgml cleanly.
    > Applied patch src/backend/tcop/postgres.c cleanly.
    > Applied patch src/backend/utils/error/elog.c cleanly.
    > Applied patch src/backend/utils/misc/guc_tables.c cleanly.
    > Applied patch src/backend/utils/misc/postgresql.conf.sample cleanly.
    > Applied patch src/bin/pg_ctl/t/004_logrotate.pl cleanly.
    > Applied patch src/include/utils/elog.h cleanly.
    > warning: 1 line adds whitespace errors.
    >
    > --
    > Jim
    >
    >
      Thanks for spotting mistakes.
      Setting max_log_size to 0 already disables truncation.
      I changed guc units to bytes, just to make it more human-friendly. Did
    some refactoring and fixed all warnings. Set default value in
    postgresql.conf.
    
  13. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2024-11-29T19:12:44Z

    
    On 29.11.24 12:05, Kirill Gavrilov wrote:
    >   Setting max_log_size to 0 already disables truncation.
    >   I changed guc units to bytes, just to make it more human-friendly.
    > Did some refactoring and fixed all warnings. Set default value in
    > postgresql.conf.
    
    Nice. The patch applies cleanly and the warnings are gone.
    
    A few other things:
    
    IMHO the documentation can be a bit clearer. It says to input the values
    in bytes, but the default value is in megabytes.
    
    +        If greater than zero, each query logged is truncated to this
    many bytes.
    +        Zero disables the setting.
    +        Default value is 5MB.
    
    Perhaps something like "If this value is specified without units, it is
    taken as bytes." (see wal_keep_size)
    
    And a pedantic note: This hint suggests that you can use TB as unit ..
    
    postgres=# set max_log_size = '1foo';
    ERROR:  invalid value for parameter "max_log_size": "1foo"
    HINT:  Valid units for this parameter are "B", "kB", "MB", "GB", and "TB".
    
    .. but it can never be used, as it exceeds the integer range:
    
    postgres=# SET max_log_size = '1TB';
    ERROR:  invalid value for parameter "max_log_size": "1TB"
    HINT:  Value exceeds integer range.
    
    Thanks
    
    -- 
    Jim
    
    
    
    
    
  14. Re: Truncate logs by max_log_size

    Kirill Gavrilov <diphantxm@gmail.com> — 2024-11-29T20:57:38Z

    On Fri, Nov 29, 2024 at 10:12 PM Jim Jones <jim.jones@uni-muenster.de>
    wrote:
    
    >
    >
    > On 29.11.24 12:05, Kirill Gavrilov wrote:
    > >   Setting max_log_size to 0 already disables truncation.
    > >   I changed guc units to bytes, just to make it more human-friendly.
    > > Did some refactoring and fixed all warnings. Set default value in
    > > postgresql.conf.
    >
    > Nice. The patch applies cleanly and the warnings are gone.
    >
    > A few other things:
    >
    > IMHO the documentation can be a bit clearer. It says to input the values
    > in bytes, but the default value is in megabytes.
    >
    > +        If greater than zero, each query logged is truncated to this
    > many bytes.
    > +        Zero disables the setting.
    > +        Default value is 5MB.
    >
    > Perhaps something like "If this value is specified without units, it is
    > taken as bytes." (see wal_keep_size)
    >
    
    Added to documentation. I hope it's clear now.
    
    
    >
    > And a pedantic note: This hint suggests that you can use TB as unit ..
    >
    > postgres=# set max_log_size = '1foo';
    > ERROR:  invalid value for parameter "max_log_size": "1foo"
    > HINT:  Valid units for this parameter are "B", "kB", "MB", "GB", and "TB".
    >
    > .. but it can never be used, as it exceeds the integer range:
    >
    > postgres=# SET max_log_size = '1TB';
    > ERROR:  invalid value for parameter "max_log_size": "1TB"
    > HINT:  Value exceeds integer range.
    >
    > Thanks
    >
    > --
    > Jim
    >
    
    Same thing applies to log_parameter_max_length, for example.
    
    postgres=# set log_parameter_max_length = '1foo';
    ERROR:  invalid value for parameter "log_parameter_max_length": "1foo"
    HINT:  Valid units for this parameter are "B", "kB", "MB", "GB", and "TB".
    postgres=# set log_parameter_max_length = '1TB';
    ERROR:  invalid value for parameter "log_parameter_max_length": "1TB"
    HINT:  Value exceeds integer range.
    
    I think we can leave it as is.
    
  15. Re: Truncate logs by max_log_size

    Kirill Reshke <reshkekirill@gmail.com> — 2024-11-30T06:58:38Z

    On Sat, 30 Nov 2024 at 01:57, Kirill Gavrilov <diphantxm@gmail.com> wrote:
    >
    > On Fri, Nov 29, 2024 at 10:12 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    >>
    >>
    >>
    >> On 29.11.24 12:05, Kirill Gavrilov wrote:
    >> >   Setting max_log_size to 0 already disables truncation.
    >> >   I changed guc units to bytes, just to make it more human-friendly.
    >> > Did some refactoring and fixed all warnings. Set default value in
    >> > postgresql.conf.
    >>
    >> Nice. The patch applies cleanly and the warnings are gone.
    >>
    >> A few other things:
    >>
    >> IMHO the documentation can be a bit clearer. It says to input the values
    >> in bytes, but the default value is in megabytes.
    >>
    >> +        If greater than zero, each query logged is truncated to this
    >> many bytes.
    >> +        Zero disables the setting.
    >> +        Default value is 5MB.
    >>
    >> Perhaps something like "If this value is specified without units, it is
    >> taken as bytes." (see wal_keep_size)
    >
    >
    > Added to documentation. I hope it's clear now.
    >
    >>
    >>
    >> And a pedantic note: This hint suggests that you can use TB as unit ..
    >>
    >> postgres=# set max_log_size = '1foo';
    >> ERROR:  invalid value for parameter "max_log_size": "1foo"
    >> HINT:  Valid units for this parameter are "B", "kB", "MB", "GB", and "TB".
    >>
    >> .. but it can never be used, as it exceeds the integer range:
    >>
    >> postgres=# SET max_log_size = '1TB';
    >> ERROR:  invalid value for parameter "max_log_size": "1TB"
    >> HINT:  Value exceeds integer range.
    >>
    >> Thanks
    >>
    >> --
    >> Jim
    >
    >
    > Same thing applies to log_parameter_max_length, for example.
    >
    > postgres=# set log_parameter_max_length = '1foo';
    > ERROR:  invalid value for parameter "log_parameter_max_length": "1foo"
    > HINT:  Valid units for this parameter are "B", "kB", "MB", "GB", and "TB".
    > postgres=# set log_parameter_max_length = '1TB';
    > ERROR:  invalid value for parameter "log_parameter_max_length": "1TB"
    > HINT:  Value exceeds integer range.
    >
    > I think we can leave it as is.
    
    
    Hi
    
    > +for (my $attempts = 0; $attempts < $max_attempts; $attempts++)
    > +{
    > + eval {
    > + $current_logfiles = slurp_file($node->data_dir . '/current_logfiles');
    > + };
    > + last unless $@;
    > + usleep(100_000);
    > +}
    
    
    `usleep` in tap tests is usually a bad pattern. Do we have a chance to
    test this using `wait_for_log` or similar?
    
    
    -- 
    Best regards,
    Kirill Reshke
    
    
    
    
  16. Re: Truncate logs by max_log_size

    Kirill Gavrilov <diphantxm@gmail.com> — 2024-11-30T08:44:00Z

    >
    >
    > Hi
    >
    > > +for (my $attempts = 0; $attempts < $max_attempts; $attempts++)
    > > +{
    > > + eval {
    > > + $current_logfiles = slurp_file($node->data_dir . '/current_logfiles');
    > > + };
    > > + last unless $@;
    > > + usleep(100_000);
    > > +}
    >
    >
    > `usleep` in tap tests is usually a bad pattern. Do we have a chance to
    > test this using `wait_for_log` or similar?
    >
    
    I'm not sure we can use `wait_for_log` because it checks for only one
    logfile. But even if it's possible, I don't think it's a good idea to use
    different checks in the same file or to change tests for another feature. I
    used test case from above as an example for mine.
    
  17. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2024-12-02T10:08:55Z

    
    On 29.11.24 21:57, Kirill Gavrilov wrote:
    > Same thing applies to log_parameter_max_length, for example.
    >
    > postgres=# set log_parameter_max_length = '1foo';
    > ERROR:  invalid value for parameter "log_parameter_max_length": "1foo"
    > HINT:  Valid units for this parameter are "B", "kB", "MB", "GB", and "TB".
    > postgres=# set log_parameter_max_length = '1TB';
    > ERROR:  invalid value for parameter "log_parameter_max_length": "1TB"
    > HINT:  Value exceeds integer range. 
    >
    > I think we can leave it as is.
    
    I see. So I guess it is out of scope to change this message here.
    
    Small nitpicks:
    
    1) The indentation of the comment at postgresql.conf.sample is a little
    bit off
    
    #max_log_size = 0                 # max size of logged statement
                        # 0 disables the feature
    
    IMHO it looks better like this:
    
    #max_log_size = 0   # max size of logged statement
                        # 0 disables the feature
    
    
    2) You introduced a trailing whitespace at L34 (Not critical :))
    
    +        Zero disables the setting.
    
    It happens to me all the time, so I usually try to apply my patches in a
    clean branch just to make sure I didn't miss anything.
    
    Other than that, I have nothing more to add at this point.
    
    Thanks
    
    -- 
    Jim
    
    
    
    
    
  18. Re: Truncate logs by max_log_size

    Kirill Gavrilov <diphantxm@gmail.com> — 2025-01-31T10:46:37Z

    On Mon, Dec 2, 2024 at 1:09 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    
    >
    >
    > On 29.11.24 21:57, Kirill Gavrilov wrote:
    > > Same thing applies to log_parameter_max_length, for example.
    > >
    > > postgres=# set log_parameter_max_length = '1foo';
    > > ERROR:  invalid value for parameter "log_parameter_max_length": "1foo"
    > > HINT:  Valid units for this parameter are "B", "kB", "MB", "GB", and
    > "TB".
    > > postgres=# set log_parameter_max_length = '1TB';
    > > ERROR:  invalid value for parameter "log_parameter_max_length": "1TB"
    > > HINT:  Value exceeds integer range.
    > >
    > > I think we can leave it as is.
    >
    > I see. So I guess it is out of scope to change this message here.
    >
    > Small nitpicks:
    >
    > 1) The indentation of the comment at postgresql.conf.sample is a little
    > bit off
    >
    > #max_log_size = 0                 # max size of logged statement
    >                     # 0 disables the feature
    >
    > IMHO it looks better like this:
    >
    > #max_log_size = 0   # max size of logged statement
    >                     # 0 disables the feature
    >
    >
    > 2) You introduced a trailing whitespace at L34 (Not critical :))
    >
    > +        Zero disables the setting.
    >
    > It happens to me all the time, so I usually try to apply my patches in a
    > clean branch just to make sure I didn't miss anything.
    >
    > Other than that, I have nothing more to add at this point.
    >
    > Thanks
    >
    > --
    > Jim
    >
    >
    Sorry for the long silence.  I fixed the indentation and a trailing
    whitespace. Should look fine now.
    
  19. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2025-02-03T10:31:07Z

    Hi Kirill
    
    On 31.01.25 11:46, Kirill Gavrilov wrote:
    > Sorry for the long silence.  I fixed the indentation and a trailing
    > whitespace. Should look fine now.
    
    
    The patch applies cleanly, the documentation is clear, and all tests pass.
    
    It is possible to change this new parameter session-wise, which is nice!
    
    postgres=# SET max_log_size TO 7;
    SET
    postgres=# SHOW max_log_size;
     max_log_size
    --------------
     7B
    (1 row)
    
    
    The default value now is clear and it corresponds to the value set on
    postgresql.conf:
    
    #max_log_size = 0       # max size of logged statement 
    
    postgres=# SHOW max_log_size;
     max_log_size
    --------------
     0
    (1 row)
    
    
    Logs are truncated as expected:
    
    postgres=# SET max_log_size TO 6;
    SET
    postgres=# SELECT length('CALL xyz;');
     length
    --------
          9
    (1 row)
    
    postgres=# CALL xyz;
    ERROR:  syntax error at or near ";"
    LINE 1: CALL xyz;
    
    
    log entry:
    
    2025-02-03 10:58:19.975 CET [123945] ERROR:  syntax error at or near ";"
    at character 9
    2025-02-03 10:58:19.975 CET [123945] STATEMENT:  CALL x
    
    
    The issue with log entry sizes for queries containing special characters
    was resolved by setting the unit to bytes.
    
    Overall, everythingLGTM.
    
    The new status of this patch is: Ready for Committer
    
    Jim
    
    
    
    
    
  20. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@oss.nttdata.com> — 2025-03-31T18:20:36Z

    
    On 2025/02/03 19:31, Jim Jones wrote:
    > Hi Kirill
    > 
    > On 31.01.25 11:46, Kirill Gavrilov wrote:
    >> Sorry for the long silence.  I fixed the indentation and a trailing
    >> whitespace. Should look fine now.
    > 
    > 
    > The patch applies cleanly, the documentation is clear, and all tests pass.
    > 
    > It is possible to change this new parameter session-wise, which is nice!
    > 
    > postgres=# SET max_log_size TO 7;
    > SET
    > postgres=# SHOW max_log_size;
    >   max_log_size
    > --------------
    >   7B
    > (1 row)
    > 
    > 
    > The default value now is clear and it corresponds to the value set on
    > postgresql.conf:
    > 
    > #max_log_size = 0       # max size of logged statement
    > 
    > postgres=# SHOW max_log_size;
    >   max_log_size
    > --------------
    >   0
    > (1 row)
    > 
    > 
    > Logs are truncated as expected:
    > 
    > postgres=# SET max_log_size TO 6;
    > SET
    > postgres=# SELECT length('CALL xyz;');
    >   length
    > --------
    >        9
    > (1 row)
    > 
    > postgres=# CALL xyz;
    > ERROR:  syntax error at or near ";"
    > LINE 1: CALL xyz;
    > 
    > 
    > log entry:
    > 
    > 2025-02-03 10:58:19.975 CET [123945] ERROR:  syntax error at or near ";"
    > at character 9
    > 2025-02-03 10:58:19.975 CET [123945] STATEMENT:  CALL x
    > 
    > 
    > The issue with log entry sizes for queries containing special characters
    > was resolved by setting the unit to bytes.
    > 
    > Overall, everythingLGTM.
    > 
    > The new status of this patch is: Ready for Committer
    
    Since this patch is marked as ready-for-committer, I started reviewing it.
    Basically I like the proposed idea.
    
    
    When I set log_statement to 'all', max_log_size to 3, and ran "SELECT 1/0",
    only the first three bytes of the query were logged by log_statement.
    However, no query statement appeared under STATEMENT, as shown below.
    Is this a bug?
    
    --------------------------
    =# SET log_statement TO 'all';
    =# SET max_log_size TO 3;
    =# SELECT 1/0;
    LOG:  statement: SEL
    ERROR:  division by zero
    STATEMENT:
    --------------------------
    
    
    When log_replication_commands is enabled, replication commands are logged.
    Should max_log_size apply to these logs as well to prevent excessively
    large commands from being logged in full?
    
    
    The parameter name max_log_size seems misleading. It sounds like
    it controls the maximum log file size. Would a name like
    log_statement_max_length be clearer?
    
    
    The functions like exec_parse_message(), exec_bind_message(),
    and exec_execute_message() may log query statements (e.g., via
    log_min_duration_statement), but the patch doesn't seem to
    update them to consider max_log_size.
    
    
    Queries can also be logged in the CONTEXT line, such as when running
    "DO $$ BEGIN SELECT 1/0; END $$;", but max_log_size doesn't seem to
    apply in this case.
    
    
    There might be other cases where queries are logged, but the patch
    doesn't handle them. I'm not sure we can identify and address all of
    them before the feature freeze.
    
    Regards,
    
    -- 
    Fujii Masao
    Advanced Computing Technology Center
    Research and Development Headquarters
    NTT DATA CORPORATION
    
    
    
    
    
  21. Re: Truncate logs by max_log_size

    Álvaro Herrera <alvherre@kurilemu.de> — 2026-02-04T09:48:23Z

    On 2025-Apr-01, Fujii Masao wrote:
    
    > Since this patch is marked as ready-for-committer, I started reviewing it.
    > Basically I like the proposed idea.
    
    Hello, is this something that anybody is working on?
    https://commitfest.postgresql.org/patch/5272/
    Apparently it was very close to done but was abandoned after several
    rounds of review at the start of the cycle.
    
    -- 
    Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
    "Computing is too important to be left to men." (Karen Spärck Jones)
    
    
    
    
  22. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-02-05T02:17:45Z

    On Wed, Feb 4, 2026 at 6:48 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
    >
    > On 2025-Apr-01, Fujii Masao wrote:
    >
    > > Since this patch is marked as ready-for-committer, I started reviewing it.
    > > Basically I like the proposed idea.
    >
    > Hello, is this something that anybody is working on?
    > https://commitfest.postgresql.org/patch/5272/
    
    At least I'm not for now. So please feel free to work on the patch if
    you'd like!
    
    Regards,
    
    -- 
    Fujii Masao
    
    
    
    
  23. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-02-05T09:08:22Z

    
    On 05/02/2026 03:17, Fujii Masao wrote:
    > At least I'm not for now. So please feel free to work on the patch if
    > you'd like!
    
    If nobody is planning to work on this, I can take a look at it next week.
    
    Best, Jim
    
    
    
    
  24. Re: Truncate logs by max_log_size

    Álvaro Herrera <alvherre@kurilemu.de> — 2026-02-05T10:22:19Z

    On 2026-Feb-05, Jim Jones wrote:
    
    > On 05/02/2026 03:17, Fujii Masao wrote:
    > > At least I'm not for now. So please feel free to work on the patch if
    > > you'd like!
    > 
    > If nobody is planning to work on this, I can take a look at it next week.
    
    That'd be swell.
    
    My only comment at this point is that the proposed GUC name is not
    great.  I think it should be something like log_statement_max_length, or
    something like that.  Reading just the thread subject, people would
    imagine this is about the size of the log file.
    
    Another point is that the current patch does strlen() twice on each
    query.  It might be better to do away with need_truncate_query_log() and
    have a single routine that both determines whether the truncation is
    needed and returns the truncated query if it is.  If it returns NULL
    then caller assumes it's not needed.
    
    -- 
    Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
    
    
    
    
  25. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-02-05T11:53:22Z

    
    On 05/02/2026 11:22, Álvaro Herrera wrote:
    > My only comment at this point is that the proposed GUC name is not
    > great.  I think it should be something like log_statement_max_length, or
    > something like that.  Reading just the thread subject, people would
    > imagine this is about the size of the log file.
    
    +1 for log_statement_max_length
    
    > 
    > Another point is that the current patch does strlen() twice on each
    > query.  It might be better to do away with need_truncate_query_log() and
    > have a single routine that both determines whether the truncation is
    > needed and returns the truncated query if it is.  If it returns NULL
    > then caller assumes it's not needed.
    
    I'll take a look at this.
    
    Another thing that we could adjust is the default/disable value: I
    personally find 0 to disable the feature a bit confusing. 0 might be
    interpreted as "log 0 bytes", and the user ends up with the full
    statement logged. What about -1?
    
    Best, Jim
    
    
    
    
  26. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-02-06T07:50:03Z

    
    On 05/02/2026 11:22, Álvaro Herrera wrote:
    > My only comment at this point is that the proposed GUC name is not
    > great.  I think it should be something like log_statement_max_length, or
    > something like that.  Reading just the thread subject, people would
    > imagine this is about the size of the log file.
    
    Done. GUC changed to log_statement_max_length.
    
    > Another point is that the current patch does strlen() twice on each
    > query.  It might be better to do away with need_truncate_query_log() and
    > have a single routine that both determines whether the truncation is
    > needed and returns the truncated query if it is.  If it returns NULL
    > then caller assumes it's not needed.
    
    Done. Now truncate_query_log() returns a palloc'd truncated copy of the
    statement if truncation is needed, and NULL otherwise.
    
    == issue with issue with empty STATEMENT ==
    
    This issue was mentioned by Fujii upthread. It is now fixed:
    
    postgres=# SET log_statement TO 'all';
    SET
    postgres=# SET log_statement_max_length TO 3;
    SET
    postgres=# SELECT 1/0;
    ERROR:  division by zero
    
    Log entries:
    
    2026-02-05 17:54:47.521 CET [570568] LOG:  statement: SEL
    2026-02-05 17:54:47.521 CET [570568] ERROR:  division by zero
    2026-02-05 17:54:47.521 CET [570568] STATEMENT:  SELECT 1/0;
    
    == default value ==
    
    To be consistent with other parameters, such as
    log_parameter_max_length, the default (disabled) value is now -1.
    
    == tests ==
    
    Added new tests for -1 and multi-byte characters.
    
    
    Best, Jim
  27. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-03-20T11:08:59Z

    rebase
    
    Jim
  28. Re: Truncate logs by max_log_size

    Kirill Reshke <reshkekirill@gmail.com> — 2026-03-20T17:33:21Z

    On Fri, 20 Mar 2026 at 16:09, Jim Jones <jim.jones@uni-muenster.de> wrote:
    >
    > rebase
    >
    > Jim
    
    
    Hi!
    We discussed this patch off-list with Andrey @x4mmm in sight of
    CVE-2026-2006. Looks like this patch is not vulnerable, and its use of
    pg_mbcliplen are correct.
    But I anyway raise this question in lists just for record.
    
    
    -- 
    Best regards,
    Kirill Reshke
    
    
    
    
  29. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-04-03T21:59:48Z

    Hi Kirill
    
    On 20/03/2026 18:33, Kirill Reshke wrote:
    > We discussed this patch off-list with Andrey @x4mmm in sight of
    > CVE-2026-2006. Looks like this patch is not vulnerable, and its use of
    > pg_mbcliplen are correct.
    
    Thanks for checking!
    
    I spent some time revisiting this patch today and realised that it only
    applied truncation in exec_simple_query. I believe the original intent
    of this feature was to cover other paths as well, so I added the same
    logic in exec_execute_message (which handles log_statement logging for
    the extended query protocol), and in exec_parse_message and
    exec_bind_message (which log statement text when
    log_min_duration_statement fires).
    
    v9 attached.
    
    Thoughts on this approach?
    
    Best, Jim
    
    
    
  30. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-04-08T16:18:45Z

    On Sat, Apr 4, 2026 at 6:59 AM Jim Jones <jim.jones@uni-muenster.de> wrote:
    > v9 attached.
    
    Thanks for updating the patch!
    
    I tried to review this in time for the feature freeze, but unfortunately
    didn't make it. Still, I'd like to share some comments for future work.
    
    
    +        If greater than zero, each statement written to the server log
    +        is truncated to at most this many bytes.
    
    It would be good to clarify which query logging this parameter affects.
    As I understand it, it applies only to statements logged by log_statement and
    log_min_duration_statement, and not to statements included in other messages
    (e.g., errors). Is that correct?
    
    
    + truncated_query = truncate_query_log(query_string);
    + query_log = truncated_query ? truncated_query : query_string;
    
    In the patch, truncate_query_log() is called unconditionally in
    exec_simple_query(), even when the query isn't logged. This adds unnecessary
    overhead. It would be better to call it only when logging is actually performed
    (e.g., under check_log_statement() or check_log_duration()). For example,
    
    -------------------------------------------
             /* Log immediately if dictated by log_statement */
             if (check_log_statement(parsetree_list))
             {
    +                char    *truncated_stmt = NULL;
    +
    +                if (log_statement_max_length >= 0)
    +                        truncated_stmt = truncate_query_log(query_string);
    +
                     ereport(LOG,
    -                                (errmsg("statement: %s", query_string),
    +                                (errmsg("statement: %s",
    (truncated_stmt != NULL) ? truncated_stmt : query_string),
                                      errhidestmt(true),
                                      errdetail_execute(parsetree_list)));
                     was_logged = true;
    +
    +                if (truncated_stmt != NULL)
    +                        pfree(truncated_stmt);
             }
    
    <snip>
    
                     case 2:
    -                        ereport(LOG,
    -                                        (errmsg("duration: %s ms
    statement: %s",
    -                                                        msec_str,
    query_string),
    -                                         errhidestmt(true),
    -                                         errdetail_execute(parsetree_list)));
    -                        break;
    +                        {
    +                                char    *truncated_stmt = NULL;
    +
    +                                if (log_statement_max_length >= 0)
    +                                        truncated_stmt =
    truncate_query_log(query_string);
    +
    +                                ereport(LOG,
    +                                                (errmsg("duration: %s
    ms  statement: %s",
    +
    msec_str, (truncated_stmt != NULL) ? truncated_stmt : query_string),
    +                                                 errhidestmt(true),
    +
    errdetail_execute(parsetree_list)));
    +
    +                                if (truncated_stmt != NULL)
    +                                        pfree(truncated_stmt);
    +                                break;
    +                        }
             }
    -------------------------------------------
    
    
    + char    *truncated_query = NULL;
    + const char *query_log;
    
    In exec_parse_message(), exec_bind_message(), and exec_execute_message(),
    variables like truncated_query can be declared closer to where they are used
    (e.g., inside the check_log_duration() switch case) to improve readability.
    For example,
    
    -------------------------------------------
                            break;
                     case 2:
    -                        ereport(LOG,
    -                                        (errmsg("duration: %s ms
    parse %s: %s",
    -                                                        msec_str,
    -                                                        *stmt_name ?
    stmt_name : "<unnamed>",
    -                                                        query_string),
    -                                         errhidestmt(true)));
    -                        break;
    +                        {
    +                                char    *truncated_stmt = NULL;
    +
    +                                if (log_statement_max_length >= 0)
    +                                        truncated_stmt =
    truncate_query_log(query_string);
    +
    +                                ereport(LOG,
    +                                                (errmsg("duration: %s
    ms  parse %s: %s",
    +                                                                msec_str,
    +
    *stmt_name ? stmt_name : "<unnamed>",
    +
    (truncated_stmt != NULL) ? truncated_stmt : query_string),
    +                                                 errhidestmt(true)));
    +
    +                                if (truncated_stmt != NULL)
    +                                        pfree(truncated_stmt);
    +                                break;
    +                        }
             }
    -------------------------------------------
    
    
    +  long_desc => '-1 means no truncation.',
    
    +#log_statement_max_length = -1          # max length of logged statements
    +                                        # -1 disables truncation
    
    I like the description like "-1 means log statement in full", which seems
    clearer and easier to understand for users. Thought?
    
    
    Regarding the regression test, testing log_statement_max_length in pg_ctl test
    looks a bit odd to me. It might be better to place it under
    src/test/modules/test_misc, for example?
    
    Regards,
    
    -- 
    Fujii Masao
    
    
    
    
  31. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-04-08T20:52:27Z

    Hi Fujii
    
    On 08/04/2026 18:18, Fujii Masao wrote:
    > +        If greater than zero, each statement written to the server log
    > +        is truncated to at most this many bytes.
    > 
    > It would be good to clarify which query logging this parameter affects.
    > As I understand it, it applies only to statements logged by log_statement and
    > log_min_duration_statement, and not to statements included in other messages
    > (e.g., errors). Is that correct?
    
    Agreed. Changed text to:
    
    If greater than zero, each statement logged by <xref
    linkend="guc-log-statement"/> or <xref
    linkend="guc-log-min-duration-statement"/> is truncated to at most this
    many bytes. A value of zero causes statements to be logged with an empty
    body. <literal>-1</literal> (the default) logs statements in full. If
    this value is specified without units, it is taken as bytes. Only
    superusers and users with the appropriate <literal>SET</literal>
    privilege can change this setting.
    
    > + truncated_query = truncate_query_log(query_string);
    > + query_log = truncated_query ? truncated_query : query_string;
    > 
    > In the patch, truncate_query_log() is called unconditionally in
    > exec_simple_query(), even when the query isn't logged. This adds unnecessary
    > overhead. It would be better to call it only when logging is actually performed
    > (e.g., under check_log_statement() or check_log_duration()).
    
    > + char    *truncated_query = NULL;
    > + const char *query_log;
    > 
    > In exec_parse_message(), exec_bind_message(), and exec_execute_message(),
    > variables like truncated_query can be declared closer to where they are used
    > (e.g., inside the check_log_duration() switch case) to improve readability.
    
    
    Done.
    
    Removed the top-level declarations and unconditional
    truncate_query_log() call from all four functions. Truncation is now
    performed lazily, with local variables declared inside
    check_log_statement and case 2 of check_log_duration.
    
    
    > +  long_desc => '-1 means no truncation.',
    > 
    > +#log_statement_max_length = -1          # max length of logged statements
    > +                                        # -1 disables truncation
    > 
    > I like the description like "-1 means log statement in full", which seems
    > clearer and easier to understand for users. Thought?
    
    Done.
    
    Changed long_desc and comment in postgresql.conf.sqmple from "-1 means
    no truncation" to "-1 means log statement in full"
    
    > Regarding the regression test, testing log_statement_max_length in pg_ctl test
    > looks a bit odd to me. It might be better to place it under
    > src/test/modules/test_misc, for example?
    
    Done.
    
    Moved tests to:
     src/test/modules/test_misc/t/012_log_statement_max_length.pl
    
    Something I just noticed: the command that enables truncation is the
    first victim of its own effect.
    
    $ psql postgres
    psql (19devel)
    Type "help" for help.
    
    postgres=# SET log_min_duration_statement = 0;
    SET log_statement_max_length = 20;
    SET
    SET
    postgres=#
    \q
    $ tail /usr/local/postgres-dev/logfile
    
    2026-04-08 22:17:41.958 CEST [206029] LOG:  duration: 0.450 ms
    statement: SET log_min_duration_statement = 0;
    2026-04-08 22:17:41.958 CEST [206029] LOG:  duration: 0.085 ms
    statement: SET log_statement_ma
    
    I guess it is technically correct.. just a bit funny :)
    
    Thanks for the thorough review!
    
    Best, Jim
    
  32. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-04-09T18:11:38Z

    On Thu, Apr 9, 2026 at 5:52 AM Jim Jones <jim.jones@uni-muenster.de> wrote:
    > Moved tests to:
    >  src/test/modules/test_misc/t/012_log_statement_max_length.pl
    
    Thanks for updating the patch! It looks good to me except the
    following comments.
    
    
    +$node->append_conf('postgresql.conf', "log_statement = 'all'\n");
    
    This doesn't seem necessary, since $node->init already sets
    log_statement = 'all'.
    
    
    +$node->append_conf('postgresql.conf', "log_statement_max_length = 20\n");
    +$node->reload();
    +my $log_offset = -s $node->logfile;
    +$node->psql('postgres', "SELECT '123456789ABCDEF'");
    
    Would it be simpler (and cheaper) to use SET instead of reloading the
    config? For example:
    
    ---------------------------
    my $log_offset = -s $node->logfile;
    $node->psql(
            'postgres', "
    SET log_statement_max_length TO 20;
    SELECT '123456789ABCDEF';
    ");
    ---------------------------
    
    
    +char *
    +truncate_query_log(const char *query)
    
    In elog.c, truncate_query_log() is currently placed between write_stderr() and
    vwrite_stderr(). Since those two functions are related, it might be better to
    move truncate_query_log() to a more appropriate location. Thoughts?
    
    
    I see the patch has been moved to CommitFest PG20-1. Once development for v20
    starts, I'd like to commit it.
    
    Regards,
    
    -- 
    Fujii Masao
    
    
    
    
  33. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-04-09T22:35:59Z

    
    On 09/04/2026 20:11, Fujii Masao wrote:
    > +$node->append_conf('postgresql.conf', "log_statement = 'all'\n");
    > 
    > This doesn't seem necessary, since $node->init already sets
    > log_statement = 'all'.
    
    
    Removed.
    Most likely still leftovers from previous attempts.
    
    > +$node->append_conf('postgresql.conf', "log_statement_max_length = 20\n");
    > +$node->reload();
    > +my $log_offset = -s $node->logfile;
    > +$node->psql('postgres', "SELECT '123456789ABCDEF'");
    > 
    > Would it be simpler (and cheaper) to use SET instead of reloading the
    > config? For example:
    > 
    > ---------------------------
    > my $log_offset = -s $node->logfile;
    > $node->psql(
    >         'postgres', "
    > SET log_statement_max_length TO 20;
    > SELECT '123456789ABCDEF';
    > ");
    > ---------------------------
    
    
    Done.
    It's indeed much simpler this way. I replaced all append + reload
    postgresql.conf calls with SET.
    
    
    > +char *
    > +truncate_query_log(const char *query)
    > 
    > In elog.c, truncate_query_log() is currently placed between write_stderr() and
    > vwrite_stderr(). Since those two functions are related, it might be better to
    > move truncate_query_log() to a more appropriate location. Thoughts?
    
    
    Agreed.
    The function now lives between check_log_of_query() and
    get_backend_type_for_log(), which have more semantic overlap :)
    
    
    > I see the patch has been moved to CommitFest PG20-1. Once development for v20
    > starts, I'd like to commit it.
    
    
    Terrific. Thanks!
    
    Best, Jim
    
  34. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-04-10T02:01:12Z

    On Fri, Apr 10, 2026 at 7:36 AM Jim Jones <jim.jones@uni-muenster.de> wrote:
    > > I see the patch has been moved to CommitFest PG20-1. Once development for v20
    > > starts, I'd like to commit it.
    >
    >
    > Terrific. Thanks!
    
    Thanks for updating the patch! LGTM. Let's wait for next CF for v20 to begin.
    
    Regards,
    
    -- 
    Fujii Masao
    
    
    
    
  35. Re: Truncate logs by max_log_size

    Maxym Kharchenko <maxymkharchenko@gmail.com> — 2026-04-17T17:03:49Z

    Hello Fujii-san,
    
    There seems to be an inconsistency in the current patch. When a statement
    has errors (for example, when it hits a table that does not exist), the
    full statement is still being logged.
    
    Similar parameter: `log_parameter_max_length` has a companion
    `log_parameter_max_length_on_error` to handle this case (commit:
    0b34e7d307e6,
    https://github.com/postgres/postgres/commit/0b34e7d307e6a142ee94800e6d5f3e73449eeffd
    ).
    
    Should the same treatment be added for `log_statement_max_length`?
    
    Have a nice day,
    Maxym Kharchenko
    
    On Fri, Apr 17, 2026 at 6:32 AM Fujii Masao <masao.fujii@gmail.com> wrote:
    
    > On Fri, Apr 10, 2026 at 7:36 AM Jim Jones <jim.jones@uni-muenster.de>
    > wrote:
    > > > I see the patch has been moved to CommitFest PG20-1. Once development
    > for v20
    > > > starts, I'd like to commit it.
    > >
    > >
    > > Terrific. Thanks!
    >
    > Thanks for updating the patch! LGTM. Let's wait for next CF for v20 to
    > begin.
    >
    > Regards,
    >
    > --
    > Fujii Masao
    >
    >
    >
    >
    >
    
  36. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-04-20T08:04:17Z

    On Sat, Apr 18, 2026 at 2:04 AM Maxym Kharchenko
    <maxymkharchenko@gmail.com> wrote:
    >
    > Hello Fujii-san,
    >
    > There seems to be an inconsistency in the current patch. When a statement has errors (for example, when it hits a table that does not exist), the full statement is still being logged.
    >
    > Similar parameter: `log_parameter_max_length` has a companion `log_parameter_max_length_on_error` to handle this case (commit: 0b34e7d307e6, https://github.com/postgres/postgres/commit/0b34e7d307e6a142ee94800e6d5f3e73449eeffd).
    >
    > Should the same treatment be added for `log_statement_max_length`?
    
    I think extending log_statement_max_length, or adding something like
    log_statement_max_length_on_error, would be a good idea to cover statements
    logged on error. However, I think the current patch is good as it stands,
    so I'd recommend pursuing that as a separate patch after the current one
    is committed.
    
    Regards,
    
    -- 
    Fujii Masao
    
    
    
    
  37. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-04-20T17:33:27Z

    Hi Maxym, Hi Fujii
    
    On 20/04/2026 10:04, Fujii Masao wrote:
    > On Sat, Apr 18, 2026 at 2:04 AM Maxym Kharchenko
    > <maxymkharchenko@gmail.com> wrote:
    >> Hello Fujii-san,
    >>
    >> There seems to be an inconsistency in the current patch. When a statement has errors (for example, when it hits a table that does not exist), the full statement is still being logged.
    >>
    >> Similar parameter: `log_parameter_max_length` has a companion `log_parameter_max_length_on_error` to handle this case (commit: 0b34e7d307e6, https://github.com/postgres/postgres/
    >> commit/0b34e7d307e6a142ee94800e6d5f3e73449eeffd).
    
    Thanks for the input!
    
    It's an interesting idea. However, I am not entirely convinced it
    applies to this patch. IIUC log_parameter_max_length_on_error can be
    used if you want to see the parameter values (for debugging), which
    might contain sensitive information. So it is more like a
    security/privacy control?
    
    psql (19devel)
    Type "help" for help.
    
    postgres=# SELECT 1/$1
    \bind 000
    \g
    ERROR:  division by zero
    
    postgres=# SET log_parameter_max_length_on_error = -1;
    SELECT 1/$1
    \bind 000
    \g
    SET
    ERROR:  division by zero
    CONTEXT:  unnamed portal with parameters: $1 = '000'
    
    postgres=# SET log_parameter_max_length_on_error = 2;
    SELECT 1/$1
    \bind 000
    \g
    SET
    ERROR:  division by zero
    CONTEXT:  unnamed portal with parameters: $1 = '00...'
    
    Please correct me if I am wrong, but a statement is not sensitive in the
    way parameter values can be. The reason to truncate statements is purely
    log size management.
    
    
    > I think extending log_statement_max_length, or adding something like
    > log_statement_max_length_on_error, would be a good idea to cover statements
    > logged on error. However, I think the current patch is good as it stands,
    > so I'd recommend pursuing that as a separate patch after the current one
    > is committed.
    
    +1
    
    
    Best, Jim
    
    
    
    
  38. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-04-30T21:33:18Z

    rebase
    
    Jim
  39. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-05-15T10:48:52Z

    rebase due to recent changes in src/test/modules/test_misc/meson.build
    
    Jim
    
  40. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-07-02T15:49:24Z

    On Fri, May 15, 2026 at 7:48 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    >
    > rebase due to recent changes in src/test/modules/test_misc/meson.build
    
    I reviewed the patch again and made a few additional changes. The updated
    patch is attached. Barring any objections, I'm thinking to commit it.
    
             If greater than zero, each statement logged by
    -        <xref linkend="guc-log-statement"/> or
    -        <xref linkend="guc-log-min-duration-statement"/> is truncated to
    -        at most this many bytes.
    +        <xref linkend="guc-log-statement"/>,
    +        <xref linkend="guc-log-min-duration-statement"/>,
    +        <xref linkend="guc-log-min-duration-sample"/>, or
    +        <xref linkend="guc-log-transaction-sample-rate"/>
    +        is truncated to at most this many bytes.
    
    Since this parameter also affects statements logged by
    log_min_duration_sample and log_transaction_sample_rate, I added
    those parameters to the description.
    
    
    +        This setting does not affect statements logged because of
    +        <xref linkend="guc-log-min-error-statement"/>.
    
    I also clarified that this parameter does not affect statements logged
    by log_min_error_statement.
    
    
    +static char *
    +truncate_query_log(const char *query)
    
    Since truncate_query_log() is only used in postgres.c, I moved it
    from elog.c and made it a static function.
    
    
    -ok( $node->log_contains(
    - qr/statement: SELECT '123456789ABC(?!D)/, $log_offset),
    +ok($node->log_contains(qr/statement: SELECT '123456789ABC$/m, $log_offset),
    
    I tightened the test to verify that the truncated statement ends exactly
    at the 20th byte.
    
    
    -# character (the 🐘 emoji is 4 bytes; with limit=12 it must be kept whole
    -# and the following 't' must not appear).
    -note "Multibyte truncation respects character boundaries";
    +# character when the byte limit falls in the middle of it.
    +SKIP:
    
    Using an emoji directly in the test seems fragile and the behavior
    may depend on the test platform. To make the test more robust, I changed
    it to construct the multibyte character with pack() and run the test
    only when the server encoding is UTF-8.
    
    Regards,
    
    -- 
    Fujii Masao
    
  41. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-07-02T18:47:48Z

    Hi Fujii
    
    On 02/07/2026 17:49, Fujii Masao wrote:
    > I reviewed the patch again and made a few additional changes. The updated
    > patch is attached. Barring any objections, I'm thinking to commit it.
    
    
    The changes seem reasonable to me.
    Thanks for taking care of it!
    
    Best, Jim
    
    
    
    
  42. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-07-03T00:56:04Z

    On Fri, Jul 3, 2026 at 3:47 AM Jim Jones <jim.jones@uni-muenster.de> wrote:
    >
    > Hi Fujii
    >
    > On 02/07/2026 17:49, Fujii Masao wrote:
    > > I reviewed the patch again and made a few additional changes. The updated
    > > patch is attached. Barring any objections, I'm thinking to commit it.
    >
    >
    > The changes seem reasonable to me.
    > Thanks for taking care of it!
    
    Thanks for the review! I've pushed the patch.
    
    While working on it, I found a few possible follow-up improvements.
    
    (1)
    When log_statement is enabled, executing a prepared statement logs the
    prepared query in a DETAIL message. For example:
    
        =# SET log_statement_max_length TO 10;
        =# PREPARE test AS SELECT * FROM pgbench_accounts WHERE aid = $1;
        LOG:  statement: PREPARE te
        =# EXECUTE test(1);
        LOG:  statement: EXECUTE te
        DETAIL:  prepare: PREPARE test AS SELECT * FROM pgbench_accounts
    WHERE aid = $1;
    
    Should log_statement_max_length also apply to such query string in the
    DETAIL message?
    
    (2)
    When a bind parameter is truncated by
    log_parameter_max_length, an ellipsis (...) is appended:
    
        =# SET log_parameter_max_length TO 5;
        =# SELECT $1::text \bind 'abcdefghijk' \g
        LOG:  execute <unnamed>: SELECT $1::text
        DETAIL:  Parameters: $1 = 'abcde...'
    
    Would it make sense for log_statement_max_length to append an
    ellipsis as well, so that users can easily tell when a statement has
    been truncated?
    
    (3)
    + query_len = strlen(query);
    
    truncate_query_log() uses strlen() only to determine whether the
    query exceeds log_statement_max_length. Since the query can be very
    large, would it be better to use
    
        strnlen(query, log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN)
    
    instead, to avoid scanning the entire string?
    
    Regards,
    
    -- 
    Fujii Masao
    
    
    
    
  43. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-07-03T04:24:21Z

    On Fri, Jul 3, 2026 at 9:56 AM Fujii Masao <masao.fujii@gmail.com> wrote:
    > Thanks for the review! I've pushed the patch.
    
    The buildfarm member prion reported the failure [1].
    
    It looks like the failure occurs because prion runs with
    log_error_verbosity = verbose, which inserts the SQLSTATE between
    "LOG:" and the message text. The log_statement_max_length = 0 test
    expected "statement:" to appear immediately after "LOG:", so it failed
    even though the server correctly logged an empty statement body.
    
    The attached patch fixes the test.
    
    Regards,
    
    [1] https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=prion&dt=2026-07-03%2002%3A23%3A06
    
    -- 
    Fujii Masao
    
  44. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-07-03T07:34:22Z

    On 03/07/2026 02:56, Fujii Masao wrote:
    > Thanks for the review! I've pushed the patch.
    
    Awesome. Thanks!
    
    > While working on it, I found a few possible follow-up improvements.
    > 
    > (1)
    > When log_statement is enabled, executing a prepared statement logs the
    > prepared query in a DETAIL message. For example:
    > 
    >     =# SET log_statement_max_length TO 10;
    >     =# PREPARE test AS SELECT * FROM pgbench_accounts WHERE aid = $1;
    >     LOG:  statement: PREPARE te
    >     =# EXECUTE test(1);
    >     LOG:  statement: EXECUTE te
    >     DETAIL:  prepare: PREPARE test AS SELECT * FROM pgbench_accounts
    > WHERE aid = $1;
    > 
    > Should log_statement_max_length also apply to such query string in the
    > DETAIL message?
    > 
    > (2)
    > When a bind parameter is truncated by
    > log_parameter_max_length, an ellipsis (...) is appended:
    > 
    >     =# SET log_parameter_max_length TO 5;
    >     =# SELECT $1::text \bind 'abcdefghijk' \g
    >     LOG:  execute <unnamed>: SELECT $1::text
    >     DETAIL:  Parameters: $1 = 'abcde...'
    > 
    > Would it make sense for log_statement_max_length to append an
    > ellipsis as well, so that users can easily tell when a statement has
    > been truncated?
    
    +1
    Nice additions -- the feature gap is obvious, IMHO.
    
    Are you planning to work on it? I'm drowning in work right now and can
    only jump on it next week.
    
    > (3)
    > + query_len = strlen(query);
    > 
    > truncate_query_log() uses strlen() only to determine whether the
    > query exceeds log_statement_max_length. Since the query can be very
    > large, would it be better to use
    > 
    >     strnlen(query, log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN)
    > 
    > instead, to avoid scanning the entire string?
    
    I'm not so sure about this one. At this point, isn't "query" already \0
    terminated? I'm also wondering if it could affect pg_mbcliplen() down
    the road, since strnlen() can return a different value
    (log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN) on large queries --
    not tested yet.
    
    Thanks!
    
    Best, Jim
    
    
    
    
  45. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-07-03T15:06:44Z

    On Fri, Jul 3, 2026 at 1:24 PM Fujii Masao <masao.fujii@gmail.com> wrote:
    >
    > On Fri, Jul 3, 2026 at 9:56 AM Fujii Masao <masao.fujii@gmail.com> wrote:
    > > Thanks for the review! I've pushed the patch.
    >
    > The buildfarm member prion reported the failure [1].
    >
    > It looks like the failure occurs because prion runs with
    > log_error_verbosity = verbose, which inserts the SQLSTATE between
    > "LOG:" and the message text. The log_statement_max_length = 0 test
    > expected "statement:" to appear immediately after "LOG:", so it failed
    > even though the server correctly logged an empty statement body.
    >
    > The attached patch fixes the test.
    
    I've pushed the patch, and confirmed that prion is green again.
    
    Regards,
    
    -- 
    Fujii Masao
    
    
    
    
  46. Re: Truncate logs by max_log_size

    Fujii Masao <masao.fujii@gmail.com> — 2026-07-03T15:46:46Z

    On Fri, Jul 3, 2026 at 4:34 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    > +1
    > Nice additions -- the feature gap is obvious, IMHO.
    >
    > Are you planning to work on it? I'm drowning in work right now and can
    > only jump on it next week.
    
    I don't have plans to work on those at the moment, so please feel free
    to take them on if you have time!
    
    
    > I'm not so sure about this one. At this point, isn't "query" already \0
    > terminated? I'm also wondering if it could affect pg_mbcliplen() down
    > the road, since strnlen() can return a different value
    > (log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN) on large queries --
    > not tested yet.
    
    Yes, "query" should already be NUL-terminated here. The reason for
    using strnlen() is not to handle an unterminated string, but to avoid
    scanning the entire query when it's very large and we only need to
    know whether it exceeds log_statement_max_length.
    
    I think it's fine to pass the bounded length to pg_mbcliplen().
    It only needs enough input to find a multibyte-safe clipping point at
    or before log_statement_max_length, i.e., it doesn't need the full
    query length. The extra MAX_MULTIBYTE_CHAR_LEN bytes provide enough
    lookahead to handle a multibyte character boundary correctly.
    
    - query_len = strlen(query);
    + query_len = strnlen(query,
    + (size_t) log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN);
    
    Regards,
    
    -- 
    Fujii Masao
    
    
    
    
  47. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-07-04T11:01:51Z

    On 03/07/2026 17:46, Fujii Masao wrote:
    > On Fri, Jul 3, 2026 at 4:34 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    >> +1
    >> Nice additions -- the feature gap is obvious, IMHO.
    >>
    >> Are you planning to work on it? I'm drowning in work right now and can
    >> only jump on it next week.
    > I don't have plans to work on those at the moment, so please feel free
    > to take them on if you have time!
    > 
    > 
    >> I'm not so sure about this one. At this point, isn't "query" already \0
    >> terminated? I'm also wondering if it could affect pg_mbcliplen() down
    >> the road, since strnlen() can return a different value
    >> (log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN) on large queries --
    >> not tested yet.
    > Yes, "query" should already be NUL-terminated here. The reason for
    > using strnlen() is not to handle an unterminated string, but to avoid
    > scanning the entire query when it's very large and we only need to
    > know whether it exceeds log_statement_max_length.
    > 
    > I think it's fine to pass the bounded length to pg_mbcliplen().
    > It only needs enough input to find a multibyte-safe clipping point at
    > or before log_statement_max_length, i.e., it doesn't need the full
    > query length. The extra MAX_MULTIBYTE_CHAR_LEN bytes provide enough
    > lookahead to handle a multibyte character boundary correctly.
    > 
    > - query_len = strlen(query);
    > + query_len = strnlen(query,
    > + (size_t) log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN);
    
    All right, thanks for the explanation.
    I'll give it a try next week.
    
    Have a nice weekend!
    
    Best, Jim
    
    
    
    
    
  48. Re: Truncate logs by max_log_size

    Jim Jones <jim.jones@uni-muenster.de> — 2026-07-08T17:02:40Z

    Hi Fujii
    
    On 03.07.26 17:46, Fujii Masao wrote:
    > On Fri, Jul 3, 2026 at 4:34 PM Jim Jones <jim.jones@uni-muenster.de> wrote:
    >> +1
    >> Nice additions -- the feature gap is obvious, IMHO.
    >>
    >> Are you planning to work on it? I'm drowning in work right now and can
    >> only jump on it next week.
    > 
    > I don't have plans to work on those at the moment, so please feel free
    > to take them on if you have time!
    > 
    > 
    >> I'm not so sure about this one. At this point, isn't "query" already \0
    >> terminated? I'm also wondering if it could affect pg_mbcliplen() down
    >> the road, since strnlen() can return a different value
    >> (log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN) on large queries --
    >> not tested yet.
    > 
    > Yes, "query" should already be NUL-terminated here. The reason for
    > using strnlen() is not to handle an unterminated string, but to avoid
    > scanning the entire query when it's very large and we only need to
    > know whether it exceeds log_statement_max_length.
    > 
    > I think it's fine to pass the bounded length to pg_mbcliplen().
    > It only needs enough input to find a multibyte-safe clipping point at
    > or before log_statement_max_length, i.e., it doesn't need the full
    > query length. The extra MAX_MULTIBYTE_CHAR_LEN bytes provide enough
    > lookahead to handle a multibyte character boundary correctly.
    > 
    > - query_len = strlen(query);
    > + query_len = strnlen(query,
    > + (size_t) log_statement_max_length + MAX_MULTIBYTE_CHAR_LEN);
    
    Attached 0001 addressing the points you made:
    
    * appending ellipsis to the query to indicate truncation (docs and tests
    also updated accordingly). A side effect of this change is that setting
    the parameter to 0 logs an ellipsis, which is not zero in length, but is
    arguably correct, as it indicates that the whole query has been
    truncated - just noting.
    * use of strnlen to avoid scanning the whole query.
    * truncation of prepared statements in DETAIL.
    
    While working on this I noticed some redundant checks to call
    truncate_query_log(), e.g. in exec_execute_message():
    
    if (log_statement_max_length >= 0)
    	truncated_source = truncate_query_log(sourceText);
    
    truncate_query_log() already returns NULL when query logging is disabled
    or when no truncation is needed:
    
    /* Truncation is disabled when the limit is negative */
    if (!query || log_statement_max_length < 0)
    	return NULL;
    
    So I'd argue that we don't need any checks in the caller.
    
    - char	   *truncated_source = NULL;
    -
    - if (log_statement_max_length >= 0)
    -	truncated_source = truncate_query_log(sourceText);
    + char	   *truncated_source = truncate_query_log(sourceText);
    
    0002 attached does this.
    
    Thoughts?
    
    BTW, should I open a new CF entry for this?
    
    Best, Jim