-
Notifications
You must be signed in to change notification settings - Fork 353
Add :telemetry_prefix option to Tesla.Middleware.Telemetry #390
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,34 @@ if Code.ensure_loaded?(:telemetry) do | |
end) | ||
``` | ||
|
||
## Options | ||
- `:telemetry_prefix` - replaces default `[:tesla]` with desired Telemetry event prefix (see below) | ||
|
||
## Custom Telemetry Prefix | ||
|
||
All events will use a `:telemetry_prefix` which defaults to `[:tesla]`. | ||
|
||
You can customize events by providing your own `:telemetry_prefix` locally: | ||
|
||
``` | ||
defmodule MyClient do | ||
use Tesla | ||
|
||
plug Tesla.Middleware.Telemetry, telemetry_prefix: [:custom, :prefix] | ||
|
||
end | ||
|
||
:telemetry.attach("my-tesla-telemetry", [:custom, :prefix, :request, :stop], fn event, measurements, meta, config -> | ||
# Do something with the event | ||
end) | ||
``` | ||
|
||
You can configure `:telemetry_prefix` globally in your config, but if set the `:telemetry_prefix` option will override: | ||
|
||
``` | ||
config :tesla, Tesla.Middleware.Telemetry, telemetry_prefix: [:custom, :prefix] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is a good idea - it would override this all clients from all dependencies. Since the use case comes from building API clients as packages I think it would be better to hide tesla from end user and use this instead. # config/config.exs
config :myclient, telemetry_prefix: [...]
# myclient.ex
defmodule Myclient do
use Tesla
@compile_config Application.compile_env(:myclient, :telemetry_prefix, [])
plug Tesla.Middleware.Telemetry, prefix: Keyword.get(@compile_config, :prefix, [:myclient])
# ...
end
# or top provide runtime configuration
defmodule Myclient do
def new do
config = Application.get_env(:myclient, :telemetry_prefix, [])
middleware = [
# ...
{Tesla.Middleware.Telemetry, prefix: Keyword.get(@compile_config, :prefix, [:myclient])}
]
Tesla.client(middleware, adapter)
end
end There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense. I kept going back and forth on globalizing. Will remove and update. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just updated. Let me know if that works. |
||
``` | ||
|
||
## Telemetry Events | ||
|
||
* `[:tesla, :request, :start]` - emitted at the beginning of the request. | ||
|
@@ -46,11 +74,14 @@ if Code.ensure_loaded?(:telemetry) do | |
|
||
@behaviour Tesla.Middleware | ||
|
||
@default_telemetry_prefix [:tesla] | ||
|
||
@impl Tesla.Middleware | ||
def call(env, next, _opts) do | ||
def call(env, next, opts) do | ||
start_time = System.monotonic_time() | ||
prefix = telemetry_prefix(opts) | ||
|
||
emit_start(%{env: env}) | ||
emit_start(%{env: env}, prefix) | ||
|
||
try do | ||
Tesla.run(env, next) | ||
|
@@ -59,62 +90,57 @@ if Code.ensure_loaded?(:telemetry) do | |
stacktrace = System.stacktrace() | ||
duration = System.monotonic_time() - start_time | ||
|
||
emit_exception(duration, %{kind: kind, reason: reason, stacktrace: stacktrace}) | ||
emit_exception(duration, %{kind: kind, reason: reason, stacktrace: stacktrace}, prefix) | ||
|
||
:erlang.raise(kind, reason, stacktrace) | ||
else | ||
{:ok, env} = result -> | ||
duration = System.monotonic_time() - start_time | ||
|
||
emit_stop(duration, %{env: env}) | ||
emit_legacy_event(duration, result) | ||
emit_stop(duration, %{env: env}, prefix) | ||
emit_legacy_event(duration, result, prefix) | ||
|
||
result | ||
|
||
{:error, reason} = result -> | ||
duration = System.monotonic_time() - start_time | ||
|
||
emit_stop(duration, %{env: env, error: reason}) | ||
emit_legacy_event(duration, result) | ||
emit_stop(duration, %{env: env, error: reason}, prefix) | ||
emit_legacy_event(duration, result, prefix) | ||
|
||
result | ||
end | ||
end | ||
|
||
defp emit_start(metadata) do | ||
:telemetry.execute( | ||
[:tesla, :request, :start], | ||
%{system_time: System.system_time()}, | ||
metadata | ||
) | ||
defp config, do: Application.get_env(:tesla, __MODULE__, []) | ||
|
||
defp telemetry_prefix(opts) do | ||
with nil <- Keyword.get(opts, :telemetry_prefix) do | ||
Keyword.get(config(), :telemetry_prefix, @default_telemetry_prefix) | ||
end | ||
end | ||
|
||
defp emit_start(metadata, prefix) do | ||
event = prefix ++ [:request, :start] | ||
:telemetry.execute(event, %{system_time: System.system_time()}, metadata) | ||
end | ||
|
||
defp emit_stop(duration, metadata) do | ||
:telemetry.execute( | ||
[:tesla, :request, :stop], | ||
%{duration: duration}, | ||
metadata | ||
) | ||
defp emit_stop(duration, metadata, prefix) do | ||
event = prefix ++ [:request, :stop] | ||
:telemetry.execute(event, %{duration: duration}, metadata) | ||
end | ||
|
||
defp emit_legacy_event(duration, result) do | ||
defp emit_legacy_event(duration, result, prefix) do | ||
if !@disable_legacy_event do | ||
event = prefix ++ [:request] | ||
duration_µs = System.convert_time_unit(duration, :native, :microsecond) | ||
|
||
:telemetry.execute( | ||
[:tesla, :request], | ||
%{request_time: duration_µs}, | ||
%{result: result} | ||
) | ||
:telemetry.execute(event, %{request_time: duration_µs}, %{result: result}) | ||
end | ||
end | ||
|
||
defp emit_exception(duration, metadata) do | ||
:telemetry.execute( | ||
[:tesla, :request, :exception], | ||
%{duration: duration}, | ||
metadata | ||
) | ||
defp emit_exception(duration, metadata, prefix) do | ||
event = prefix ++ [:request, :exception] | ||
:telemetry.execute(event, %{duration: duration}, metadata) | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this option is passed directly to telemetry middleware I don't think we need to include the
telemetry_
prefix in the prefix name (🥁)I'd go with just
:prefix
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. Will update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just updated. Let me know if that works.