I have a /ping
route that gets called a lot in production by the load balancer and kubernetes health checks. I'd like to set the log level of Plug.Logger
to :debug
just for that one route.
defmodule Web.Endpoint do
...
forward "/ping", Web.HealthCheck
...
end
defmodule Web.HealthCheck do
use Plug.Router
plug :match
plug :dispatch
get "/" do
send_resp(conn, 200, "ok")
end
end
I've not found a way to modify or remove an existing plug. I tried adding plug Plug.Logger, log: :debug
to Web.HealthCheck, but then I just get the route logged twice at different levels
[info] GET /ping
[debug] GET /ping
I've found a way to disable logging entirely for a specific route by removing plug Plug.Logger
from endpoint.ex
and manually adding back as needed https://elixirforum.com/t/disable-logging-on-specific-route/622, but then I have to be careful to remember to make sure logging is enabled for every new route I add, and really I'd prefer just to have the /ping
route set to debug so it can log in dev as needed, but won't be so spammy in production.
In more recent versions of Phoenix it looks like that specific log is now produced by Phoenix.Logger
in response to telemetry events emitted by Plug.Telemetry
. Suppressing specific routes can be done in very much the same fashion as with Plug.Logger
. Either create a separate endpoint / pipeline that does not include telemetry at all, or provide a custom implementation of the plug that alters the log level for certain paths:
defmodule MyWeb.Plugs.Telemetry do
@behaviour Plug
@impl true
def init(opts), do: Plug.Telemetry.init(opts)
@impl true
def call(%{path_info: ["ping"]} = conn, {start_event, stop_event, opts}) do
Plug.Telemetry.call(conn, {start_event, stop_event, Keyword.put(opts, :log, :debug)})
end
def call(conn, args), do: Plug.Telemetry.call(conn, args)
end
and then replace
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
with
plug MyWeb.Plugs.Telemetry, event_prefix: [:phoenix, :endpoint]
in your endpoint.ex
.
You can define a plug that calls Plug.Logger
with a different level for different paths.
defmodule MyApp.Logger do
def init(_opts), do: {}
def call(%{path_info: ["ping"]} = conn, _opts) do
Plug.Logger.call(conn, :error)
end
def call(conn, _opts) do
Plug.Logger.call(conn, :info)
end
end
Now replace plug Plug.Logger
with plug MyApp.Logger
in your Endpoint
module. All requests to /ping
will now log at :error
level while everything else will log at info
level.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With