This repository has been archived.
📚 Archived Status: This repository is no longer actively maintained or updated. It is being preserved for historical reference or potential future use. Issues, pull requests, and contributions are no longer accepted.
🙏 Thank You: We appreciate the contributions and engagement from the community during the active phase of this project.
Thank you!
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.
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.exsdefmoduleMyApp.MixfiledouseMix.Project# ...defpdepsdo[{:new_relixir,"~> 0.4"}]endend
If you use the
applicationskey (only for apps created before Elixir 1.4) indef application do, then you will also need to addnew_relixirto it:defapplicationdo[mod: {MyApp,[]},applications: [:new_relixir]]end
If 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.exdefmoduleMyApp.RepodouseEcto.Repo,otp_app: :my_appdefmoduleNewRelicdouseNewRelixir.Plug.Repo,repo: MyApp.Repoendend
Now
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.exdefmoduleMyApp.RepodouseEcto.Repo,otp_app: :my_appdefmy_custom_operation(queryable,opts\\[])do# ...enddefmoduleNewRelicdouseNewRelixir.Plug.Repo,repo: MyApp.Repodefmy_custom_operation(queryable,opts\\[])doinstrument_db(:my_custom_operation,queryable,opts,fn()->MyApp.Repo.my_custom_operation(queryable,opts)end)endendend
When using the wrapper module's
my_custom_operation, the time it takes to callMyApp.Repo.my_custom_operation/2will be recorded to New Relic.
If you want to report all errors to new relic
Configure your router
# lib/my_app/router.exdefmoduleMyApp.RouterdouseMyApp,:routeruseNewRelixir.Plug.Exception...endIf you want to report caught errors
trydoraise"oops"catchkind,reason->transaction=caseNewRelixir.CurrentTransaction.get()do{:ok,transaction}->transaction{:error,_}->NewRelixir.CurrentTransaction.set(conn.request_path)endNewRelixir.Transaction.record_error(transaction,{kind,reason})# You may want to re-raise this exception:erlang.raise(kind,reason,System.stacktrace)endRemove
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.exdefmoduleMyApp.UserControllerdouseMyApp.Web,:controllerdefindex(conn,_params)do# Beforeusers=Repo.all(User,conn: conn)# Nowusers=Repo.all(User)endend
Copyright © 2016 The RealReal, Inc.
Distributed under the MIT License.