Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter structs in MapFilter #507

Merged
merged 5 commits into from Sep 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
76 changes: 52 additions & 24 deletions lib/appsignal/utils/map_filter.ex
Expand Up @@ -32,43 +32,71 @@ defmodule Appsignal.Utils.MapFilter do
Application.get_env(:appsignal, :config)[:filter_session_data] || []
end

defp discard_values(%{__struct__: mod} = struct, _params) when is_atom(mod) do
defp discard_values(list, filter_keys) when is_list(list) do
discard_values(list, filter_keys, [])
end

defp discard_values(%{__struct__: _} = struct, filter_keys) do
struct
|> Map.from_struct()
|> discard_values(filter_keys)
end

defp discard_values(map, filter_keys) when is_map(map) do
map
|> Map.to_list()
|> discard_values(filter_keys, [])
|> Enum.into(%{})
end

defp discard_values(value, _filter_keys), do: value

defp discard_values([{key, value} | tail], filter_keys, acc) do
if (is_binary(key) or is_atom(key)) and to_string(key) in filter_keys do
discard_values(tail, filter_keys, [{key, "[FILTERED]"} | acc])
else
discard_values(tail, filter_keys, [{key, discard_values(value, filter_keys)} | acc])
end
end

defp discard_values([value | tail], filter_keys, acc) do
discard_values(tail, filter_keys, [discard_values(value, filter_keys) | acc])
end

defp discard_values(%{} = map, params) do
Enum.into(map, %{}, fn {k, v} ->
if (is_binary(k) or is_atom(k)) and String.contains?(to_string(k), params) do
{k, "[FILTERED]"}
else
{k, discard_values(v, params)}
end
end)
defp discard_values([], _filter_keys, acc), do: acc

defp keep_values(list, keep_keys) when is_list(list) do
keep_values(list, keep_keys, [])
end

defp discard_values([_ | _] = list, params) do
Enum.map(list, &discard_values(&1, params))
defp keep_values(%{__struct__: _} = struct, keep_keys) do
struct
|> Map.from_struct()
|> keep_values(keep_keys)
end

defp discard_values(other, _params), do: other
defp keep_values(map, keep_keys) when is_map(map) do
map
|> Map.to_list()
|> keep_values(keep_keys, [])
|> Enum.into(%{})
end

defp keep_values(%{__struct__: mod}, _params) when is_atom(mod), do: "[FILTERED]"
defp keep_values(_value, _keep_keys), do: "[FILTERED]"

defp keep_values(%{} = map, params) do
Enum.into(map, %{}, fn {k, v} ->
if (is_binary(k) or is_atom(k)) and to_string(k) in params do
{k, discard_values(v, [])}
else
{k, keep_values(v, params)}
end
end)
defp keep_values([{key, value} | tail], keep_keys, acc) do
if (is_binary(key) or is_atom(key)) and to_string(key) in keep_keys do
keep_values(tail, keep_keys, [{key, discard_values(value, [])} | acc])
else
keep_values(tail, keep_keys, [{key, keep_values(value, keep_keys)} | acc])
end
end

defp keep_values([_ | _] = list, params) do
Enum.map(list, &keep_values(&1, params))
defp keep_values([value | tail], keep_keys, acc) do
keep_values(tail, keep_keys, [keep_values(value, keep_keys) | acc])
end

defp keep_values(_other, _params), do: "[FILTERED]"
defp keep_values([], _keep_keys, acc), do: acc

defp merge_filters(appsignal, phoenix) when is_list(appsignal) and is_list(phoenix) do
appsignal ++ phoenix
Expand Down