diff --git a/README.md b/README.md index 1430ec5..3edbd59 100644 --- a/README.md +++ b/README.md @@ -4,26 +4,7 @@ En Elixir based built-in error tracking solution. ## Configuration -Set up the repository: - -```elixir -config :error_tracker, - repo: MyApp.Repo -``` - -And you are ready to go! - -By default Phoenix and Oban integrations will start registering exceptions. - -If you want to also catch exceptions before your Phoenix Router (in plugs used -on your Endpoint) or your application just use `Plug` but not `Phoenix`, you can -attach to those errors with: - -```elixir -defmodule MyApp.Endpoint do - use ErrorTracker.Integrations.Plug -end -``` +Take a look at the [Getting Started](/guides/Getting%20Started.md) guide. ## Development @@ -61,5 +42,3 @@ To do so you can execute this task in a separate terminal: ``` mix assets.watch ``` - - diff --git a/dev.exs b/dev.exs index 55ea57c..08c33b1 100644 --- a/dev.exs +++ b/dev.exs @@ -43,7 +43,7 @@ Application.put_env(:error_tracker, ErrorTrackerDevWeb.Endpoint, # Setup up the ErrorTracker configuration Application.put_env(:error_tracker, :repo, ErrorTrackerDev.Repo) -Application.put_env(:error_tracker, :application, :error_tracker_dev) +Application.put_env(:error_tracker, :otp_app, :error_tracker_dev) Application.put_env(:error_tracker, :prefix, "private") defmodule ErrorTrackerDevWeb.PageController do @@ -54,7 +54,7 @@ defmodule ErrorTrackerDevWeb.PageController do def call(conn, :index) do content(conn, """

ErrorTracker Dev Server

