diff --git a/README.md b/README.md index 12a5aa5..c2f5709 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,70 @@ 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 +:ok = :telemetry.attach( + "spandex-query-tracer", + # this should match your repo's telemetry prefix + [:my_app, :repo, :query], + &SpandexEcto.TelemetryAdapter.handle_event/4, + nil +) ``` -### For Ecto 3 +You can override the global configuration by passing overrides to `:telemetry.attach/4` (useful for projects with multiple Ecto repos): ```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) +# 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: :other_db, + tracer: MyApp.OtherRepoTracer +) ``` > NOTE: **If you are upgrading from Ecto 2**, make sure to **remove** the `loggers` -> entry from your configuration after adding the `:telemetry.attach`. +> 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. + +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 +# config/config.exs + +config :my_app, MyApp.Repo, + loggers: [ + {Ecto.LogEntry, :log, [:info]}, + {SpandexEcto.EctoLogger, :trace, ["database_name"]} + ] +``` 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