New Relixir 
Instrument your Phoenix and Plug applications with New Relic.
New Relixir currently supports instrumenting bare-bones Plug endpoints, Phoenix controllers and Ecto repositories, to record response times of web transactions and database queries.
Usage
The following instructions show how to add instrumentation with New Relixir to a hypothetical
Phoenix application named MyApp.
Add
new_relixirto your list of dependencies inmix.exs:# mix.exsdefmodule MyApp.Mixfile douse Mix.Project# ...defp deps do[{:new_relixir, "~> 0.4"}]endendIf you use the
applicationskey (only for apps created before Elixir 1.4) indef application do, then you will also need to addnew_relixirto it:def application do[mod: {MyApp, []},applications: [:new_relixir]]endIf your app does not have an
applicationskey, skip this instruction.Add your New Relic application name and license key to
config/config.exs. You may wish to use environment variables to keep production, staging, and development environments separate:# config/config.exsconfig :new_relixir,application_name: System.get_env("NEWRELIC_APP_NAME"),license_key: System.get_env("NEWRELIC_LICENSE_KEY")Add
NewRelixir.Instrumenters.Phoenixto the list of instrumenters in yourEndpointconfiguration:# config/config.exsconfig :my_app, MyAppWeb.Endpoint,instrumenters: [NewRelixir.Instrumenters.Phoenix],# ...If your app also uses
Ecto, define a module to wrap your repository's methods with New Relic instrumentation:# lib/my_app/repo.exdefmodule MyApp.Repo douse Ecto.Repo, otp_app: :my_appdefmodule NewRelic douse NewRelixir.Plug.Repo, repo: MyApp.RepoendendNow
MyApp.Repo.NewReliccan be used as a substitute forMyApp.Repo. It will dispatch and instrument the response time for allRepocalls.If you've defined custom functions on your
Repo, you will need to define them on your wrapper module as well. In the wrapper module, simply call your repository's original function inside a closure that you pass toinstrument_db:# lib/my_app/repo.exdefmodule MyApp.Repo douse Ecto.Repo, otp_app: :my_appdef my_custom_operation(queryable, opts \\ []) do# ...enddefmodule NewRelic douse NewRelixir.Plug.Repo, repo: MyApp.Repodef my_custom_operation(queryable, opts \\ []) doinstrument_db(:my_custom_operation, queryable, opts, fn() ->MyApp.Repo.my_custom_operation(queryable, opts)end)endendendWhen using the wrapper module's
my_custom_operation, the time it takes to callMyApp.Repo.my_custom_operation/2will be recorded to New Relic.
Error Reporting
If you want to report all errors to new relic
Configure your router
# lib/my_app/router.ex
defmodule MyApp.Router do
use MyApp, :router
use NewRelixir.Plug.Exception
...
end
If you want to report caught errors
try do
raise "oops"
catch
kind, reason ->
transaction =
case NewRelixir.CurrentTransaction.get() do
{:ok, transaction} -> transaction
{:error, _} -> NewRelixir.CurrentTransaction.set(conn.request_path)
end
NewRelixir.Transaction.record_error(transaction, {kind, reason})
# You may want to re-raise this exception
:erlang.raise(kind, reason, System.stacktrace)
end
Upgrading from 0.3.x
Remove
NewRelixir.Plug.Phoenixfrom your Plug pipeline and all further references to that module.Add
NewRelixir.Instrumenters.Phoenixto the list of instrumenters in yourEndpointconfiguration. See more in usage.Passing a
connto the functions of yourRepowrapper is no longer required, calls to the wrapper can now be made the same way as calls to the originalRepo:# web/controllers/users.exdefmodule MyApp.UserController douse MyApp.Web, :controllerdef index(conn, _params) do# Beforeusers = Repo.all(User, conn: conn)# Nowusers = Repo.all(User)endend
Copyright
Copyright © 2016 The RealReal, Inc.
Distributed under the MIT License.