Packages
sentry
10.2.0-rc.2
13.3.0
13.2.0
13.1.0
13.0.1
13.0.0
12.0.3
12.0.2
12.0.1
12.0.0
11.0.4
11.0.3
11.0.2
11.0.1
11.0.0
10.10.0
10.9.0
10.8.1
10.8.0
10.7.1
10.7.0
10.6.2
10.6.1
10.6.0
10.5.0
10.4.0
10.3.0
10.2.1
10.2.0
10.2.0-rc.2
10.2.0-rc.1
10.1.0
10.0.3
10.0.2
10.0.1
10.0.0
9.1.0
9.0.0
8.1.0
8.0.6
8.0.5
8.0.4
8.0.3
8.0.2
8.0.1
8.0.0
8.0.0-rc.2
8.0.0-rc.1
8.0.0-rc.0
retired
7.2.5
7.2.4
7.2.3
7.2.2
7.2.1
7.2.0
7.1.0
7.0.6
7.0.5
7.0.4
7.0.3
7.0.2
7.0.1
7.0.0
6.4.2
6.4.1
6.4.0
6.3.0
6.2.1
6.2.0
6.1.0
6.0.5
6.0.4
6.0.3
6.0.2
6.0.1
6.0.0
5.0.1
5.0.0
4.0.3
4.0.2
4.0.1
4.0.0
3.0.0
2.2.0
2.1.0
2.0.2
2.0.1
2.0.0
1.1.2
1.1.1
1.1.0
1.0.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
The Official Elixir client for Sentry
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/sentry.package_source_code.ex
defmodule Mix.Tasks.Sentry.PackageSourceCode do
@shortdoc "Packages source code for Sentry to use when reporting errors"
@moduledoc """
Packages source code for Sentry to use when reporting errors.
This task should be used in production settings, before building a release of your
application. It packages all the source code of your application in a single file
(called `sentry.map`), which is optimized for fast retrieval of source code lines.
Sentry then uses this to report source code context. See the documentation for the
`Sentry` module for configuration options related to the source code context.
*This task is available since v10.0.0 of this library*.
## Usage
```shell
mix sentry.package_source_code
```
### Using in Production
In production settings, call this task before building a release. This way, the source
code packaged by this task will be included in the release.
For example, in a release script (this could also be in a `Dockerfile`, if you're using
Docker):
```shell
# ...
mix sentry.package_source_code
mix release
```
> #### Runtime Configuration {: .tip}
>
> If you use `config/runtime.exs` for runtime configuration of your application and
> release, *and* you also configure the source-context-related options for the `:sentry`
> application in that file (such as `:root_source_code_paths`), you'll need to call the
> `mix app.config` task before calling this Mix task. `mix app.config` loads the
> `config/runtime.exs` configuration. Generally, we recommend configuring all the
> source-context-related options in compile-time config files (like `config/config.exs`
> or `config/prod.exs`).
## Options
* `--debug` - print more information about collecting and encoding source code
* `--output PATH` - write source map file to the given `PATH`. If you don't specify
this option, the file will be written to the default path, which is inside the `priv`
directory of the `:sentry` application. If you use this option, remember to also
**configure the `:source_code_map_path` option**, otherwise Sentry will try to
*read* the file from the default location. See `Sentry` for more information.
This option can be useful when the source
`priv` directory is read-only, such as with [NixOS](https://github.com/NixOS/nixpkgs)
and similar tools.
*Available since v10.2.0*.
"""
@moduledoc since: "10.0.0"
use Mix.Task
alias Sentry.Sources
@bytes_in_kb 1024
@bytes_in_mb 1024 * 1024
@bytes_in_gb 1024 * 1024 * 1024
@switches [
debug: :boolean,
output: :string
]
@impl true
def run(args) do
{opts, _args} = OptionParser.parse!(args, strict: @switches)
config = Application.get_all_env(:sentry)
{elapsed, source_map} =
:timer.tc(fn ->
case Sources.load_files(config) do
{:ok, source_map} -> source_map
{:error, message} -> Mix.raise(message)
end
end)
log_debug(
opts,
"Loaded source code map with #{map_size(source_map)} files in #{format_time(elapsed)}"
)
{elapsed, contents} = :timer.tc(fn -> Sources.encode_source_code_map(source_map) end)
log_debug(opts, "Encoded source code map in #{format_time(elapsed)}")
output_path = Keyword.get_lazy(opts, :output, &Sources.path_of_packaged_source_code/0)
File.mkdir_p!(Path.dirname(output_path))
File.write!(output_path, contents)
Mix.shell().info([
"Wrote #{map_size(source_map)} files in ",
[:cyan, format_bytes(byte_size(contents)), :reset],
" to: #{Path.relative_to_cwd(output_path)}"
])
end
## Helpers
defp log_debug(opts, str) do
if opts[:debug] do
Mix.shell().info([:magenta, str, :reset])
end
end
defp format_bytes(n) when n < @bytes_in_kb, do: "#{n} bytes"
defp format_bytes(n) when n < @bytes_in_mb, do: "#{Float.round(n / @bytes_in_kb, 2)} kb"
defp format_bytes(n) when n < @bytes_in_gb, do: "#{Float.round(n / @bytes_in_mb, 2)} Mb"
defp format_time(n) when n < 1000, do: "#{n} µs"
defp format_time(n) when n < 1_000_000, do: "#{div(n, 1000)} ms"
defp format_time(n), do: "#{Float.round(n / 1_000_000, 2)} s"
end