From 882d64cbfce52bacdb51d638151d36073f91805b Mon Sep 17 00:00:00 2001 From: Tomoki Sekiyama Date: Wed, 17 Aug 2022 17:47:36 +0900 Subject: [PATCH 1/2] Allow to configure whether to omit queue/run_query/decode spans By specifying the `query_only?` option to true, only parent query spans are sent, and child spans are omitted. This makes trace data size ~1/4. --- README.md | 11 ++++---- lib/spandex_ecto/ecto_logger.ex | 47 ++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 8d21c6b..8bf7a47 100644 --- a/README.md +++ b/README.md @@ -73,11 +73,12 @@ You can override the global configuration by passing overrides to `:telemetry.at 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 | +| 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 | +| `query_only?` | Whether to omit queue/run_query/decode timings | false | ### Ecto 2 diff --git a/lib/spandex_ecto/ecto_logger.ex b/lib/spandex_ecto/ecto_logger.ex index 3bc7612..34f5b19 100644 --- a/lib/spandex_ecto/ecto_logger.ex +++ b/lib/spandex_ecto/ecto_logger.ex @@ -21,6 +21,7 @@ defmodule SpandexEcto.EctoLogger do tracer = config[:tracer] || raise "tracer is a required option for #{inspect(__MODULE__)}" service = config[:service] || :ecto truncate = config[:truncate] || 5000 + query_only? = config[:query_only?] if tracer.current_trace_id() do now = :os.system_time(:nano_seconds) @@ -58,34 +59,36 @@ defmodule SpandexEcto.EctoLogger do report_error(tracer, log_entry) - if queue_time != 0 do - tracer.start_span("queue") - tracer.update_span(service: service, start: start, completion_time: start + queue_time) - tracer.finish_span() - end + unless query_only? do + if queue_time != 0 do + tracer.start_span("queue") + tracer.update_span(service: service, start: start, completion_time: start + queue_time) + tracer.finish_span() + end - if query_time != 0 do - tracer.start_span("run_query") + if query_time != 0 do + tracer.start_span("run_query") - tracer.update_span( - service: service, - start: start + queue_time, - completion_time: start + queue_time + query_time - ) + tracer.update_span( + service: service, + start: start + queue_time, + completion_time: start + queue_time + query_time + ) - tracer.finish_span() - end + tracer.finish_span() + end - if decoding_time != 0 do - tracer.start_span("decode") + if decoding_time != 0 do + tracer.start_span("decode") - tracer.update_span( - service: service, - start: start + queue_time + query_time, - completion_time: now - ) + tracer.update_span( + service: service, + start: start + queue_time + query_time, + completion_time: now + ) - tracer.finish_span() + tracer.finish_span() + end end tracer.finish_span() From 9d574a46824f73d4884f0c8a7057cd28aa1c4c51 Mon Sep 17 00:00:00 2001 From: Tomoki Sekiyama Date: Wed, 17 Aug 2022 19:50:04 +0900 Subject: [PATCH 2/2] Allow to specify a default function to generate span's resource from a query Instead of adding `telemetry_options` to every query, this allows to provide a custom function to convert a query to span's resource. It is useful to group queries by target table names, for example. --- README.md | 16 ++++++++++------ lib/spandex_ecto/ecto_logger.ex | 3 ++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8bf7a47..53b78d4 100644 --- a/README.md +++ b/README.md @@ -73,12 +73,13 @@ You can override the global configuration by passing overrides to `:telemetry.at 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 | -| `query_only?` | Whether to omit queue/run_query/decode timings | false | +| 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 | +| `query_only?` | Whether to omit queue/run_query/decode timings | false | +| `resource_fun` | The function to convert a query to span's resource | & &1 | ### Ecto 2 @@ -109,3 +110,6 @@ of almost all of `Ecto.Repo`'s repository functions. Repo.all(query, telemetry_options: [spandex_resource: "users-with-addresses"]) Repo.get!(User, id, telemetry_options: [spandex_resource: "get-user"]) ``` + +Or, you can provide a function to to convert a query to the span's resource to the `resource_fun` option. +This is applied only the query doesn't have the `spandex_resource` telemetry option. diff --git a/lib/spandex_ecto/ecto_logger.ex b/lib/spandex_ecto/ecto_logger.ex index 34f5b19..c669406 100644 --- a/lib/spandex_ecto/ecto_logger.ex +++ b/lib/spandex_ecto/ecto_logger.ex @@ -22,6 +22,7 @@ defmodule SpandexEcto.EctoLogger do service = config[:service] || :ecto truncate = config[:truncate] || 5000 query_only? = config[:query_only?] + resource_fun = config[:resource_fun] || (& &1) if tracer.current_trace_id() do now = :os.system_time(:nano_seconds) @@ -32,7 +33,7 @@ defmodule SpandexEcto.EctoLogger do |> String.slice(0, truncate) num_rows = num_rows(log_entry) - resource = log_entry[:resource] || query + resource = log_entry[:resource] || resource_fun.(query) queue_time = get_time(log_entry, :queue_time) query_time = get_time(log_entry, :query_time)