Reputation: 13795
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.
Upvotes: 8
Views: 924
Reputation: 52997
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
.
Upvotes: 8
Reputation: 222398
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.
Upvotes: 7