Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F114205
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/tesla/middleware/telemetry.ex b/lib/tesla/middleware/telemetry.ex
index e633a51..e282225 100644
--- a/lib/tesla/middleware/telemetry.ex
+++ b/lib/tesla/middleware/telemetry.ex
@@ -1,105 +1,113 @@
if Code.ensure_loaded?(:telemetry) do
defmodule Tesla.Middleware.Telemetry do
@behaviour Tesla.Middleware
@moduledoc """
Emits events using the `:telemetry` library to expose instrumentation.
### Example usage
```
defmodule MyClient do
use Tesla
plug Tesla.Middleware.Telemetry, prefix: [:my_client]
end
:telemetry.attach("my-tesla-telemetry", [:my_client, :tesla, :request, stop], fn event, measurements, meta, config ->
# Do something with the event
end)
```
### Options
* `:event_prefix` - a list of atoms to prefix to the telemetry event. Defaults to `[]`
## Telemetry Events
* `[:tesla, :request, :start]` - emitted at the beginning of the request.
* Measurement: `%{time: System.monotonic_time}`
* Metadata: `%{env: Tesla.Env.t}`
* `[:tesla, :request, :stop]` - emitted at the end of the request.
* Measurement: `%{duration: native_time}`
* Metadata: `%{env: Tesla.Env.t}`
* `[:tesla, :request, :error]` - emitted at the end of the request when there is an error.
* Measurement: `%{duration: native_time}`
* Metadata: `%{env: Tesla.Env.t, reason: term}`
* `[:tesla, :request, :exception]` - emitted at the end of the request when an exception is raised.
* Measurement: `%{duration: native_time}`
* Metadata: `%{env: Tesla.Env.t, exception: Exception.t, stacktrace: Exception.stacktrace}`
+ * `[:tesla, :request]` - This event is emitted for backwards compatibility only and should be considered deprecated.
+ This event can be disabled by setting `config :tesla, Tesla.Middleware.Telemetry, disable_legacy_event: true` in your config.
Please check the [telemetry](https://hexdocs.pm/telemetry/) for the further usage.
"""
+ @disable_legacy_event Application.get_env(:tesla, Tesla.Middleware.Telemetry,
+ disable_legacy_event: false
+ )[:disable_legacy_event]
+
@doc false
def call(env, next, opts) do
prefix = Keyword.get(opts, :event_prefix, [])
start_time = System.monotonic_time()
emit_start(env, start_time, prefix)
result =
try do
Tesla.run(env, next)
rescue
e ->
stacktrace = System.stacktrace()
metadata = %{env: env, exception: e, stacktrace: stacktrace}
:telemetry.execute(
prefix ++ [:tesla, :request, :exception],
%{duration: System.monotonic_time() - start_time},
metadata
)
reraise e, stacktrace
end
emit_stop(result, start_time, prefix, env)
result
end
defp emit_start(env, start_time, prefix) do
:telemetry.execute(prefix ++ [:tesla, :request, :start], %{time: start_time}, %{
env: env
})
end
defp emit_stop(result, start_time, prefix, req_env) do
duration = System.monotonic_time() - start_time
case result do
{:ok, env} ->
:telemetry.execute(
prefix ++ [:tesla, :request, :stop],
%{duration: duration},
%{env: env}
)
{:error, error} ->
:telemetry.execute(
prefix ++ [:tesla, :request, :error],
%{duration: duration},
%{env: req_env, reason: error}
)
end
- # retained for backwards compatibility - remove in 2.0
- :telemetry.execute([:tesla, :request], %{request_time: duration}, %{result: result})
+ if !@disable_legacy_event do
+ # retained for backwards compatibility - remove in 2.0
+ :telemetry.execute([:tesla, :request], %{request_time: duration}, %{result: result})
+ end
end
end
end
diff --git a/test/tesla/middleware/telemetry_test.exs b/test/tesla/middleware/telemetry_test.exs
index 2c2f339..6ab2d47 100644
--- a/test/tesla/middleware/telemetry_test.exs
+++ b/test/tesla/middleware/telemetry_test.exs
@@ -1,102 +1,116 @@
defmodule Tesla.Middleware.TelemetryTest do
use ExUnit.Case, async: true
defmodule Client do
use Tesla
plug Tesla.Middleware.Telemetry
adapter fn env ->
case env.url do
"/telemetry" -> {:ok, env}
"/telemetry_error" -> {:error, :econnrefused}
"/telemetry_exception" -> raise "some exception"
end
end
end
defmodule ClientWithOptions do
use Tesla
plug Tesla.Middleware.Telemetry, event_prefix: [:my_client]
adapter fn env ->
case env.url do
"/telemetry" -> {:ok, env}
end
end
end
setup do
Application.ensure_all_started(:telemetry)
on_exit(fn ->
:telemetry.list_handlers([])
|> Enum.each(&:telemetry.detach(&1.id))
end)
:ok
end
test "accepts options" do
:telemetry.attach("with_opts", [:my_client, :tesla, :request, :stop], &echo_event/4, %{
caller: self()
})
ClientWithOptions.get("/telemetry")
assert_receive {:event, [:my_client, :tesla, :request, :stop], %{duration: time},
%{env: %Tesla.Env{url: "/telemetry", method: :get}}}
end
test "with default options" do
:telemetry.attach("with_default_opts_start", [:tesla, :request, :start], &echo_event/4, %{
caller: self()
})
:telemetry.attach("with_default_opts_stop", [:tesla, :request, :stop], &echo_event/4, %{
caller: self()
})
+ :telemetry.attach("with_default_opts_legacy", [:tesla, :request, :stop], &echo_event/4, %{
+ caller: self()
+ })
+
Client.get("/telemetry")
assert_receive {:event, [:tesla, :request, :start], %{time: time},
%{env: %Tesla.Env{url: "/telemetry", method: :get}}}
assert_receive {:event, [:tesla, :request, :stop], %{duration: time},
%{env: %Tesla.Env{url: "/telemetry", method: :get}}}
end
+ test "legacy_event_emitted_by_default" do
+ :telemetry.attach("with_default_opts_legacy", [:tesla, :request], &echo_event/4, %{
+ caller: self()
+ })
+
+ Client.get("/telemetry")
+
+ assert_receive {:event, [:tesla, :request], %{request_time: time}, %{result: result}}
+ end
+
test "with an error returned" do
:telemetry.attach("with_error", [:tesla, :request, :error], &echo_event/4, %{caller: self()})
Client.get("/telemetry_error")
assert_receive {:event, [:tesla, :request, :error], %{duration: time},
%{
env: %Tesla.Env{url: "/telemetry_error", method: :get},
reason: :econnrefused
}}
end
test "with an exception raised" do
:telemetry.attach("with_exception", [:tesla, :request, :exception], &echo_event/4, %{
caller: self()
})
assert_raise RuntimeError, fn ->
Client.get("/telemetry_exception")
end
assert_receive {:event, [:tesla, :request, :exception], %{duration: time},
%{
env: %Tesla.Env{url: "/telemetry_exception", method: :get},
exception: kind,
stacktrace: stacktrace
}}
end
def echo_event(event, measurements, metadata, config) do
send(config.caller, {:event, event, measurements, metadata})
end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Nov 25, 10:56 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40104
Default Alt Text
(7 KB)
Attached To
Mode
R28 tesla
Attached
Detach File
Event Timeline
Log In to Comment