From 87140aeaf7fcdb5fcf70ca6ad99d8e1a7cf374c0 Mon Sep 17 00:00:00 2001 From: Kamil Kowalski Date: Fri, 3 Apr 2020 19:16:41 +0200 Subject: [PATCH 1/4] Allow to configure EctoLogger through :telemetry For complex umbrella apps, having a global config for the :spandex_ecto library can be limiting - particularly when a different tracer is to be used depending on the repo. This change allows to pass configuration to the underlying EctoLogger module, like the `:tracer` option, through the `config` argument in `:telemetry.attach/4`. --- lib/spandex_ecto/ecto_logger.ex | 8 ++++++-- lib/spandex_ecto/telemetry_adapter.ex | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/spandex_ecto/ecto_logger.ex b/lib/spandex_ecto/ecto_logger.ex index e932d88..853a970 100644 --- a/lib/spandex_ecto/ecto_logger.ex +++ b/lib/spandex_ecto/ecto_logger.ex @@ -11,9 +11,13 @@ defmodule SpandexEcto.EctoLogger do @empty_query_placeholder "unknown (unsupported ecto adapter?)" - def trace(log_entry, database) do + def trace(log_entry, database, config \\ []) do # Put in your own configuration here - config = Application.get_env(:spandex_ecto, __MODULE__) + config = + :spandex_ecto + |> Application.get_env(__MODULE__) + |> Keyword.merge(config || []) + tracer = config[:tracer] || raise "tracer is a required option for #{inspect(__MODULE__)}" service = config[:service] || :ecto truncate = config[:truncate] || 5000 diff --git a/lib/spandex_ecto/telemetry_adapter.ex b/lib/spandex_ecto/telemetry_adapter.ex index 9793525..eacb6df 100644 --- a/lib/spandex_ecto/telemetry_adapter.ex +++ b/lib/spandex_ecto/telemetry_adapter.ex @@ -6,12 +6,12 @@ defmodule SpandexEcto.TelemetryAdapter do alias SpandexEcto.EctoLogger # this is for ecto_sql 3.0.x - def handle_event([_app_name, repo_name, :query], total_time, log_entry, _config) when is_integer(total_time) do - EctoLogger.trace(log_entry, "#{repo_name}_database") + def handle_event([_app_name, repo_name, :query], total_time, log_entry, config) when is_integer(total_time) do + EctoLogger.trace(log_entry, "#{repo_name}_database", config) end # This is for ecto_sql >= 3.1 - def handle_event([_app_name, repo_name, :query], measurements, metadata, _config) when is_map(measurements) do + def handle_event([_app_name, repo_name, :query], measurements, metadata, config) when is_map(measurements) do log_entry = %{ query: metadata.query, source: metadata.source, @@ -22,7 +22,7 @@ defmodule SpandexEcto.TelemetryAdapter do result: wrap_result(metadata.result) } - EctoLogger.trace(log_entry, "#{repo_name}_database") + EctoLogger.trace(log_entry, "#{repo_name}_database", config) end def handle_event(event_name, measurements, log_entry, config) when is_list(event_name) do From 54b68a951a1dafa2defad78ff3ed5524ae6ee1bf Mon Sep 17 00:00:00 2001 From: Kamil Kowalski Date: Sun, 7 Feb 2021 13:27:23 +0100 Subject: [PATCH 2/4] Improve README * Make Ecto 3 config the default * Describe how to override config in :telemetry.attach/4 --- README.md | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 12a5aa5..8699053 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Hex pm](http://img.shields.io/hexpm/v/spandex_ecto.svg?style=flat)](https://hex.pm/packages/spandex_ecto) [![SourceLevel](https://sourcelevel.io/github/spandex-project/spandex_ecto.svg)](https://sourcelevel.io/github/spandex-project/spandex_ecto) -Tools for integrating Ecto with Spandex +Tools for integrating Ecto with Spandex. ## Limitations @@ -30,30 +30,46 @@ end ## Configuration +Configure `SpandexEcto` globally in your application config: + ```elixir +# config/config.exs + config :spandex_ecto, SpandexEcto.EctoLogger, service: :ecto, # Optional tracer: MyApp.Tracer, # Required ``` -### For Ecto 2 +Then attach it to your repository's telemetry events: ```elixir -# Be aware that this is a *compile* time configuration. As such, if you change this you -# may need to `mix compile --force` and/or `mix deps.compile --force ecto` -config :my_app, MyApp.Repo, - loggers: [{Ecto.LogEntry, :log, [:info]}, {SpandexEcto.EctoLogger, :trace, ["database_name"]}] +# lib/my_app/application.ex +:telemetry.attach( + "spandex-query-tracer", + # this should match your repo's telemetry prefix + [:my_app, :repo, :query], + &SpandexEcto.TelemetryAdapter.handle_event/4, + # this config will override the global config + tracer: MyApp.OtherTracer +) ``` -### For Ecto 3 +> NOTE: **If you are upgrading from Ecto 2**, make sure to **remove** the `loggers` +> entry from your configuration after adding `:telemetry.attach/4`. + +### Ecto 2 + +To integrate `SpandexEcto` with pre-`:telemetry` versions of Ecto you need to add `SpandexEcto.EctoLogger` as a logger to your repository. + +Be aware that this is a *compile* time configuration. As such, if you change this you may need to `mix compile --force` and/or `mix deps.compile --force ecto`. ```elixir -# in application.ex -# If your repo is called `MyApp.Repo`, use `[:my_app, :repo, :query]` -# If your repo is called `Foo.Bar.Baz`, use `[:foo, :bar, :baz, :query]` -:ok = :telemetry.attach("spandex-query-tracer-repo_name", [:my_app, :repo, :query], &SpandexEcto.TelemetryAdapter.handle_event/4, nil) -``` +# config/config.exs -> NOTE: **If you are upgrading from Ecto 2**, make sure to **remove** the `loggers` -> entry from your configuration after adding the `:telemetry.attach`. +config :my_app, MyApp.Repo, + loggers: [ + {Ecto.LogEntry, :log, [:info]}, + {SpandexEcto.EctoLogger, :trace, ["database_name"]} + ] +``` From 79cc4fe31891ace9841c453211cec939a0279467 Mon Sep 17 00:00:00 2001 From: Kamil Kowalski Date: Mon, 8 Feb 2021 09:44:18 +0100 Subject: [PATCH 3/4] Add config options documentation --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 8699053..4ed4ed2 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Then attach it to your repository's telemetry events: [:my_app, :repo, :query], &SpandexEcto.TelemetryAdapter.handle_event/4, # this config will override the global config + service: "main-db", tracer: MyApp.OtherTracer ) ``` @@ -58,6 +59,16 @@ Then attach it to your repository's telemetry events: > NOTE: **If you are upgrading from Ecto 2**, make sure to **remove** the `loggers` > entry from your configuration after adding `:telemetry.attach/4`. +### Options + +The following configuration options are supported: + +|Option|Description|Default| +|-|-|-| +|`tracer`|Tracer instance to use for reporting traces (*required*)|| +|`service`|Service name for Ecto traces|`ecto`| +|`truncate`|Maximum length of a query (excess will be truncated)|5000| + ### Ecto 2 To integrate `SpandexEcto` with pre-`:telemetry` versions of Ecto you need to add `SpandexEcto.EctoLogger` as a logger to your repository. From 199430e26ce41dd3cbbddc382f6291140b7ca75e Mon Sep 17 00:00:00 2001 From: Kamil Kowalski Date: Sun, 4 Jul 2021 09:31:02 +0200 Subject: [PATCH 4/4] Improve configuration docs --- README.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4ed4ed2..c2f5709 100644 --- a/README.md +++ b/README.md @@ -45,14 +45,27 @@ Then attach it to your repository's telemetry events: ```elixir # lib/my_app/application.ex -:telemetry.attach( +:ok = :telemetry.attach( "spandex-query-tracer", # this should match your repo's telemetry prefix [:my_app, :repo, :query], &SpandexEcto.TelemetryAdapter.handle_event/4, + nil +) +``` + +You can override the global configuration by passing overrides to `:telemetry.attach/4` (useful for projects with multiple Ecto repos): + +```elixir +# lib/my_app/application.ex + +:ok = :telemetry.attach( + "spandex-query-tracer-other-repo", + [:my_app, :other_repo, :query], + &SpandexEcto.TelemetryAdapter.handle_event/4, # this config will override the global config - service: "main-db", - tracer: MyApp.OtherTracer + service: :other_db, + tracer: MyApp.OtherRepoTracer ) ```