mirror of https://github.com/postgres/postgres
parent
0381fefaa4
commit
cde9cf170c
@ -1,678 +0,0 @@ |
|||||||
<!-- doc/src/sgml/pgaudit.sgml --> |
|
||||||
|
|
||||||
<sect1 id="pgaudit" xreflabel="pgaudit"> |
|
||||||
<title>pg_audit</title> |
|
||||||
|
|
||||||
<indexterm zone="pgaudit"> |
|
||||||
<primary>pg_audit</primary> |
|
||||||
</indexterm> |
|
||||||
|
|
||||||
<para> |
|
||||||
The <filename>pg_audit</filename> extension provides detailed session |
|
||||||
and/or object audit logging via the standard logging facility. The goal |
|
||||||
is to provide the tools needed to produce audit logs required to pass any |
|
||||||
government, financial, or ISO certification audit. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
An audit is an official inspection of an individual's or organization's |
|
||||||
accounts, typically by an independent body. The information gathered by |
|
||||||
<filename>pg_audit</filename> is properly called an audit trail or audit |
|
||||||
log. The term audit log is used in this documentation. |
|
||||||
</para> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Why <literal>pg_audit</>?</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Basic statement logging can be provided by the standard logging facility |
|
||||||
using <literal>log_statement = all</>. This is acceptable for monitoring |
|
||||||
and other usages but does not provide the level of detail generally |
|
||||||
required for an audit. It is not enough to have a list of all the |
|
||||||
operations performed against the database. It must also be possible to |
|
||||||
find particular statements that are of interest to an auditor. The |
|
||||||
standard logging facility shows what the user requested, while |
|
||||||
<literal>pg_audit</> focuses on the details of what happened while |
|
||||||
the database was satisfying the request. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
For example, an auditor may want to verify that a particular table was |
|
||||||
created inside a documented maintenance window. This might seem like a |
|
||||||
simple job for grep, but what if you are presented with something like |
|
||||||
this (intentionally obfuscated) example: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
DO $$ |
|
||||||
BEGIN |
|
||||||
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)'; |
|
||||||
END $$; |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
<para> |
|
||||||
Standard logging will give you this: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
LOG: statement: DO $$ |
|
||||||
BEGIN |
|
||||||
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)'; |
|
||||||
END $$; |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
<para> |
|
||||||
It appears that finding the table of interest may require some knowledge |
|
||||||
of the code in cases where tables are created dynamically. This is not |
|
||||||
ideal since it would be preferrable to just search on the table name. |
|
||||||
This is where <literal>pg_audit</> comes in. For the same input, |
|
||||||
it will produce this output in the log: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
AUDIT: SESSION,33,1,FUNCTION,DO,,,"DO $$ |
|
||||||
BEGIN |
|
||||||
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)'; |
|
||||||
END $$;" |
|
||||||
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT) |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
<para> |
|
||||||
Not only is the <literal>DO</> block logged, but substatement 2 contains |
|
||||||
the full text of the <literal>CREATE TABLE</> with the statement type, |
|
||||||
object type, and full-qualified name to make searches easy. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
When logging <literal>SELECT</> and <literal>DML</> statements, |
|
||||||
<literal>pg_audit</> can be configured to log a separate entry for each |
|
||||||
relation referenced in a statement. No parsing is required to find all |
|
||||||
statements that touch a particular table. In fact, the goal is that the |
|
||||||
statement text is provided primarily for deep forensics and should not be |
|
||||||
required for an audit. |
|
||||||
</para> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Usage Considerations</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Depending on settings, it is possible for <literal>pg_audit</literal> to |
|
||||||
generate an enormous volume of logging. Be careful to determine |
|
||||||
exactly what needs to be audit logged in your environment to avoid |
|
||||||
logging too much. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
For example, when working in an OLAP environment it would probably not be |
|
||||||
wise to audit log inserts into a large fact table. The size of the log |
|
||||||
file will likely be many times the actual data size of the inserts because |
|
||||||
the log file is expressed as text. Since logs are generally stored with |
|
||||||
the OS this may lead to disk space being exhausted very |
|
||||||
quickly. In cases where it is not possible to limit audit logging to |
|
||||||
certain tables, be sure to assess the performance impact while testing |
|
||||||
and allocate plenty of space on the log volume. This may also be true for |
|
||||||
OLTP environments. Even if the insert volume is not as high, the |
|
||||||
performance impact of audit logging may still noticeably affect latency. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
To limit the number of relations audit logged for <literal>SELECT</> |
|
||||||
and <literal>DML</> statments, consider using object audit logging |
|
||||||
(see <xref linkend="pgaudit-object-audit-logging">). Object audit logging |
|
||||||
allows selection of the relations to be logged allowing for reduction |
|
||||||
of the overall log volume. However, when new relations are added they |
|
||||||
must be explicitly added to object audit logging. A programmatic |
|
||||||
solution where specified tables are excluded from logging and all others |
|
||||||
are included may be a good option in this case. |
|
||||||
</para> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Settings</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Settings may be modified only by a superuser. Allowing normal users to |
|
||||||
change their settings would defeat the point of an audit log. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
Settings can be specified globally (in |
|
||||||
<filename>postgresql.conf</filename> or using |
|
||||||
<literal>ALTER SYSTEM ... SET</>), at the database level (using |
|
||||||
<literal>ALTER DATABASE ... SET</literal>), or at the role level (using |
|
||||||
<literal>ALTER ROLE ... SET</literal>). Note that settings are not |
|
||||||
inherited through normal role inheritance and <literal>SET ROLE</> will |
|
||||||
not alter a user's <literal>pg_audit</> settings. This is a limitation |
|
||||||
of the roles system and not inherent to <literal>pg_audit</>. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
The <literal>pg_audit</> extension must be loaded in |
|
||||||
<xref linkend="guc-shared-preload-libraries">. Otherwise, an error |
|
||||||
will be raised at load time and no audit logging will occur. |
|
||||||
</para> |
|
||||||
|
|
||||||
<variablelist> |
|
||||||
<varlistentry id="guc-pgaudit-log" xreflabel="pg_audit.log"> |
|
||||||
<term><varname>pg_audit.log</varname> (<type>string</type>) |
|
||||||
<indexterm> |
|
||||||
<primary><varname>pg_audit.log</> configuration parameter</primary> |
|
||||||
</indexterm> |
|
||||||
</term> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Specifies which classes of statements will be logged by session |
|
||||||
audit logging. Possible values are: |
|
||||||
</para> |
|
||||||
|
|
||||||
<itemizedlist> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>READ</literal> - <literal>SELECT</literal> and |
|
||||||
<literal>COPY</literal> when the source is a relation or a |
|
||||||
query. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>WRITE</literal> - <literal>INSERT</literal>, |
|
||||||
<literal>UPDATE</literal>, <literal>DELETE</literal>, |
|
||||||
<literal>TRUNCATE</literal>, and <literal>COPY</literal> when the |
|
||||||
destination is a relation. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>FUNCTION</literal> - Function calls and |
|
||||||
<literal>DO</literal> blocks. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>ROLE</literal> - Statements related to roles and |
|
||||||
privileges: <literal>GRANT</literal>, |
|
||||||
<literal>REVOKE</literal>, |
|
||||||
<literal>CREATE/ALTER/DROP ROLE</literal>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>DDL</literal> - All <literal>DDL</> that is not included |
|
||||||
in the <literal>ROLE</> class. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>MISC</literal> - Miscellaneous commands, e.g. |
|
||||||
<literal>DISCARD</literal>, <literal>FETCH</literal>, |
|
||||||
<literal>CHECKPOINT</literal>, <literal>VACUUM</literal>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</itemizedlist> |
|
||||||
|
|
||||||
<para> |
|
||||||
Multiple classes can be provided using a comma-separated list and |
|
||||||
classes can be subtracted by prefacing the class with a |
|
||||||
<literal>-</> sign (see <xref linkend="pgaudit-session-audit-logging">). |
|
||||||
The default is <literal>none</>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</varlistentry> |
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-catalog" xreflabel="pg_audit.log_catalog"> |
|
||||||
<term><varname>pg_audit.log_catalog</varname> (<type>boolean</type>) |
|
||||||
<indexterm> |
|
||||||
<primary><varname>pg_audit.log_catalog</> configuration parameter</primary> |
|
||||||
</indexterm> |
|
||||||
</term> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Specifies that session logging should be enabled in the case where all |
|
||||||
relations in a statement are in pg_catalog. Disabling this setting |
|
||||||
will reduce noise in the log from tools like psql and PgAdmin that query |
|
||||||
the catalog heavily. The default is <literal>on</>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</varlistentry> |
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-level" xreflabel="pg_audit.log_level"> |
|
||||||
<term><varname>pg_audit.log_level</varname> (<type>boolean</type>) |
|
||||||
<indexterm> |
|
||||||
<primary><varname>pg_audit.log_level</> configuration parameter</primary> |
|
||||||
</indexterm> |
|
||||||
</term> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Specifies the log level that will be used for log entries (see |
|
||||||
<xref linkend="RUNTIME-CONFIG-SEVERITY-LEVELS"> for valid levels). |
|
||||||
This setting is used for regression testing and may also be useful |
|
||||||
to end users for testing or other purposes. It is not intended to |
|
||||||
be used in a production environment as it may leak which statements |
|
||||||
are being logged to the user. The default is <literal>log</>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</varlistentry> |
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-parameter" xreflabel="pg_audit.log_parameter"> |
|
||||||
<term><varname>pg_audit.log_parameter</varname> (<type>boolean</type>) |
|
||||||
<indexterm> |
|
||||||
<primary><varname>pg_audit.log_parameter</> configuration parameter</primary> |
|
||||||
</indexterm> |
|
||||||
</term> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Specifies that audit logging should include the parameters that |
|
||||||
were passed with the statement. When parameters are present they will |
|
||||||
be included in CSV format after the statement text. The default is |
|
||||||
<literal>off</>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</varlistentry> |
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-relation" xreflabel="pg_audit.log_relation"> |
|
||||||
<term><varname>pg_audit.log_relation</varname> (<type>boolean</type>) |
|
||||||
<indexterm> |
|
||||||
<primary><varname>pg_audit.log_relation</> configuration parameter</primary> |
|
||||||
</indexterm> |
|
||||||
</term> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Specifies whether session audit logging should create a separate |
|
||||||
log entry for each relation (<literal>TABLE</>, <literal>VIEW</>, |
|
||||||
etc.) referenced in a <literal>SELECT</> or <literal>DML</> |
|
||||||
statement. This is a useful shortcut for exhaustive logging |
|
||||||
without using object audit logging. The default is |
|
||||||
<literal>off</>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</varlistentry> |
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-log-statement-once" xreflabel="pg_audit.log_statement-once"> |
|
||||||
<term><varname>pg_audit.log_statement_once</varname> (<type>boolean</type>) |
|
||||||
<indexterm> |
|
||||||
<primary><varname>pg_audit.log_statement_once</> configuration parameter</primary> |
|
||||||
</indexterm> |
|
||||||
</term> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Specifies whether logging will include the statement text and |
|
||||||
parameters with the first log entry for a statement/substatement |
|
||||||
combination or with every entry. Disabling this setting will |
|
||||||
result in less verbose logging but may make it more difficult to |
|
||||||
determine the statement that generated a log entry, though the |
|
||||||
statement/substatement pair along with the process id should suffice |
|
||||||
to identify the statement text logged with a previous entry. The |
|
||||||
default is <literal>off</>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</varlistentry> |
|
||||||
|
|
||||||
<varlistentry id="guc-pgaudit-role" xreflabel="pg_audit.role"> |
|
||||||
<term><varname>pg_audit.role</varname> (<type>string</type>) |
|
||||||
<indexterm> |
|
||||||
<primary><varname>pg_audit.role</> configuration parameter</primary> |
|
||||||
</indexterm> |
|
||||||
</term> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Specifies the master role to use for object audit logging. Muliple |
|
||||||
audit roles can be defined by granting them to the master role. |
|
||||||
This allows multiple groups to be in charge of different aspects |
|
||||||
of audit logging. There is no default. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</varlistentry> |
|
||||||
</variablelist> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2 id="pgaudit-session-audit-logging"> |
|
||||||
<title>Session Audit Logging</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Session audit logging provides detailed logs of all statements executed |
|
||||||
by a user in the backend. |
|
||||||
</para> |
|
||||||
|
|
||||||
<sect3> |
|
||||||
<title>Configuration</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Session logging is enabled with the <xref linkend="guc-pgaudit-log"> |
|
||||||
setting. |
|
||||||
|
|
||||||
Enable session logging for all <literal>DML</> and <literal>DDL</> and |
|
||||||
log all relations in <literal>DML</> statements: |
|
||||||
<programlisting> |
|
||||||
set pg_audit.log = 'write, ddl'; |
|
||||||
set pg_audit.log_relation = on; |
|
||||||
</programlisting> |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
Enable session logging for all commands except <literal>MISC</> and |
|
||||||
raise audit log messages as <literal>NOTICE</>: |
|
||||||
<programlisting> |
|
||||||
set pg_audit.log = 'all, -misc'; |
|
||||||
set pg_audit.log_notice = on; |
|
||||||
</programlisting> |
|
||||||
</para> |
|
||||||
</sect3> |
|
||||||
|
|
||||||
<sect3> |
|
||||||
<title>Example</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
In this example session audit logging is used for logging |
|
||||||
<literal>DDL</> and <literal>SELECT</> statements. Note that the |
|
||||||
insert statement is not logged since the <literal>WRITE</> class |
|
||||||
is not enabled |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
SQL: |
|
||||||
</para> |
|
||||||
<programlisting> |
|
||||||
set pg_audit.log = 'read, ddl'; |
|
||||||
|
|
||||||
create table account |
|
||||||
( |
|
||||||
id int, |
|
||||||
name text, |
|
||||||
password text, |
|
||||||
description text |
|
||||||
); |
|
||||||
|
|
||||||
insert into account (id, name, password, description) |
|
||||||
values (1, 'user1', 'HASH1', 'blah, blah'); |
|
||||||
|
|
||||||
select * |
|
||||||
from account; |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
<para> |
|
||||||
Log Output: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
AUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.account,create table account |
|
||||||
( |
|
||||||
id int, |
|
||||||
name text, |
|
||||||
password text, |
|
||||||
description text |
|
||||||
); |
|
||||||
AUDIT: SESSION,2,1,READ,SELECT,,,select * |
|
||||||
from account |
|
||||||
</programlisting> |
|
||||||
</sect3> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2 id="pgaudit-object-audit-logging"> |
|
||||||
<title>Object Auditing</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Object audit logging logs statements that affect a particular relation. |
|
||||||
Only <literal>SELECT</>, <literal>INSERT</>, <literal>UPDATE</> and |
|
||||||
<literal>DELETE</> commands are supported. <literal>TRUNCATE</> is not |
|
||||||
included because there is no specific privilege for it. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
Object audit logging is intended to be a finer-grained replacement for |
|
||||||
<literal>pg_audit.log = 'read, write'</literal>. As such, it may not |
|
||||||
make sense to use them in conjunction but one possible scenario would |
|
||||||
be to use session logging to capture each statement and then supplement |
|
||||||
that with object logging to get more detail about specific relations. |
|
||||||
</para> |
|
||||||
|
|
||||||
<sect3> |
|
||||||
<title>Configuration</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Object-level audit logging is implemented via the roles system. The |
|
||||||
<xref linkend="guc-pgaudit-role"> setting defines the role that |
|
||||||
will be used for audit logging. A relation (<literal>TABLE</>, |
|
||||||
<literal>VIEW</>, etc.) will be audit logged when the audit role has |
|
||||||
permissions for the command executed or inherits the permissions from |
|
||||||
another role. This allows you to effectively have multiple audit roles |
|
||||||
even though there is a single master role in any context. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
Set <xref linkend="guc-pgaudit-role"> to <literal>auditor</> and |
|
||||||
grant <literal>SELECT</> and <literal>DELETE</> privileges on the |
|
||||||
<literal>account</> table. Any <literal>SELECT</> or |
|
||||||
<literal>DELETE</> statements on <literal>account</> will now be |
|
||||||
logged: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
set pg_audit.role = 'auditor'; |
|
||||||
|
|
||||||
grant select, delete |
|
||||||
on public.account |
|
||||||
to auditor; |
|
||||||
</programlisting> |
|
||||||
</sect3> |
|
||||||
|
|
||||||
<sect3> |
|
||||||
<title>Example</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
In this example object audit logging is used to illustrate how a |
|
||||||
granular approach may be taken towards logging of <literal>SELECT</> |
|
||||||
and <literal>DML</> statements. Note that logging on the |
|
||||||
<literal>account</> table is controlled by column-level permissions, |
|
||||||
while logging on <literal>account_role_map</> is table-level. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
SQL: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
set pg_audit.role = 'auditor'; |
|
||||||
|
|
||||||
create table account |
|
||||||
( |
|
||||||
id int, |
|
||||||
name text, |
|
||||||
password text, |
|
||||||
description text |
|
||||||
); |
|
||||||
|
|
||||||
grant select (password) |
|
||||||
on public.account |
|
||||||
to auditor; |
|
||||||
|
|
||||||
select id, name |
|
||||||
from account; |
|
||||||
|
|
||||||
select password |
|
||||||
from account; |
|
||||||
|
|
||||||
grant update (name, password) |
|
||||||
on public.account |
|
||||||
to auditor; |
|
||||||
|
|
||||||
update account |
|
||||||
set description = 'yada, yada'; |
|
||||||
|
|
||||||
update account |
|
||||||
set password = 'HASH2'; |
|
||||||
|
|
||||||
create table account_role_map |
|
||||||
( |
|
||||||
account_id int, |
|
||||||
role_id int |
|
||||||
); |
|
||||||
|
|
||||||
grant select |
|
||||||
on public.account_role_map |
|
||||||
to auditor; |
|
||||||
|
|
||||||
select account.password, |
|
||||||
account_role_map.role_id |
|
||||||
from account |
|
||||||
inner join account_role_map |
|
||||||
on account.id = account_role_map.account_id |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
<para> |
|
||||||
Log Output: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.account,select password |
|
||||||
from account |
|
||||||
AUDIT: OBJECT,2,1,WRITE,UPDATE,TABLE,public.account,update account |
|
||||||
set password = 'HASH2' |
|
||||||
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account,select account.password, |
|
||||||
account_role_map.role_id |
|
||||||
from account |
|
||||||
inner join account_role_map |
|
||||||
on account.id = account_role_map.account_id |
|
||||||
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account_role_map,select account.password, |
|
||||||
account_role_map.role_id |
|
||||||
from account |
|
||||||
inner join account_role_map |
|
||||||
on account.id = account_role_map.account_id |
|
||||||
</programlisting> |
|
||||||
</sect3> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Format</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Audit entries are written to the standard logging facility and contain |
|
||||||
the following columns in comma-separated format: |
|
||||||
|
|
||||||
<note> |
|
||||||
<para> |
|
||||||
Output is compliant CSV format only if the log line prefix portion |
|
||||||
of each log entry is removed. |
|
||||||
</para> |
|
||||||
</note> |
|
||||||
|
|
||||||
<itemizedlist> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>AUDIT_TYPE</> - <literal>SESSION</> or |
|
||||||
<literal>OBJECT</>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>STATEMENT_ID</> - Unique statement ID for this session. |
|
||||||
Each statement ID represents a backend call. Statement IDs are |
|
||||||
sequential even if some statements are not logged. There may be |
|
||||||
multiple entries for a statement ID when more than one relation |
|
||||||
is logged. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>SUBSTATEMENT_ID</> - Sequential ID for each |
|
||||||
substatement within the main statement. For example, calling |
|
||||||
a function from a query. Substatement IDs are continuous |
|
||||||
even if some substatements are not logged. There may be multiple |
|
||||||
entries for a substatement ID when more than one relation is logged. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>CLASS</> - e.g. (<literal>READ</>, |
|
||||||
<literal>ROLE</>) (see <xref linkend="guc-pgaudit-log">). |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>COMMAND</> - e.g. <literal>ALTER TABLE</>, |
|
||||||
<literal>SELECT</>. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>OBJECT_TYPE</> - <literal>TABLE</>, |
|
||||||
<literal>INDEX</>, <literal>VIEW</>, etc. |
|
||||||
Available for <literal>SELECT</>, <literal>DML</> and most |
|
||||||
<literal>DDL</> statements. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>OBJECT_NAME</> - The fully-qualified object name |
|
||||||
(e.g. public.account). Available for <literal>SELECT</>, |
|
||||||
<literal>DML</> and most <literal>DDL</> statements. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
<literal>STATEMENT</> - Statement executed on the backend. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</itemizedlist> |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
Use <xref linkend="guc-log-line-prefix"> to add any other fields that |
|
||||||
are needed to satisfy your audit log requirements. A typical log line |
|
||||||
prefix might be <literal>'%m %u %d: '</> which would provide the date/time, |
|
||||||
user name, and database name for each audit log. |
|
||||||
</para> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Caveats</title> |
|
||||||
|
|
||||||
<itemizedlist> |
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Object renames are logged under the name they were renamed to. |
|
||||||
For example, renaming a table will produce the following result: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
ALTER TABLE test RENAME TO test2; |
|
||||||
|
|
||||||
AUDIT: SESSION,36,1,DDL,ALTER TABLE,TABLE,public.test2,ALTER TABLE test RENAME TO test2 |
|
||||||
</programlisting> |
|
||||||
</listitem> |
|
||||||
|
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
It is possible to have a command logged more than once. For example, |
|
||||||
when a table is created with a primary key specified at creation time |
|
||||||
the index for the primary key will be logged independently and another |
|
||||||
audit log will be made for the index under the create entry. The |
|
||||||
multiple entries will however be contained within one statement ID. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
|
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Autovacuum and Autoanalyze are not logged. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
|
|
||||||
<listitem> |
|
||||||
<para> |
|
||||||
Statements that are executed after a transaction enters an aborted state |
|
||||||
will not be audit logged. However, the statement that caused the error |
|
||||||
and any subsequent statements executed in the aborted transaction will |
|
||||||
be logged as ERRORs by the standard logging facility. |
|
||||||
</para> |
|
||||||
</listitem> |
|
||||||
</itemizedlist> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Authors</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Abhijit Menon-Sen <email>ams@2ndQuadrant.com</email>, Ian Barwick <email>ian@2ndQuadrant.com</email>, and David Steele <email>david@pgmasters.net</email>. |
|
||||||
</para> |
|
||||||
</sect2> |
|
||||||
</sect1> |
|
Loading…
Reference in new issue