Current section
Files
Jump to
Current section
Files
lib/builder/builder.ex
defmodule Quill.Builder do
@moduledoc """
Documentation for Quill.Builder.
"""
def add_base_fields(data, message, level, timestamp, config) when is_list(message) do
add_base_fields(data, IO.iodata_to_binary(message), level, timestamp, config)
end
def add_base_fields(data, message, level, timestamp, config) do
data
|> Map.merge(%{
name: get_name(config),
level: level,
message: message
|> censor_regex(config.custom_censor_regex)
|> censor_email(config.email_censor_type)
|> censor_phone_number(config.phone_number_censor_type, config.phone_number_prefix),
timestamp: get_formatted_timestamp(timestamp),
version: get_version(config),
})
end
def add_metadata_fields(data, metadata, config) do
data
|> Map.merge(metadata
|> filter_metadata(config)
|> Enum.into(%{})
|> Map.delete(:timestamp))
end
def censor_regex(message, nil) do
message
end
def censor_regex(message, regex_list) when is_list(regex_list) do
List.foldl(regex_list, message, fn rx, msg -> censor_regex(msg, rx) end)
end
def censor_regex(message, regex) do
Regex.replace(regex, message, "***")
end
def censor_email(message, nil) do
message
end
def censor_email(message, :partial) do
~r<((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*"))(@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))>
|> Regex.replace(message, fn _, name, suffix -> "#{String.slice(name, 0..0)}***#{suffix}" end)
end
def censor_email(message, :full) do
~r<((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*"))(@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))>
|> Regex.replace(message, fn _, _, _ -> "***" end)
end
def censor_phone_number(message, _, nil) do
message
end
def censor_phone_number(message, level, area_code_list) when is_list(area_code_list) do
List.foldl(area_code_list, message, fn code, msg -> censor_phone_number(msg, level, code) end)
end
def censor_phone_number(message, :partial, area_code) do
"(#{Regex.replace(~r/\+/, area_code, "\\+")})(\\d+)"
|> Regex.compile!()
|> Regex.replace(message, fn _, code, number -> "#{code}***#{String.slice(number, -3..-1)}" end)
end
def censor_phone_number(message, :full, area_code) do
"(#{Regex.replace(~r/\+/, area_code, "\\+")})(\\d+)"
|> Regex.compile!()
|> Regex.replace(message, fn _, _, _ -> "***" end)
end
defp get_name(config) do
config.name
end
defp get_formatted_timestamp({date, {hours, minutes, seconds, microsecond}}) do
{date, {hours, minutes, seconds}}
|> NaiveDateTime.from_erl!({microsecond * 1000, 3})
|> DateTime.from_naive!("Etc/UTC")
|> DateTime.to_iso8601()
end
# defp get_level_rank(level) do
# case level do
# :debug -> 10
# :info -> 20
# :notice -> 30
# :warning -> 40
# :error -> 50
# :critical -> 60
# :alert -> 70
# :emergency -> 80
# end
# end
defp get_version(config) do
config.version
end
defp filter_metadata(metadata, %{metadata: nil}) do
metadata
end
defp filter_metadata(metadata, config) do
metadata
|> Enum.filter(fn
{key, _} -> key in config.metadata
end)
end
end