Packages
timber
2.0.2
3.1.2
3.1.1
3.1.0
3.0.0
3.0.0-alpha.3
3.0.0-alpha.2
3.0.0-alpha.1
2.8.4
2.8.3
2.8.2
2.8.1
2.8.0
2.7.0
2.6.1
2.6.0
2.5.6
2.5.5
2.5.4
2.5.3
2.5.2
2.5.1
2.5.0
2.4.5
2.4.4
2.4.3
2.4.2
2.4.1
2.4.0
2.3.4
2.3.3
2.3.1
2.3.0
2.2.1
2.2.0
2.1.8
2.1.7
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.2
2.0.1
2.0.0
2.0.0-rc7
2.0.0-rc6
2.0.0-rc5
2.0.0-rc4
2.0.0-rc3
2.0.0-rc2
2.0.0-rc1
1.1.18
1.1.17
1.1.16
1.1.15
1.1.14
1.1.13
1.1.12
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
🌲 Great Elixir Logging Made Easy. Official Timber.io Integration.
Current section
Files
Jump to
Current section
Files
lib/timber/utils/http_events.ex
defmodule Timber.Utils.HTTPEvents do
@moduledoc false
alias Timber.Config
def format_time_ms(time_ms) when is_integer(time_ms),
do: [Integer.to_string(time_ms), "ms"]
def format_time_ms(time_ms) when is_float(time_ms) and time_ms >= 1,
do: [:erlang.float_to_binary(time_ms, decimals: 2), "ms"]
def format_time_ms(time_ms) when is_float(time_ms) and time_ms < 1,
do: [:erlang.float_to_binary(time_ms * 1000, decimals: 0), "µs"]
@doc false
# Constructs a full path from the given parts
def full_path(path, query_string) do
%URI{path: path, query: query_string}
|> URI.to_string()
end
@doc false
# Constructs a full path from the given parts
def full_url(scheme, host, path, port, query_string) do
%URI{scheme: scheme, host: host, path: path, port: port, query: query_string}
|> URI.to_string()
end
@doc false
# Attemps to grab the request ID from the headers
def get_request_id_from_headers(%{"x-request-id" => request_id}), do: request_id
def get_request_id_from_headers(%{"request-id" => request_id}), do: request_id
def get_request_id_from_headers(_headers), do: nil
@doc false
# Normalizes the body into a truncated string
def normalize_body(nil = body), do: body
def normalize_body("" = body), do: body
def normalize_body(body) when is_map(body) do
case Config.json_encoder().(body) do
{:ok, json} -> normalize_body(to_string(json))
_ -> nil
end
end
def normalize_body(body) when is_list(body) do
normalize_body(to_string(body))
end
def normalize_body(body) when is_binary(body) do
limit = Config.http_body_size_limit()
Timber.Utils.Logger.truncate(body, limit)
end
@doc false
# Normalizes HTTP headers into a structure expected by the Timber API.
def normalize_headers(headers) when is_list(headers) do
headers
|> List.flatten()
|> Enum.into(%{})
|> normalize_headers()
end
def normalize_headers(headers) when is_map(headers) do
headers
|> Enum.map(&normalize_header/1)
|> Enum.map(&sanitize_header/1)
|> Enum.into(%{})
end
def normalize_headers(headers), do: headers
@doc false
# Normalizes an individual header
@spec normalize_header({String.t, String.t}) :: {String.t, String.t}
defp normalize_header({name, value}) do
{String.downcase(name), Timber.Utils.Logger.truncate(value, 255)}
end
# Sanitizes sensitive headers
defp sanitize_header({"authorization", _value}) do
{"authorization", "[sanitized]"}
end
defp sanitize_header(header), do: header
@doc false
# Normalizes HTTP methods into a value expected by the Timber API.
def normalize_method(method) when is_atom(method) do
method
|> Atom.to_string()
|> normalize_method()
end
def normalize_method(method) when is_binary(method), do: String.upcase(method)
def normalize_method(method), do: method
@doc false
# Normalizes a URL into a Keyword.t that maps to our HTTP event fields.
def normalize_url(url) when is_binary(url) do
uri = URI.parse(url)
[
host: uri.authority,
path: uri.path,
port: uri.port,
query_string: uri.query,
scheme: uri.scheme
]
end
def normalize_url(_url), do: []
@doc false
# Convenience method that checks if the value is an atom and also converts it to a string.
def try_atom_to_string(nil), do: nil
def try_atom_to_string(val) when is_atom(val), do: Atom.to_string(val)
def try_atom_to_string(val), do: val
end