Packages
raygun
0.0.21
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.45
0.0.44
0.0.43
0.0.42
0.0.41
0.0.40
0.0.39
0.0.38
0.0.37
0.0.36
0.0.35
0.0.34
0.0.33
0.0.32
0.0.31
0.0.30
0.0.29
0.0.28
0.0.27
0.0.26
0.0.25
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
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
Send errors in your application to Raygun. Raygun captures all your application errors in one place. It can be used as a Plug, via Logger and/or programmatically.
Current section
Files
Jump to
Current section
Files
lib/raygun/format.ex
defmodule Raygun.Format do
@moduledoc """
This module builds payloads of error messages that Raygun will understand.
These functions return maps of data which will be encoding as JSON prior
to submission to Raygun.
"""
@doc """
Builds an error payload that Raygun will understand for a string.
"""
def message_payload(msg, opts) do
%{
occurredOn: now,
details:
details
|> Dict.merge( environment )
|> Dict.merge( user )
|> Dict.merge( custom(opts) )
|> Dict.merge( %{error: %{ message: msg } } )
}
end
@doc """
Builds an error payload that Raygun will understand for an exception and its
corresponding stacktrace.
"""
def stacktrace_payload(stacktrace, exception, opts) do
%{
occurredOn: now,
details:
details
|> Dict.merge( err(stacktrace, exception) )
|> Dict.merge( environment )
|> Dict.merge( user )
|> Dict.merge( custom(opts) )
}
end
@doc """
Builds an error payload that Raygun will understand for an exception that was
caught in our Plug.
"""
def conn_payload(conn, stacktrace, exception, opts) do
%{
occurredOn: now,
details:
details
|> Dict.merge( err(stacktrace, exception) )
|> Dict.merge( environment )
|> Dict.merge( request(conn) )
|> Dict.merge( response(conn) )
|> Dict.merge( user(conn) )
|> Dict.merge( custom(opts) )
}
end
@doc """
Return custom information. Tags are configured per application via config and
user custom data can be provided per error.
"""
def custom(opts) do
%{
tags: Application.get_env(:raygun,:tags),
userCustomData: Enum.into(opts, %{})
}
end
@doc """
Returns the system user from the configuration if one is specified.
"""
def user() do
%{user: Application.get_env(:raygun, :system_user)}
end
@doc """
Get the logged in user from the Plug Conn. This function will most likely be
overridden by a function provided by the clients.
"""
def user(_conn) do
%{user: %{
identifier: "",
isAnonymous: true,
email: "",
fullName: "",
firstName: "",
uuid: ""
}
}
end
@doc """
Return a map of information about the environment in which the bug was encountered.
"""
def environment do
:disksup.start_link
disks = :disksup.get_disk_data
disk_free_spaces = for {_mount_point, capacity, percent_used} <- disks do
((100-percent_used)/100) * capacity
end
{:ok, hostname} = :inet.gethostname
hostname = hostname |> List.to_string
{os_type, os_flavor} = :os.type
os_version = "#{os_type} - #{os_flavor}"
architecture = :erlang.system_info(:system_architecture) |> List.to_string
sys_version = :erlang.system_info(:system_version) |> List.to_string
processor_count = :erlang.system_info(:logical_processors_online)
memory_used = :erlang.memory(:total)
%{environment: %{
osVersion: os_version,
architecture: architecture,
packageVersion: sys_version,
processorCount: processor_count,
totalPhysicalMemory: memory_used,
deviceName: hostname,
diskSpaceFree: disk_free_spaces,
}
}
end
@doc """
Returns deatils about the client and server machine.
"""
def details do
{:ok, hostname} = :inet.gethostname
hostname = hostname |> List.to_string
%{
machineName: hostname,
version: Mix.Project.config[:deps][:raygun],
client: %{
name: Mix.Project.config[:app],
version: Mix.Project.config[:version],
clientUrl: Mix.Project.config[:raygun][:url]
}
}
end
@doc """
Get the current time in ISO 8601 format.
"""
def now do
{:ok, datetime} = Timex.Date.now |> Timex.DateFormat.format("{ISOz}")
datetime
end
@doc """
Given a Plug Conn return a map containing information about the request.
"""
def request(conn) do
%{request: %{
hostName: conn.host,
url: "#{Atom.to_string(conn.scheme)}://#{conn.host}:#{conn.port}#{conn.request_path}",
httpMethod: conn.method,
iPAddress: conn.remote_ip |> :inet.ntoa |> List.to_string,
queryString: Plug.Conn.fetch_query_params(conn).query_params,
form: Plug.Parsers.call(conn, []).params,
headers: Raygun.Util.format_headers(conn.req_headers),
rawData: %{}
}
}
end
@doc """
Given a Plug Conn return a map containing information about the response.
"""
def response(conn) do
%{response: %{
statusCode: conn.status
}
}
end
@doc """
Given a stacktrace and an exception, return a map with the error data.
"""
def err(stacktrace, error) do
s0 = Enum.at(stacktrace, 0) |> stacktrace_entry
%{error: %{
innerError: nil,
data: %{fileName: s0.fileName, lineNumber: s0.lineNumber, function: s0.methodName},
className: s0.className,
message: Exception.message(error),
stackTrace: stacktrace(stacktrace)
}
}
end
@doc """
Given a stacktrace return a list of maps for the frames.
"""
def stacktrace(s) do
s |> Enum.map(&stacktrace_entry/1)
end
@doc """
Given a stacktrace frame, return a map with the information in a structure
that Raygun will understand.
"""
def stacktrace_entry({function, arity_or_args, location}) do
stacktrace_entry {__MODULE__, function, arity_or_args, location}
end
def stacktrace_entry(entry = {module, function, arity_or_args, location}) do
IO.inspect entry
%{
lineNumber: Raygun.Util.line_from(location),
className: Raygun.Util.mod_for(module),
fileName: Raygun.Util.file_from(location),
methodName: Raygun.Util.function_and_arity(function,arity_or_args)
}
end
end