如何在Postgres中写入自定义服务端日志并推送至AWS CloudWatch
Postgres 自定义服务端日志写入及CloudWatch推送方案
问题原因说明
你当前使用RAISE NOTICE/RAISE INFO没有写入服务端日志,是因为Postgres默认的服务端日志级别阈值设置高于notice/info,这类消息默认只会返回给调用客户端,不会落盘到服务端日志文件。
方案1:调整日志配置让RAISE语句写入服务端日志
全局配置方式
修改postgresql.conf中的以下参数:
log_min_messages = notice:控制写入服务端日志的最低消息级别,默认值通常为warning,修改为notice后,RAISE NOTICE及更高级别的消息都会写入服务端日志;如果需要RAISE INFO也写入,可以调整为log_min_messages = info- 可选配置:
client_min_messages = warning:调整返回给客户端的最低消息级别,避免自定义日志内容返回给调用侧造成输出冗余
修改完成后执行SELECT pg_reload_conf();重载配置即可生效,无需重启数据库实例。
函数级配置方式(更推荐,不影响全局日志)
如果不想修改全局配置造成全库日志量上涨,可以仅在需要写日志的函数上单独配置参数:
CREATE or replace FUNCTION logInfo() RETURNS void AS $$ BEGIN raise notice 'Hello World!'; raise info 'Hello World!'; END; $$ LANGUAGE plpgsql SET log_min_messages = 'notice'; -- 仅该函数执行时生效
方案2:自定义日志表方案
如果需要更灵活的日志字段扩展(比如增加业务ID、请求标识、trace ID等),可以直接创建业务日志表存储自定义日志:
-- 创建自定义日志表 CREATE TABLE app_custom_logs ( id SERIAL PRIMARY KEY, log_level VARCHAR(10) NOT NULL, log_content TEXT NOT NULL, biz_id VARCHAR(64), created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, created_by TEXT NOT NULL DEFAULT CURRENT_USER ); -- 写日志示例 INSERT INTO app_custom_logs(log_level, log_content, biz_id) VALUES ('INFO', 'Hello World!', 'biz_12345');
推送日志到AWS CloudWatch方案
如果你使用AWS RDS for PostgreSQL
- 若采用方案1写入服务端日志:直接在RDS控制台开启PostgreSQL日志到CloudWatch的导出功能,无需额外开发即可自动同步日志到CloudWatch Logs
- 若采用方案2存储到自定义表:可以通过Lambda函数定时拉取表内新增日志写入CloudWatch,也可以通过AWS DMS做增量同步
如果你使用自建PostgreSQL(EC2/本地托管)
- 若采用方案1写入日志文件:安装CloudWatch Agent,配置采集路径指向Postgres服务端日志目录即可自动推送日志到CloudWatch
- 若采用方案2存储到自定义表:可以使用Fluentd、Filebeat等日志采集工具对接Postgres增量读取日志,再推送至CloudWatch
内容的提问来源于stack exchange,提问作者Marek Puchalski
相关产品推荐
相关产品推荐

