Archive for category Elixir

How to Change Elixir Log Levels for a Running Application

Logging is essential to any production system, but it’s also terribly easy to make your logs so noisy they become worthless. That’s why I’m a big fan of carefully specifying the criticality level of everything I log. Not only does it allow us to easily search the logs for potential problems, it allows us to quiet our logs down and raise the signal to noise ratio. In production, I don’t want or need debug level logging… until I do. Thankfully, Elixir makes it easy for us to change what level we’re logging at on the fly.

Let’s say we have a Phoenix website and we want to create a log entry every time we serve the site’s index while we’re developing, but not when we go to production.

require Logger

defmodule LogBlogWeb.PageController do
  use LogBlogWeb, :controller

  def index(conn, _params) do
    Logger.log(:debug, "hello there!")
    render conn, "index.html"
  end
end

By default, a Pheonix app runs with debug logging under the dev configuration and info under the prod config.

# config/dev.exs
config :logger, :console, format: "[$level] $message\n"

# config/prod.exs
config :logger, level: :info

This is great! It’s exactly the behavior we want in our production system. At least, that is, until we need to see the debug information because something is wrong in production.

Or, we would be if it wasn’t for the Erlang VM and iex.

In order to be able to connect to our running system, we need to start the process with a node name. Instead of starting our website with mix phx.server like we normally might, we start it with elixir instead.

MIX_ENV=prod PORT=4000 elixir --name myapp@localhost -S mix phx.server

Now that we have a name for our process, we can use iex to connect to the running process via the --remsh option in a separate shell.

iex --sname debug --remsh "myapp@localhost"

Erlang/OTP 20 [erts-9.2]  [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.5.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(myapp@localhost)1>

Finally, now that we have an interactive session established, we can change the Logger configuration to output the debug logs.

iex(myapp@localhost)1> Logger.configure(level: :debug)
:ok

If we check the logs now, we’ll see our debug message.

08:56:34.205 [info] GET /
08:56:34.218 [debug] Processing with LogBlogWeb.PageController.index/2
  Parameters: %{}
  Pipelines: [:browser]
08:56:34.218 [debug] hello there!
08:56:34.227 [info] Sent 200 in 22ms

When we’re done gathering the extra information, we can simply set the level back to info.

iex(myapp@localhost)2> Logger.configure(level: :info)
:ok

And there you have it folks. That’s how you change the log level of your Elixir application without ever taking it offline.

, ,

3 Comments