如何在Heroku和Rails上配置PostgreSQL的client_min_messages?

4
我试图减少Heroku / Rails应用程序中PostgreSQL的一些日志噪音。具体来说,我正在尝试将client_min_messages设置配置为warning,而不是默认值notice
我按照此文章中的步骤,在我的database.yml文件中指定了min_messages: warning,但这似乎对我的Heroku PostgreSQL实例没有任何影响。我仍然在日志中看到NOTICE消息,并且当我在数据库上运行SHOW client_min_messages时,它仍然返回notice
以下是我在Papertrail日志中看到的示例(已编辑)。
Nov 23 15:04:51 my-app-name-production app/postgres.123467 [COLOR] [1234-5]  sql_error_code = 00000 log_line="5733" application_name="puma: cluster worker 0: 4 [app]" NOTICE:  text-search query contains only stop words or doesn't contain lexemes, ignored

我还可以确认该设置似乎在Rails配置中 - Rails.application.config.database_configuration[Rails.env] 在生产控制台中显示一个哈希,其中包含"min_messages"=>"warning"

我还尝试通过PostgreSQL控制台手动更新它 - 所以 SET client_min_messages TO WARNING; - 但这个设置不会“保留”。它似乎会在下一个会话中重置。

如何在Heroku/Rails上配置client_min_messageswarning


1
嗯,根据文档 https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html,似乎 min_messages: warning 应该可以工作。 - engineersmnky
是的,从我参考的博客文章上看来是真的。但是我可以确认在我的database.yml中我有min_messages: warning,但在Heroku上并没有起作用。Heroku 是否真的使用你的 database.yml 呢? - Jaco Pretorius
1
当您发出SET client_min_messages TO WARNING;时,它仅适用于当前会话/连接。通过ALTER DATABASE your_database SET client_min_messages TO 'warning';在数据库级别上设置它将其设置为从那时起新建立的连接的默认值。这些新连接仍然可以在其范围内更改它。此外,其他内容仍然可以在重置/重建服务器时将数据库设置恢复为初始的默认值。 - Zegarek
“我仍然在我的日志中看到 NOTICE 消息。” 你知道有一个单独的设置来控制日志输出吗?log_min_messages(但默认值是 WARNING,所以也许你只是表述不清楚...) - Erwin Brandstetter
好的一点是:哪些日志是我的日志Chris'命令设置了客户端日志的默认级别,database.yml在客户端上指定了相同的内容,Erwin's将其设置为保存到log_destination的服务器日志的级别。 - Zegarek
如果有帮助的话,我添加了一个日志示例。 - Jaco Pretorius
2个回答

2
如果其他方法都失败了,服务器日志无法控制或客户端日志无法跟踪和关闭,则Papertrail允许您过滤掉任何不需要的日志。数据库/客户端仍会生成它们,Heroku仍会将它们传递给Papertrail,但是一旦它们进入Papertrail,Papertrail就会将它们丢弃。
“Shotgun”方法,基于PostgreSQL。
REVOKE SET ON PARAMETER client_min_messages,log_min_messages FROM your_app_user;
REVOKE GRANT OPTION FOR SET ON PARAMETER client_min_messages,log_min_messages FROM your_app_user;
ALTER SYSTEM   SET client_min_messages=WARNING;
ALTER SYSTEM   SET log_min_messages   =WARNING;
ALTER DATABASE db_user_by_your_app SET client_min_messages=WARNING;
ALTER DATABASE db_user_by_your_app SET log_min_messages   =WARNING;
ALTER ROLE your_app_user SET client_min_messages=WARNING;
ALTER ROLE your_app_user SET log_min_messages   =WARNING;

然后你需要等待、重新启动应用程序、强制重新连接或重启它连接到的数据库/实例/服务器/集群。
如果你的应用程序打开和关闭连接 - 只需等待,随着时间的推移,旧连接将被使用新设置的新连接所替换。
如果它使用一个,它将继续重复使用已有的连接,因此你需要强制重新打开它们以使更改生效。你可能需要重新启动应用程序,或者它们可以被强制关闭:
SELECT pg_terminate_backend(pid) from pg_stat_activity where pid<>pg_backend_pid();