-
Open ErrorTracker
+
Open ErrorTracker
Generate Plug exception
Generate Router 404
Raise NoRouteError from a controller
@@ -108,7 +108,9 @@ defmodule ErrorTrackerDevWeb.Router do get "/exception", ErrorTrackerDevWeb.PageController, :exception get "/exit", ErrorTrackerDevWeb.PageController, :exit - error_tracker_dashboard("/errors") + scope "/dev" do + error_tracker_dashboard("/errors") + end end end @@ -143,8 +145,8 @@ end defmodule Migration0 do use Ecto.Migration - def up, do: ErrorTracker.Migrations.up(prefix: "private") - def down, do: ErrorTracker.Migrations.down(prefix: "private") + def up, do: ErrorTracker.Migration.up(prefix: "private") + def down, do: ErrorTracker.Migration.down(prefix: "private") end Application.put_env(:phoenix, :serve_endpoints, true) diff --git a/guides/Getting Started.md b/guides/Getting Started.md new file mode 100644 index 0000000..d6c531d --- /dev/null +++ b/guides/Getting Started.md @@ -0,0 +1,128 @@ +# Getting Started + +This guide is an introduction to the ErrorTracker, an Elixir based built-in error tracking solution. The ErrorTracker provides a basic and free error-tracking solution integrated in your own application. It is designed to be easy to install and easy to use so you can integrate it in your existing project with minimal changes. The only requirement is a relational database in which errors will be tracked. + +In this guide we will learn how to install the ErrorTracker in an Elixir project so you can start reporting errors as soon as possible. We will also cover more advanced topics such as how to report custom errors and how to add extra context to reported errors. + +**This guide requires you to have setup Ecto with PostgreSQL beforehand.** + +## Installing the ErrorTracking as a dependency + +The first step add the ErrorTracker to your application is to declare the package as a dependency in your `mix.exs` file: + +```elixir +# mix.exs +defp deps do + [ + {:error_tracker, "~> 1.0"} + ] +end +``` + +Once the ErrorTracker is declared as a dependency of your application, you can install it with the following command: + +```bash +mix deps.get +``` + +## Configuring the ErrorTracker + +The ErrorTracker needs a few configuration options to work. This configuration should be added in your `config/config.exs` file: + +```elixir +config :error_tracker, + repo: MyApp.Repo, + otp_app: :my_app +``` + +The `:repo` option specifies the repository that will be used by the ErrorTracker. You can use your regular application repository, or a different one if you prefer to keep errors in a different database. + +The `:otp_app` option specifies your application name. When an error happens the ErrorTracker will use this information to understand which parts of the stacktrace belong to your application and which parts belong to third party dependencies. This allows you to filter in-app vs third-party frames when viewing errors. + +## Setting up the database + +Since the ErrorTracker stores errors in the database you must create a database migration to add the required tables: + +``` +mix ecto.gen.migration add_error_tracker +``` + +Open the generated migration and call the `up` and `down` functions on `ErrorTracker.Migration`: + +```elixir +defmodule MyApp.Repo.Migrations.AddErrorTracker do + use Ecto.Migration + + def up, do: ErrorTracker.Migration.up() + def down, do: ErrorTracker.Migration.down() +end +``` + +You can run the migration and perform the database changes with the following command: + +```bash +mix ecto.migrate +``` + +For more information about how to handle migrations take a look at the `ErrorTracker.Migration` module docs. + +## Automatic error tracking + +At this point, the ErrorTracker is ready to track errors. It will automatically start when your application boots and track errors that happen in your Phoenix controllers, Phoenix LiveViews and Oban jobs. The `ErrorTracker.Integrations.Phoenix` and `ErrorTracker.Integrations.Oban` provide detailed information about how this works. + +If your application uses Plug but not Phoenix, you will need to add the relevant integration in your `Plug.Builder` or `Plug.Router` module. + +```elixir +defmodule MyApp.Router do + use Plug.Router + use ErrorTracker.Integrations.Plug + + # Your code here +end +``` + +This is also required if you want to track errors that happen in your Phoenix endpoint, before the Phoenix router starts handling the request. Keep in mind that this won't be needed in most cases as endpoint errors are very infrequent. + +```elixir +defmodule MyApp.Endpoint do + use Phoenix.Endpoint + use ErrorTracker.Integrations.Plug + + # Your code here +end +``` + +You can learn more about this in the `ErrorTracker.Integrations.Plug` module documentation. + +## Error context + +The default integrations include some additional context when tracking errors. You can take a look at the relevant integration modules to see what is being tracked out of the box. + +In certain cases you may want to include some additional information when tracking errors. For example it may be useful to track the user ID that was using the application when an error happened. Fortunately, the ErrorTracker allows you to enrich the default context with custom information. + +The `ErrorTracker.set_context/1` function stores the given context in the current process so any errors that happen in that process (for example a Phoenix request or an Oban job) will include this given context along with the default integration context. + +```elixir +ErrorTracker.set_context(%{user_id: conn.assigns.current_user.id}) +``` + +## Manual error tracking + +If you want to report custom errors that fall outside the default integrations scope you may use `ErrorTracker.report/2`. This allows you to report an exception by yourself: + +```elixir +try do + # your code +catch + e -> + ErrorTracker.report(e, __STACKTRACE__) +end +``` + +You can also use `ErrorTracker.report/3` and set some custom context that will be included along with the reported error. + +## Web UI + +The ErrorTracker also provides a dashboard built with Phoenix LiveView that can be used to see and manage the recorded errors. + +This is completely optional and you can find more information about it in the `ErrorTracker.Web` module documentation. diff --git a/lib/error_tracker.ex b/lib/error_tracker.ex index aa83fb8..c84c0e6 100644 --- a/lib/error_tracker.ex +++ b/lib/error_tracker.ex @@ -1,6 +1,61 @@ defmodule ErrorTracker do @moduledoc """ En Elixir based built-in error tracking solution. + + The main objectives behind this project are: + + * Provide a basic free error tracking solution: because tracking errors on + your application should be a requirement to almost any project, and helps to + provide quality and maintenance to your project. + + * Be easy to use: by providing plug and play integrations, documentation and a + simple UI to manage your errors. + + * Be as minimalistic as possible: you just need a database to store errors and + an Phoenix application if you want to inspect them via web. That's all. + + ## Requirements + + ErrorTracker requires Elixir 1.15+, Ecto 3.11+, Phoenix LiveView 0.19+ and PostgreSQL + + ## Integrations + + We currently include integrations for what we consider the basic stack of + an application: Phoenix, Plug and Oban. + + However, we may continue working in adding support for more systems and + libraries in the future if there is enough interest by the community. + + If you want to manually report an error you can use the `ErrorTracker.report/3` function. + + ## Context + + Aside from the information abot each exception (kind, message, stacktrace...) + we also store contexts. + + Contexts are arbitrary maps that allow you to store extra information of an + exception to be able to reproduce it later. + + Each integration includes a default context with the useful information they + can gather, but aside from that you can also add your own information. You can + do this in a per-process way or in a per-call way (or both). + + **Per process** + + This allows you to set general context for the current process such as a Phoenix + request or an Oban job. For example you could include the following code in your + authentication Plug to automatically include the user ID on any error that is + tracked during the Phoenix request handling. + + ```elixir + ErrorTracker.set_context(%{user_id: conn.assigns.current_user.id}) + ``` + + **Per call** + + As we had seen before you can use `ErrorTracker.report/3` to manually report an + error. The third parameter of this function is optional and allows you to include + extra context that will be tracked along with that error. """ @typedoc """ @@ -11,6 +66,40 @@ defmodule ErrorTracker do alias ErrorTracker.Error alias ErrorTracker.Repo + @doc """ + Report a exception to be stored. + + Aside from the exception, it is expected to receive the stacktrace and, + optionally, a context map which will be merged with the current process + context. + + Keep in mind that errors that happen in Phoenix controllers, Phoenix live views + and Oban jobs are automatically reported. You will need this function only if you + want to report custom errors. + + ```elixir + try do + # your code + catch + e -> + ErrorTracker.report(e, __STACKTRACE__) + end + ``` + + ## Exceptions + + Exceptions passed can be in three different forms: + + * An exception struct: the module of the exception is stored alongside with + the exception message. + + * A `{kind, exception}` tuple in which the `exception` is an struct: it + behaves the same as when passing just the exception struct. + + * A `{kind, reason}` tuple: it stores the kind and the message itself casted + to strings, as it is useful for some errors like EXIT signals or custom error + messages. + """ def report(exception, stacktrace, given_context \\ %{}) do {kind, reason} = case exception do @@ -40,18 +129,42 @@ defmodule ErrorTracker do |> Repo.insert!() end + @doc """ + Marks an error as resolved. + + If an error is marked as resolved and it happens again, it will automatically + appear as unresolved again. + """ def resolve(error = %Error{status: :unresolved}) do changeset = Ecto.Changeset.change(error, status: :resolved) Repo.update(changeset) end + @doc """ + Marks an error as unresolved. + """ def unresolve(error = %Error{status: :resolved}) do changeset = Ecto.Changeset.change(error, status: :unresolved) Repo.update(changeset) end + @doc """ + Sets current process context. + + By default it will merge the current context with the new one received, taking + preference the new context's contents over the existsing ones if any key + matches. + + ## Depth of the context + + You can store context on more than one level of depth, but take into account + that the merge operation is performed on the first level. + + That means that any existing data on deep levels fot he current context will + be replaced if the first level key is received on the new contents. + """ @spec set_context(context()) :: context() def set_context(params) when is_map(params) do current_context = Process.get(:error_tracker_context, %{}) @@ -61,6 +174,9 @@ defmodule ErrorTracker do params end + @doc """ + Obtain the context of the current process. + """ @spec get_context() :: context() def get_context do Process.get(:error_tracker_context, %{}) diff --git a/lib/error_tracker/integrations/oban.ex b/lib/error_tracker/integrations/oban.ex index cc8e815..69644e7 100644 --- a/lib/error_tracker/integrations/oban.ex +++ b/lib/error_tracker/integrations/oban.ex @@ -1,11 +1,33 @@ defmodule ErrorTracker.Integrations.Oban do @moduledoc """ - The ErrorTracker integration with Oban. + Integration with Oban. - ## How it works + ## How to use it - It works using your application's Telemetry events, so you don't need to - modify anything on your application. + It is a plug and play integration: as long as you have Oban installed the + ErrorTracker will receive and store the errors as they are reported. + + ### How it works + + It works using Oban's Telemetry events, so you don't need to modify anything + on your application. + + ### Default context + + By default we store some context for you on errors generated in an Oban + process: + + * `job.id`: the unqiue ID of the job. + + * `job.worker`: the name of the worker module. + + * `job.queue`: the name of the queue in which the job was inserted. + + * `job.args`: the arguments of the job being executed. + + * `job.priority`: the priority of the job. + + * `job.attempt`: the number of attempts performed for the job. """ # https://hexdocs.pm/oban/Oban.Telemetry.html @@ -14,12 +36,19 @@ defmodule ErrorTracker.Integrations.Oban do [:oban, :job, :exception] ] + @doc """ + Attachs to Oban's Telemetry events if the library is detected. + + This function is usually called internally during the startup process so you + don't have to. + """ def attach do if Application.spec(:oban) do :telemetry.attach_many(__MODULE__, @events, &__MODULE__.handle_event/4, :no_config) end end + @doc false def handle_event([:oban, :job, :start], _measurements, metadata, :no_config) do %{job: job} = metadata diff --git a/lib/error_tracker/integrations/phoenix.ex b/lib/error_tracker/integrations/phoenix.ex index 272ed42..9da9134 100644 --- a/lib/error_tracker/integrations/phoenix.ex +++ b/lib/error_tracker/integrations/phoenix.ex @@ -1,11 +1,50 @@ defmodule ErrorTracker.Integrations.Phoenix do @moduledoc """ - The ErrorTracker integration with Phoenix applications. + Integration with Phoenix applications. - ## How it works + ## How to use it - It works using your application's Telemetry events, so you don't need to - modify anything on your application. + It is a plug and play integration: as long as you have Phoenix installed the + ErrorTracker will receive and store the errors as they are reported. + + It also collects the exceptions that raise on your LiveView modules. + + ### How it works + + It works using Phoenix's Telemetry events, so you don't need to modify + anything on your application. + + ### Errors on the Endpoint + + This integration only catches errors that raise after the requests hits your + Router. That means that an exception on a plug defined on your Endpoint will + not be reported. + + If you want to also catch those errors, we recommend you to set up the + `ErrorTracker.Integrations.Plug` integration too. + + ### Default context + + For errors that are reported when executing regular HTTP requests (the ones + that go to Controllers), the context added by default is the same that you + can find on the `ErrorTracker.Integrations.Plug` integration. + + As for exceptions generated in LiveView processes, we collect some special + information on the context: + + * `live_view.view`: the LiveView module itself, + + * `live_view.uri`: last URI that loaded the LiveView (available when the + `handle_params` function is invoked). + + * `live_view.params`: the params received by the LiveView (available when the + `handle_params` function is invoked). + + * `live_view.event`: last event received by the LiveView (available when the + `handle_event` function is invoked). + + * `live_view.event_params`: last event params received by the LiveView + (available when the `handle_event` function is invoked). """ alias ErrorTracker.Integrations.Plug, as: PlugIntegration @@ -24,12 +63,19 @@ defmodule ErrorTracker.Integrations.Phoenix do [:phoenix, :live_view, :render, :exception] ] + @doc """ + Attachs to Phoenix's Telemetry events if the library is detected. + + This function is usually called internally during the startup process so you + don't have to. + """ def attach do if Application.spec(:phoenix) do :telemetry.attach_many(__MODULE__, @events, &__MODULE__.handle_event/4, :no_config) end end + @doc false def handle_event([:phoenix, :router_dispatch, :start], _measurements, metadata, :no_config) do PlugIntegration.set_context(metadata.conn) end diff --git a/lib/error_tracker/integrations/plug.ex b/lib/error_tracker/integrations/plug.ex index 51112a4..07b24c7 100644 --- a/lib/error_tracker/integrations/plug.ex +++ b/lib/error_tracker/integrations/plug.ex @@ -1,10 +1,12 @@ defmodule ErrorTracker.Integrations.Plug do @moduledoc """ - The ErrorTracker integration with Plug applications. + Integration with Plug applications. - ## How it works + ## How to use it - The way to use this integration is by adding it to either your `Plug.Builder`` + ### Plug applications + + The way to use this integration is by adding it to either your `Plug.Builder` or `Plug.Router`: ```elixir @@ -16,7 +18,7 @@ defmodule ErrorTracker.Integrations.Plug do end ``` - ## Using it with Phoenix + ### Phoenix applications There is a particular use case which can be useful when running a Phoenix web application. @@ -33,6 +35,30 @@ defmodule ErrorTracker.Integrations.Plug do ... end ``` + + ### Default context + + By default we store some context for you on errors generated during a Plug + request: + + * `request.host`: the `conn.host` value. + + * `request.ip`: the IP address that initiated the request. It includes parsing + proxy headers + + * `request.method`: the HTTP method of the request. + + * `request.path`: the path of the request. + + * `request.query`: the query string of the request. + + * `request.params`: parsed params of the request (only available if they have + been fetched and parsed as part of the Plug pipeline). + + * `request.headers`: headers received on the request. All headers are included + by default except for the `Cookie` ones, as they may include large and + sensitive content like sessions. + """ defmacro __using__(_opts) do @@ -69,6 +95,7 @@ defmodule ErrorTracker.Integrations.Plug do end end + @doc false def report_error(conn, reason, stack) do unless Process.get(:error_tracker_router_exception_reported) do try do @@ -79,6 +106,7 @@ defmodule ErrorTracker.Integrations.Plug do end end + @doc false def set_context(conn = %Plug.Conn{}) do conn |> build_context |> ErrorTracker.set_context() end diff --git a/lib/error_tracker/migrations.ex b/lib/error_tracker/migration.ex similarity index 78% rename from lib/error_tracker/migrations.ex rename to lib/error_tracker/migration.ex index 94a4c32..d87c499 100644 --- a/lib/error_tracker/migrations.ex +++ b/lib/error_tracker/migration.ex @@ -1,4 +1,4 @@ -defmodule ErrorTracker.Migrations do +defmodule ErrorTracker.Migration do @moduledoc """ Create and modify the database tables for the ErrorTracker. @@ -18,8 +18,8 @@ defmodule ErrorTracker.Migrations do defmodule MyApp.Repo.Migrations.AddErrorTracker do use Ecto.Migration - def up, do: ErrorTracker.Migrations.up() - def down, do: ErrorTracker.Migrations.down() + def up, do: ErrorTracker.Migration.up() + def down, do: ErrorTracker.Migration.down() end ``` @@ -44,8 +44,8 @@ defmodule ErrorTracker.Migrations do defmodule MyApp.Repo.Migrations.UpdateErrorTrackerToVN do use Ecto.Migration - def up, do: ErrorTracker.Migrations.up(version: N) - def down, do: ErrorTracker.Migrations.down(version: N) + def up, do: ErrorTracker.Migration.up(version: N) + def down, do: ErrorTracker.Migration.down(version: N) end ``` @@ -67,8 +67,8 @@ defmodule ErrorTracker.Migrations do defmodule MyApp.Repo.Migrations.AddErrorTracker do use Ecto.Migration - def up, do: ErrorTracker.Migrations.up(prefix: "custom_schema") - def down, do: ErrorTracker.Migrations.down(prefix: "custom_schema") + def up, do: ErrorTracker.Migration.up(prefix: "custom_schema") + def down, do: ErrorTracker.Migration.down(prefix: "custom_schema") end ``` @@ -80,8 +80,8 @@ defmodule ErrorTracker.Migrations do defmodule MyApp.Repo.Migrations.AddErrorTracker do use Ecto.Migration - def up, do: ErrorTracker.Migrations.up(prefix: "custom_schema", create_schema: false) - def down, do: ErrorTracker.Migrations.down(prefix: "custom_schema") + def up, do: ErrorTracker.Migration.up(prefix: "custom_schema", create_schema: false) + def down, do: ErrorTracker.Migration.down(prefix: "custom_schema") end ``` @@ -92,12 +92,6 @@ defmodule ErrorTracker.Migrations do config :error_tracker, :prefix, "custom_schema" ``` """ - defdelegate up(opts \\ []), to: ErrorTracker.Migration - defdelegate down(opts \\ []), to: ErrorTracker.Migration -end - -defmodule ErrorTracker.Migration do - @moduledoc false @callback up(Keyword.t()) :: :ok @callback down(Keyword.t()) :: :ok @@ -117,7 +111,7 @@ defmodule ErrorTracker.Migration do defp migrator do case ErrorTracker.Repo.__adapter__() do - Ecto.Adapters.Postgres -> ErrorTracker.Migrations.Postgres + Ecto.Adapters.Postgres -> ErrorTracker.Migration.Postgres adapter -> raise "ErrorTracker does not support #{adapter}" end end diff --git a/lib/error_tracker/migrations/postgres.ex b/lib/error_tracker/migration/postgres.ex similarity index 98% rename from lib/error_tracker/migrations/postgres.ex rename to lib/error_tracker/migration/postgres.ex index 45fa865..0ba9408 100644 --- a/lib/error_tracker/migrations/postgres.ex +++ b/lib/error_tracker/migration/postgres.ex @@ -1,4 +1,4 @@ -defmodule ErrorTracker.Migrations.Postgres do +defmodule ErrorTracker.Migration.Postgres do @moduledoc false @behaviour ErrorTracker.Migration diff --git a/lib/error_tracker/migrations/postgres/v01.ex b/lib/error_tracker/migration/postgres/v01.ex similarity index 96% rename from lib/error_tracker/migrations/postgres/v01.ex rename to lib/error_tracker/migration/postgres/v01.ex index 9946855..bdfb42b 100644 --- a/lib/error_tracker/migrations/postgres/v01.ex +++ b/lib/error_tracker/migration/postgres/v01.ex @@ -1,4 +1,4 @@ -defmodule ErrorTracker.Migrations.Postgres.V01 do +defmodule ErrorTracker.Migration.Postgres.V01 do @moduledoc false use Ecto.Migration diff --git a/lib/error_tracker/repo.ex b/lib/error_tracker/repo.ex index f736052..e243a6b 100644 --- a/lib/error_tracker/repo.ex +++ b/lib/error_tracker/repo.ex @@ -1,7 +1,6 @@ defmodule ErrorTracker.Repo do - @moduledoc """ - Wraps Ecto.Repo calls and applies default options. - """ + @moduledoc false + def insert!(struct_or_changeset, opts \\ []) do dispatch(:insert!, [struct_or_changeset], opts) end diff --git a/lib/error_tracker/schemas/error.ex b/lib/error_tracker/schemas/error.ex index 4e1c2e6..2d55554 100644 --- a/lib/error_tracker/schemas/error.ex +++ b/lib/error_tracker/schemas/error.ex @@ -1,9 +1,13 @@ defmodule ErrorTracker.Error do @moduledoc """ - An Error is a type of exception recorded by the ErrorTracker. + Schema to store an error or exception recorded by the ErrorTracker. It stores a kind, reason and source code location to generate a unique fingerprint that can be used to avoid duplicates. + + The fingerprint currently does not include the reason itself because it can + contain specific details that can change on the same error depending on + runtime conditions. """ use Ecto.Schema @@ -22,6 +26,7 @@ defmodule ErrorTracker.Error do timestamps(type: :utc_datetime_usec) end + @doc false def new(kind, reason, stacktrace = %ErrorTracker.Stacktrace{}) do source = ErrorTracker.Stacktrace.source(stacktrace) diff --git a/lib/error_tracker/schemas/occurrence.ex b/lib/error_tracker/schemas/occurrence.ex index ab76a5c..f36c583 100644 --- a/lib/error_tracker/schemas/occurrence.ex +++ b/lib/error_tracker/schemas/occurrence.ex @@ -1,6 +1,6 @@ defmodule ErrorTracker.Occurrence do @moduledoc """ - An Occurrence is a particular instance of an error in a given time. + Schema to store a particular instance of an error in a given time. It contains all the metadata available about the moment and the environment in which the exception raised. diff --git a/lib/error_tracker/schemas/stacktrace.ex b/lib/error_tracker/schemas/stacktrace.ex index 2589f3a..14f3517 100644 --- a/lib/error_tracker/schemas/stacktrace.ex +++ b/lib/error_tracker/schemas/stacktrace.ex @@ -50,7 +50,7 @@ defmodule ErrorTracker.Stacktrace do application, just the first line. """ def source(stack = %__MODULE__{}) do - client_app = Application.fetch_env!(:error_tracker, :application) + client_app = Application.fetch_env!(:error_tracker, :otp_app) Enum.find(stack.lines, &(&1.application == client_app)) || List.first(stack.lines) end diff --git a/lib/error_tracker/web.ex b/lib/error_tracker/web.ex index eb291c6..b1f865a 100644 --- a/lib/error_tracker/web.ex +++ b/lib/error_tracker/web.ex @@ -1,6 +1,6 @@ defmodule ErrorTracker.Web do @moduledoc """ - ErrorTracker includes a Web UI to view and inspect errors occurred on your + ErrorTracker includes a dashboard to view and inspect errors occurred on your application and already stored on the database. In order to use it, you need to add the following to your Phoenix's ` @@ -17,7 +17,22 @@ defmodule ErrorTracker.Web do end ``` - This will add the routes needed for the ErrorTracker LiveView UI to work. + This will add the routes needed for the ErrorTracker dashboard to work. + + ## Security considerations + + Errors may contain sensitive information, like IP addresses, users information + or even passwords sent on forms! + + Securing your dashboard is an important part of integrating `ErrorTracker` on + your project. + + In order to do so, we recommend implementing your own security mechanisms in + the form of a mount hook and pass it to the `error_tracker_dashboard` macro + using the `on_mount` option. + + You can find more details on + `ErrorTracker.Web.Router.error_tracker_dashboard/2`. ## LiveView socket options @@ -36,6 +51,7 @@ defmodule ErrorTracker.Web do ``` """ + @doc false def html do quote do import Phoenix.Controller, only: [get_csrf_token: 0] @@ -44,6 +60,7 @@ defmodule ErrorTracker.Web do end end + @doc false def live_view do quote do use Phoenix.LiveView, layout: {ErrorTracker.Web.Layouts, :live} @@ -52,6 +69,7 @@ defmodule ErrorTracker.Web do end end + @doc false def live_component do quote do use Phoenix.LiveComponent @@ -60,6 +78,7 @@ defmodule ErrorTracker.Web do end end + @doc false def router do quote do import ErrorTracker.Web.Router diff --git a/lib/error_tracker/web/components/layouts.ex b/lib/error_tracker/web/components/layouts.ex index 292429f..a7aaeb8 100644 --- a/lib/error_tracker/web/components/layouts.ex +++ b/lib/error_tracker/web/components/layouts.ex @@ -1,4 +1,5 @@ defmodule ErrorTracker.Web.Layouts do + @moduledoc false use ErrorTracker.Web, :html alias ErrorTracker.Web.Layouts.Navbar diff --git a/lib/error_tracker/web/components/layouts/navbar.ex b/lib/error_tracker/web/components/layouts/navbar.ex index d4478d5..b5ee233 100644 --- a/lib/error_tracker/web/components/layouts/navbar.ex +++ b/lib/error_tracker/web/components/layouts/navbar.ex @@ -7,7 +7,7 @@ defmodule ErrorTracker.Web.Layouts.Navbar do