Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Logging Elixir/Phoenix/Ecto:如何定制SQL查询日志格式?_Logging_Elixir_Ecto - Fatal编程技术网

Logging Elixir/Phoenix/Ecto:如何定制SQL查询日志格式?

Logging Elixir/Phoenix/Ecto:如何定制SQL查询日志格式?,logging,elixir,ecto,Logging,Elixir,Ecto,在我的Phoenix/Ecto应用程序中,当我将日志级别设置为:debug,我会看到Ecto发出的每个SQL查询的有用日志条目,如下所示: [debug] QUERY OK source="users" db=1.9ms SELECT u0."id", u0."full_name", u0."email", u0."uuid", u0."auth0_uid", u0."last_signed_in_at", u0."inserted_at", u0."updated_at" FROM "user

在我的Phoenix/Ecto应用程序中,当我将日志级别设置为
:debug
,我会看到Ecto发出的每个SQL查询的有用日志条目,如下所示:

[debug] QUERY OK source="users" db=1.9ms
SELECT u0."id", u0."full_name", u0."email", u0."uuid", u0."auth0_uid", u0."last_signed_in_at", u0."inserted_at", u0."updated_at" FROM "users" AS u0 WHERE (u0."id" = $1) LIMIT 1 [1]
[debug] QUERY OK source="projects" db=11.8ms
SELECT p0."id", p0."name", p0."uuid", p0."settings", p0."inserted_at", p0."updated_at" FROM "projects" AS p0 WHERE (p0."uuid" = $1) LIMIT 1 ["7qDjSk"]
[debug] QUERY OK source="project_admin_joins" db=1.9ms
SELECT p0."id", p0."project_id", p0."admin_id", p0."inserted_at", p0."updated_at", p0."project_id" FROM "project_admin_joins" AS p0 WHERE (p0."project_id" = $1) ORDER BY p0."project_id" [2]
但我想对这种格式做一些调整:

  • 每个sql查询生成两行日志输出。将所有这些信息放在一行中对我来说很重要,因为这样可以更容易地在日志管理服务中查找事件,如
  • 理想情况下,我希望去掉字段名周围的引号,以便查询更易于直观地扫描

如何自定义Ecto sql查询日志的格式?

看起来没有自定义Ecto日志格式的事情;相反,我需要禁用内置日志并编写自己的日志函数但这在EXTO v2和EXTO v3中的工作原理非常不同。


外星2型 在
config.exs
中,配置MyApp.Repo以使用新的自定义记录器功能。这个函数可以在任何地方使用,但在我的例子中,我将它放在了
MyApp.Repo.log\u query/2

config:my_app,MyApp.Repo,
# ...
记录器:[{MyApp.Repo,:log\u query,[]}]
lib/my\u app/repo.ex
中,定义
log\u query
函数:(注意:在我的例子中,我硬编码了
:debug
日志级别。)

就这样!确保您的日志级别设置正确,重新启动应用程序,您应该可以看到所有以新格式而不是旧格式记录的Ecto查询


外胚层v3 Ecto v3鼓励您使用,而不是那些讨厌的旧配置

lib/my_app/application.ex
MyApp.application.start/2
中,您需要设置遥测事件。在
主管之前添加此代码段。启动链接/2
调用:

#订阅用于日志记录的EXTO查询
#看https://hexdocs.pm/ecto/Ecto.Repo.html#module-遥测事件
#及https://github.com/beam-telemetry/telemetry
handler=&MyApp.Telemetry.handle\u事件/4
:ok=:telemetry.attach(“我的应用程序-exto”,[:我的应用程序,:repo,:query],处理程序,%{})
然后定义遥测模块,该模块目前只有一个事件处理程序。我把我的保存在
lib/my_app/telemetry.ex

defmodule MyApp.Telemetry do
  require Logger

  # Thanks to https://hexdocs.pm/ecto/Ecto.Repo.html#module-telemetry-events
  def handle_event([:my_app, :repo, :query], measurements, metadata, _config) do
    Logger.log(:debug, fn ->
      {ok, _} = metadata.result
      source = inspect(metadata.source)
      time = div(measurements.query_time, 100_000) / 10
      # Strip out unnecessary quotes from the query for readability
      query = Regex.replace(~r/(\d\.)"([^"]+)"/, metadata.query, "\\1\\2")
      params = inspect(metadata.params, charlists: false)

      "SQL query: #{ok} source=#{source} db=#{time}ms   #{query}   params=#{params}"
    end)
  end
end
config/config.exs
中,配置MyApp.Repo以禁用标准的Ecto日志记录:

config:my_app,MyApp.Repo,
# ...
日志:false
就这样!确保您的日志级别设置正确,重新启动应用程序,您应该可以看到所有以新格式而不是旧格式记录的Ecto查询

defmodule MyApp.Telemetry do
  require Logger

  # Thanks to https://hexdocs.pm/ecto/Ecto.Repo.html#module-telemetry-events
  def handle_event([:my_app, :repo, :query], measurements, metadata, _config) do
    Logger.log(:debug, fn ->
      {ok, _} = metadata.result
      source = inspect(metadata.source)
      time = div(measurements.query_time, 100_000) / 10
      # Strip out unnecessary quotes from the query for readability
      query = Regex.replace(~r/(\d\.)"([^"]+)"/, metadata.query, "\\1\\2")
      params = inspect(metadata.params, charlists: false)

      "SQL query: #{ok} source=#{source} db=#{time}ms   #{query}   params=#{params}"
    end)
  end
end