原因是你无法从外部即时更改会话级别设置,而且所有上述操作都只影响新会话的默认设置。REVOKE指令将防止应用程序用户更改设置,但如果他们实际尝试更改,则会引发错误。我将其保留作为以后参考,同时记住目前Heroku支持PostgreSQL版本高达14},而{{link2:REVOKE SET ON PARAMETER指令是在版本15中添加的
如果需要同时使用所有这些功能,则必须从Papertrail中查看每个连接的两端日志,连接到多个数据库,使用不同的用户,这些用户还可以不断更改设置。逐一检查以隔离根本原因。

上下文

每个客户端都会写入一个日志,服务器上可能会写入一个或多个日志。

取决于将日志馈送到 Papertrail 的方式,您可能只需要更改其中一个设置。由于参数何时以及如何应用,操纵设置始终是棘手的。您有多个级别可以指定参数,然后进行覆盖:

  1. 系统级别的参数,从postgresql.conf加载,然后是postgresql -c/pg_ctl -opostgresql.auto.conf,它反映了使用ALTER SYSTEM SET ...或直接应用的更改。
  2. 数据库覆盖系统。使用ALTER DATABASE db SET...应用。
  3. 用户/角色覆盖数据库。使用ALTER ROLE user SET...更改。
  4. 会话覆盖用户/角色。使用SET...更改,客户端在连接初始化时也使用。如果在database.ymlENV['DATABASE_URL']下设置了min_messages中的client_min_messages值,则 Rails将使用环境设置,用其覆盖在.yml中找到的值,如:DATABASE_URL=postgres://localhost/rails_event_store_active_record?min_messages=warning
  5. 事务-级别的参数是最具体的,覆盖所有其他设置-它们基本上是会话级别的参数,在事务结束时返回其初始设置。使用SET LOCAL...
当一个新的会话打开时,它会加载系统默认设置,然后覆盖数据库级别和角色级别设置,之后客户端通常会发出自己的SET设置。确保你正在使用database.yml中的设置,因为可能有多个设置集。你的应用程序中可能有一些逻辑不断更改设置,所以注意检查。

1
这些内容在Heroku托管的Postgres服务上不被允许,但总体来看这似乎是一个很好的答案。 - Chris
1
感谢。主要目标是澄清这些设置如何传播并影响数据库行为。有了这个想法,更容易找到任何托管数据库提供程序的方法以及它们如何操作设置。 - Zegarek

-2

我认为你想要的是log_min_messages,而不是client_min_messages

控制写入服务器日志的消息级别。有效值为DEBUG5DEBUG4DEBUG3DEBUG2DEBUG1INFONOTICEWARNINGERRORLOGFATALPANIC。每个级别都包括其后面的所有级别。级别越高,发送到日志的消息就越少。默认值为WARNING。请注意,LOG在此处的等级与client_min_messages中的等级不同。只有超级用户和具有适当SET权限的用户才能更改此设置。

我不确定你的数据库用户是否被允许设置它,但你可以尝试在数据库级别这样做:

ALTER DATABASE your_database
    SET log_min_messages TO 'warning';

如果这个方法不奏效,而在角色或连接层面设置也无效,并且heroku pg:settings 也无效(通过其他答案和评论进行确认),那么很遗憾的是,在Heroku上可能无法实现此目标。
Heroku Postgres是一项托管服务,因此供应商做出了某些不可配置的决策。这可能就是其中之一。

1
这似乎对Heroku的PostgreSQL实例没有任何影响。 - Jaco Pretorius
@JacoPretorius,我已经更新了我的答案。(a) 尝试使用 log_min_messages 而不是 client_min_messages。(b) 尝试使用 heroku pg:settings。由于 Heroku 删除了免费层,我不再拥有 Heroku Postgres 数据库进行测试,因此我没有测试过它。 - Chris
1
@Chris 我收到了相同的信息 - "pg:settings:log-min-messages 不是 Heroku 命令" 尝试很不错 :( - Jaco Pretorius
2
@Chris 我刚试了一下 - 这给了我一个"ERROR: permission denied to set parameter "log_min_messages"" :( 我真的认为这里的答案是你不能在Heroku上这样做。如果他们为您管理数据库,则无法访问这些配置设置。 - Jaco Pretorius
我的猜测是,Papertrail 是通过应用程序/客户端日志进行数据输入的,而这些日志从未对数据库中的设置更改做出反应,因为Rails使用池来重复使用与旧设置建立的连接,并且它有自己的一套覆盖方式,将其注入到新建立的连接中。 - Zegarek
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接