Packages
appsignal
0.11.0
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/config.ex
defmodule Appsignal.Config do
@default_config %{
debug: false,
enable_host_metrics: true,
endpoint: "https://push.appsignal.com",
env: :dev,
filter_parameters: nil,
ignore_actions: [],
ignore_errors: [],
running_in_container: false,
send_params: true,
skip_session_data: false,
log: "file"
}
@doc """
Initializes the Appsignal config. Looks at the config default, the
Elixir-provided configuration and the various `APPSIGNAL_*`
OS environment variables. Returns whether or not the configuration is valid.
"""
@spec initialize() :: :ok | {:error, :invalid_config}
def initialize() do
system_config = load_from_system()
app_config = Application.get_env(:appsignal, :config, []) |> coerce_map
env_config = load_from_environment()
config = @default_config
|> Map.merge(system_config)
|> Map.merge(app_config)
|> Map.merge(env_config)
config = config
# Config is valid when we have a push api key
|> Map.put(:valid, !empty?(config[:push_api_key]))
# Make active by default if the push key is present
|> Map.put(:active, (if config[:active] == nil, do: !empty?(config[:push_api_key]), else: config[:active]))
Application.put_env(:appsignal, :config, config)
write_to_environment(config)
case config[:valid] do
true ->
:ok
false ->
{:error, :invalid_config}
end
end
@doc """
Returns whether the Appsignal agent is configured to start on application launch.
"""
@spec active?() :: boolean
def active? do
Application.fetch_env!(:appsignal, :config).active
end
@env_to_key_mapping %{
"APPSIGNAL_ACTIVE" => :active,
"APPSIGNAL_PUSH_API_KEY" => :push_api_key,
"APPSIGNAL_APP_NAME" => :name,
"APP_REVISION" => :revision,
"APPSIGNAL_APP_ENV" => :env,
"APPSIGNAL_PUSH_API_ENDPOINT" => :endpoint,
"APPSIGNAL_FRONTEND_ERROR_CATCHING_PATH" => :frontend_error_catching_path,
"APPSIGNAL_FILTER_PARAMETERS" => :filter_parameters,
"APPSIGNAL_DEBUG" => :debug,
"APPSIGNAL_LOG" => :log,
"APPSIGNAL_LOG_PATH" => :log_path,
"APPSIGNAL_IGNORE_ERRORS" => :ignore_errors,
"APPSIGNAL_IGNORE_ACTIONS" => :ignore_actions,
"APPSIGNAL_HTTP_PROXY" => :http_proxy,
"APPSIGNAL_RUNNING_IN_CONTAINER" => :running_in_container,
"APPSIGNAL_WORKING_DIR_PATH" => :working_dir_path,
"APPSIGNAL_ENABLE_HOST_METRICS" => :enable_host_metrics,
"APPSIGNAL_SKIP_SESSION_DATA" => :skip_session_data
}
@string_keys ~w(APPSIGNAL_PUSH_API_KEY APPSIGNAL_PUSH_API_ENDPOINT APPSIGNAL_FRONTEND_ERROR_CATCHING_PATH APPSIGNAL_HTTP_PROXY APPSIGNAL_LOG APPSIGNAL_LOG_PATH APPSIGNAL_WORKING_DIR_PATH APP_REVISION)
@bool_keys ~w(APPSIGNAL_ACTIVE APPSIGNAL_DEBUG APPSIGNAL_INSTRUMENT_NET_HTTP APPSIGNAL_ENABLE_FRONTEND_ERROR_CATCHING APPSIGNAL_ENABLE_ALLOCATION_TRACKING APPSIGNAL_ENABLE_GC_INSTRUMENTATION APPSIGNAL_RUNNING_IN_CONTAINER APPSIGNAL_ENABLE_HOST_METRICS APPSIGNAL_SKIP_SESSION_DATA)
@atom_keys ~w(APPSIGNAL_APP_NAME APPSIGNAL_APP_ENV)
@string_list_keys ~w(APPSIGNAL_FILTER_PARAMETERS APPSIGNAL_IGNORE_ACTIONS APPSIGNAL_IGNORE_ERRORS)
defp load_environment(config, list, converter) do
list |> Enum.reduce(
config,
fn(key, cfg) ->
value = System.get_env(key)
if !empty?(value) do
Map.put(cfg, @env_to_key_mapping[key], converter.(value))
else
cfg
end
end)
end
defp load_from_system() do
case System.get_env("DYNO") do
nil -> %{}
_ -> %{running_in_container: true, log: "stdout"}
end
end
defp load_from_environment() do
%{}
|> load_environment(@string_keys, &(&1))
|> load_environment(@bool_keys, &(true?(&1)))
|> load_environment(@atom_keys, &(String.to_atom(&1)))
|> load_environment(@string_list_keys, &(String.split(&1, ",")))
end
defp coerce_map(value) when is_list(value) do
value |> Enum.into(%{})
end
defp coerce_map(%{} = value) do
value
end
defp empty?(nil), do: true
defp empty?(""), do: true
defp empty?(_), do: false
defp true?("true"), do: true
defp true?(true), do: true
defp true?(_), do: false
@agent_version Poison.decode!(File.read!("agent.json"))["version"]
@language_integration_version Mix.Project.config[:version]
defp write_to_environment(config) do
System.put_env("APPSIGNAL_ACTIVE", Atom.to_string(config[:active]))
System.put_env("APPSIGNAL_APP_PATH", List.to_string(:code.priv_dir(:appsignal))) # FIXME - app_path should not be necessary
System.put_env("APPSIGNAL_AGENT_PATH", List.to_string(:code.priv_dir(:appsignal)))
System.put_env("APPSIGNAL_ENVIRONMENT", Atom.to_string(config[:env]))
System.put_env("APPSIGNAL_AGENT_VERSION", @agent_version)
System.put_env("APPSIGNAL_LANGUAGE_INTEGRATION_VERSION", "elixir-" <> @language_integration_version)
System.put_env("APPSIGNAL_DEBUG_LOGGING", Atom.to_string(config[:debug]))
System.put_env("APPSIGNAL_LOG", config[:log])
unless empty?(config[:log_path]) do
System.put_env("APPSIGNAL_LOG_FILE_PATH", config[:log_path])
end
System.put_env("APPSIGNAL_PUSH_API_ENDPOINT", config[:endpoint] || "")
System.put_env("APPSIGNAL_PUSH_API_KEY", config[:push_api_key] || "")
System.put_env("APPSIGNAL_APP_NAME", Atom.to_string(config[:name]))
unless empty?(config[:http_proxy]) do
System.put_env("APPSIGNAL_HTTP_PROXY", config[:http_proxy])
end
unless empty?(config[:filter_parameters]) do
System.put_env("APPSIGNAL_FILTER_PARAMETERS", config[:filter_parameters] |> Enum.join(","))
end
System.put_env("APPSIGNAL_IGNORE_ACTIONS", config[:ignore_actions] |> Enum.join(","))
System.put_env("APPSIGNAL_IGNORE_ERRORS", config[:ignore_errors] |> Enum.join(","))
System.put_env("APPSIGNAL_SEND_PARAMS", Atom.to_string(config[:send_params]))
System.put_env("APPSIGNAL_RUNNING_IN_CONTAINER", Atom.to_string(config[:running_in_container]))
unless empty?(config[:working_dir_path]) do
System.put_env("APPSIGNAL_WORKING_DIR_PATH", config[:working_dir_path])
end
System.put_env("APPSIGNAL_ENABLE_HOST_METRICS", Atom.to_string(config[:enable_host_metrics]))
unless empty?(config[:revision]) do
System.put_env("APP_REVISION", config[:revision])
end
end
def get_system_env do
System.get_env
|> Enum.filter(
fn({"APPSIGNAL_" <> _, _}) -> true;
({"APP_REVISION", _}) -> true;
(_) -> false end)
|> Enum.into(%{})
end
# When you use Appsignal.Config you get a handy config macro which
# can be used to read the application config.
defmacro __using__(_) do
quote do
defmacro config do
quote do
Application.get_env(:appsignal, :config, [])
end
end
end
end
end