Server Timing Response Headers for Elixir / Phoenix
Bring Phoenix server-side performance metrics plug_server_timing
package. Production Safeâ„¢.
Metrics are collected from the scout_apm package. A Scout account is not required.
Browser Support
- Chrome 65+ (Chrome 64 uses an old format of the server timing headers. This isn't supported by the gem).
- Firefox 59+
- Opera 52+
Installation
To install and use PlugServerTiming
, add it as a dependency in your Mixfile:
# mix.exs
def deps do
[
# ...
+ {:plug_server_timing, "~> 0.0.2"}
]
end
Add PlugServerTiming.Plug
to your Plug pipeline:
# lib/my_app_web/router.ex
defmodule MyAppWeb.Router do
pipeline :browser do
# ...
+ plug PlugServerTiming.Plug
end
end
Instrumentation
Performance metrics are collected via the scout_apm
gem. There's just a couple of steps to instrument your app.
Instrument controllers:
# lib/my_app_web.ex
defmodule MyAppWeb do
# ...
def controller do
quote do
use Phoenix.Controller, namespace: MyAppWeb
+ use ScoutApm.Instrumentation
# ...
end
end
end
Instrument Ecto queries:
# config/dev.exs
+config :my_app, MyApp.Repo,
+ loggers: [{Ecto.LogEntry, :log, []}, {ScoutApm.Instruments.EctoLogger, :log, []}]
Instrument templates:
# config/dev.exs
+config :phoenix, :template_engines,
+ eex: ScoutApm.Instruments.EExEngine,
+ exs: ScoutApm.Instruments.ExsEngine
Additional instrumentation
To instrument HTTPoison, MongoDB Ecto, and more see the Scout docs.
Custom instrumentation
Collect performance data on additional function calls by adding custom instrumentation via scout_apm
. See the docs for instructions.
Security
If you'd like to conditionally include Server-Timing headers depending on authorization, the Plug can be included in a Plug.Builder
pipeline or you can directly use PlugServerTiming.Plug.register_before_send_headers/1
in an existing Plug
.
defmodule MyExistingAuthPlug do
@behaviour Plug
import Plug.Conn
def init(opts), do: opts
def call(conn, _opts) do
case AuthModule.verify_auth(conn) do
{:ok, :admin} ->
PlugServerTiming.Plug.register_before_send_headers(conn)
{:ok, :user} ->
conn
{:error, _} ->
conn
|> put_status(:unauthorized)
|> halt()
end
end
end
Overhead
The scout_apm
package, a dependency of plug_server_timing
, applies low overhead instrumentation designed for production use.
Thanks!
Special thank you goes to @OleMchls for writing up https://blog.dnsimple.com/2018/02/server-timing-with-phoenix/ and inspiring this package