Packages
appsignal
1.2.1
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/mix/tasks/appsignal.diagnose.ex
defmodule Mix.Tasks.Appsignal.Diagnose do
use Mix.Task
alias Appsignal.Utils.PushApiKeyValidator
alias Appsignal.Config
@appsignal_version Mix.Project.config[:version]
@agent_version Mix.Project.config[:agent_version]
@system Application.get_env(:appsignal, :appsignal_system, Appsignal.System)
@nif Application.get_env(:appsignal, :appsignal_nif, Appsignal.Nif)
@shortdoc "Starts and tests AppSignal while validating the configuration."
def run(_args) do
header()
empty_line()
agent_version()
empty_line()
host_information()
empty_line()
if @nif.loaded? do
start_appsignal_in_diagnose_mode()
end
configuration()
empty_line()
validate_push_api_key()
empty_line()
paths()
end
defp header do
IO.puts "AppSignal diagnose"
IO.puts String.duplicate("=", 80)
IO.puts "Use this information to debug your configuration."
IO.puts "More information is available on the documentation site."
IO.puts "http://docs.appsignal.com/"
IO.puts "Send this output to support@appsignal.com if you need help."
IO.puts String.duplicate("=", 80)
end
defp agent_version do
IO.puts "AppSignal agent"
IO.puts " Language: Elixir"
IO.puts " Package version: #{@appsignal_version}"
IO.puts " Agent version: #{@agent_version}"
IO.puts " Nif loaded: #{yes_or_no(@nif.loaded?)}"
end
defp host_information do
IO.puts "Host information"
IO.puts " Architecture: #{:erlang.system_info(:system_architecture)}"
IO.puts " Elixir version: #{System.version}"
IO.puts " OTP version: #{System.otp_release}"
root_user = if (@system.root?), do: "yes (not recommended)", else: "no"
IO.puts " root user: #{root_user}"
if @system.heroku? do
IO.puts " Heroku: yes"
end
IO.puts " Container: #{yes_or_no(@nif.running_in_container?)}"
end
# Start AppSignal as usual, in diagnose mode, so that it exits early, but
# does go through the whole process of setting the config to the
# environment.
defp start_appsignal_in_diagnose_mode do
Config.initialize
Config.write_to_environment
agent_path = Path.join(List.to_string(:code.priv_dir(:appsignal)), "appsignal-agent")
env = [{"_APPSIGNAL_DIAGNOSE", "true"}]
case System.cmd(agent_path, [], env: env) do
{output, 0} -> IO.puts output
{output, exit_code} ->
IO.puts "Agent diagnostic failure!"
IO.puts " Exit code: #{exit_code}"
IO.puts " Error message: #{output}"
end
end
defp configuration do
IO.puts "Configuration"
Enum.each config(), fn({key, value}) ->
IO.puts " #{key}: #{value}"
end
end
defp paths do
IO.puts "Paths"
log_file_path = config()[:log_path] || "/tmp/appsignal.log"
log_dir_path = Path.dirname(log_file_path)
diagnose_path "log_dir_path", log_dir_path
diagnose_path "log_file_path", log_file_path
end
defp diagnose_path(name, path) do
IO.puts " #{name}: #{path}"
process_uid = @system.uid
if File.exists? path do
case File.stat(path) do
{:ok, %{access: access, uid: uid}} ->
IO.write " - Writable?: "
case access do
p when p in [:write, :read_write] ->
IO.puts "yes"
_ ->
IO.puts "no"
end
IO.write " - Ownership?: "
IO.write yes_or_no(uid == process_uid)
IO.puts " (file: #{uid}, process: #{process_uid})"
{:error, reason} ->
IO.puts " Can't read path: #{reason}"
end
else
IO.puts " - Exists?: no"
end
end
defp validate_push_api_key do
IO.puts "Validation"
IO.write " Push API key: "
case PushApiKeyValidator.validate(config()) do
:ok -> IO.puts "valid"
{:error, :invalid} -> IO.puts "invalid"
{:error, reason} -> IO.puts "failure: #{reason}"
end
end
defp config do
Application.get_env(:appsignal, :config)
end
defp empty_line do
IO.puts ""
end
defp yes_or_no(true), do: "yes"
defp yes_or_no(false), do: "no"
end