Packages
appsignal
1.4.6
2.17.4
2.17.3
2.17.2
2.17.1
2.17.0
2.16.0
2.15.11
2.15.10
2.15.9
2.15.8
2.15.7
2.15.6
2.15.5
2.15.4
2.15.3
2.15.2
2.15.1
2.15.0
2.14.1
2.14.0
2.13.4
2.13.3
2.13.2
2.13.1
2.13.0
2.12.3
2.12.2
2.12.1
2.12.0
2.11.0
2.10.2
2.10.1
2.10.0
2.9.2
2.9.1
2.9.0
2.8.3
2.8.2
2.8.1
2.8.0
2.7.13
2.7.12
2.7.11
2.7.10
2.7.9
2.7.8
2.7.7
2.7.6
2.7.5
2.7.4
2.7.3
2.7.2
2.7.1
2.7.0
2.7.0-beta.1
2.6.1
2.6.0
2.5.3
2.5.2
2.5.1
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.1
2.3.0
2.2.19
2.2.18
2.2.17
2.2.16
2.2.15
2.2.14
2.2.13
2.2.12
retired
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.1.15
2.1.14
2.1.13
2.1.12
2.1.11
2.1.10
2.1.9
2.1.8
2.1.7
2.1.7-beta.1
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.8
2.0.7
2.0.6
2.0.6-beta.1
2.0.5
retired
2.0.4
retired
2.0.3
retired
2.0.2
retired
2.0.1
retired
2.0.0
retired
2.0.0-beta.11
2.0.0-beta.10
2.0.0-beta.9
2.0.0-beta.8
2.0.0-beta.7
2.0.0-beta.6
2.0.0-beta.5
2.0.0-beta.4
2.0.0-beta.3
2.0.0-beta.2
2.0.0-beta.1
2.0.0-alpha.7
2.0.0-alpha.6
2.0.0-alpha.5
2.0.0-alpha.4
2.0.0-alpha.3
2.0.0-alpha.2
2.0.0-alpha.1
1.13.5
1.13.4
1.13.3
1.13.2
1.13.1
1.13.0
1.13.0-beta.2
1.13.0-beta.1
1.12.1
1.12.0
1.12.0-beta.3
1.12.0-beta.2
1.12.0-beta.1
1.11.8
1.11.7
1.11.6
1.11.5
1.11.4
1.11.3
1.11.2
1.11.1
1.11.0
1.11.0-beta.1
1.10.13
1.10.12
1.10.11
1.10.10
1.10.9
1.10.8
1.10.7
1.10.6
1.10.5
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.4
1.9.3
1.9.2
1.9.1
1.9.1-beta.1
1.9.0
1.9.0-beta.1
1.9.0-alpha.1
1.8.2
1.8.1
1.8.1-beta.2
1.8.1-beta.1
1.8.0
1.7.2
1.7.1
1.7.0
1.7.0-beta.2
1.7.0-beta.1
1.7.0-alpha.4
1.7.0-alpha.3
1.7.0-alpha.2
1.7.0-alpha.1
1.6.7
1.6.6
1.6.6-beta.2
1.6.6-beta.1
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.6.0-beta.1
1.6.0-alpha.1
1.5.1
1.5.0
1.5.0-beta.2
1.5.0-beta.1
1.4.11-beta.1
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-alpha.1
1.3.6
1.3.6-beta.1
1.3.5
1.3.4
1.3.4-beta.1
1.3.3
1.3.2
1.3.1
1.3.0
1.3.0-beta.3
1.3.0-beta.2
1.3.0-beta.1
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc.1
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.2
0.9.1
0.9.0
0.8.0
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Collects error and performance data from your Elixir applications and sends it to AppSignal
Current section
Files
Jump to
Current section
Files
lib/appsignal.ex
defmodule Appsignal do
@moduledoc """
AppSignal for Elixir. Follow the [installation guide](https://docs.appsignal.com/elixir/installation.html) to install AppSignal into your Elixir app.
This module contains the main AppSignal OTP application, as well as
a few helper functions for sending metrics to AppSignal.
These metrics do not rely on an active transaction being
present. For transaction related-functions, see the
[Appsignal.Transaction](Appsignal.Transaction.html) module.
"""
use Application
alias Appsignal.Config
require Logger
@doc """
Application callback function
"""
def start(_type, _args) do
import Supervisor.Spec, warn: false
initialize()
:error_logger.add_report_handler(Appsignal.ErrorHandler)
children = [
worker(Appsignal.TransactionRegistry, [])
]
Supervisor.start_link(children, [strategy: :one_for_one, name: Appsignal.Supervisor])
end
def plug? do
Code.ensure_loaded?(Plug)
end
def phoenix? do
Code.ensure_loaded?(Phoenix)
end
@doc """
Application callback function
"""
def stop(_state) do
Logger.debug("AppSignal stopping.")
end
def config_change(_changed, _new, _removed) do
# Spawn a separate process that reloads the configuration. AppSignal can't
# reload it in the same process because the GenServer would continue
# calling itself once it reached `Application.put_env` in
# `Appsignal.Config`.
spawn(fn ->
:ok = Appsignal.Nif.stop()
:ok = initialize()
end)
end
@doc false
def initialize() do
case {Config.initialize, Config.active?} do
{:ok, true} ->
Logger.debug("AppSignal starting.")
Config.write_to_environment
Appsignal.Nif.start
if Appsignal.Nif.loaded? do
Logger.debug("AppSignal started.")
else
Logger.error("Failed to start AppSignal. Please run the diagnose task (https://docs.appsignal.com/elixir/command-line/diagnose.html) to debug your installation.")
end
{:ok, false} ->
Logger.info("AppSignal disabled.")
:ok
{{:error, :invalid_config}, _} ->
# show warning that Appsignal is not configured; but not when we run the tests.
spawn_link(fn ->
:timer.sleep 100 # FIXME, this timeout is kind of cludgy.
unless Process.whereis(ExUnit.Server) do
Logger.warn("Warning: No valid AppSignal configuration found, continuing with AppSignal metrics disabled.")
end
end)
:ok
end
end
@doc """
Set a gauge for a measurement of some metric.
"""
@spec set_gauge(String.t, float | integer) :: :ok
def set_gauge(key, value) when is_integer(value) do
set_gauge(key, value + 0.0)
end
def set_gauge(key, value) when is_float(value) do
Appsignal.Nif.set_gauge(key, value)
end
@doc """
Increment a counter of some metric.
"""
@spec increment_counter(String.t, integer) :: :ok
def increment_counter(key, count \\ 1) when is_integer(count) do
Appsignal.Nif.increment_counter(key, count)
end
@doc """
Add a value to a distribution
Use this to collect multiple data points that will be merged into a
graph.
"""
@spec add_distribution_value(String.t, float | integer) :: :ok
def add_distribution_value(key, value) when is_integer(value) do
add_distribution_value(key, value + 0.0)
end
def add_distribution_value(key, value) when is_float(value) do
Appsignal.Nif.add_distribution_value(key, value)
end
@doc """
Send an error to AppSignal
When there is no current transaction, this call starts one.
## Examples
Appsignal.send_error(%RuntimeError{})
Appsignal.send_error(%RuntimeError{}, "Oops!")
Appsignal.send_error(%RuntimeError{}, "", System.stacktrace())
Appsignal.send_error(%RuntimeError{}, "", nil, %{foo: "bar"})
Appsignal.send_error(%RuntimeError{}, "", nil, %{}, %Plug.Conn{peer: {{127, 0, 0, 1}, 12345}})
Appsignal.send_error(%RuntimeError{}, "", nil, %{}, nil, fn(transaction) ->
Appsignal.Transaction.set_sample_data(transaction, "key", %{foo: "bar"})
end)
"""
def send_error(reason, message \\ "", stack \\ nil, metadata \\ %{}, conn \\ nil, fun \\ fn(t) -> t end, namespace \\ :http_request) do
stack = stack || System.stacktrace()
transaction = Appsignal.Transaction.start("_" <> Appsignal.Transaction.generate_id(), namespace)
fun.(transaction)
{reason, message} = Appsignal.ErrorHandler.extract_reason_and_message(reason, message)
Appsignal.TransactionRegistry.remove_transaction(transaction)
Appsignal.ErrorHandler.submit_transaction(transaction, reason, message, stack, metadata, conn)
end
end