Packages
EndPointBlank Elixir client library: authorization plus request/response/error/log ingestion (with masking, batching, timeouts, and a bounded queue) — also used for self-monitoring.
Current section
Files
Jump to
Current section
Files
lib/end_point_blank/config.ex
defmodule EndPointBlank.Config do
@moduledoc """
Singleton configuration store for the EndPointBlank library.
Backed by an Agent so all processes share the same config.
Update via `EndPointBlank.configure/1`.
Several settings also fall back to `ENDPOINTBLANK_*` environment
variables when not explicitly configured, in order to support
Rails-free (and Elixir-config-free) deployments. Precedence for each
such setting is: explicit value set via `EndPointBlank.configure/1` >
`System.get_env/1` > built-in default. The environment variable is
read at getter time (not cached), so it can be changed at runtime.
"""
use Agent
@default_base_url "https://in.endpointblank.com"
@default_log_base_url "https://log.endpointblank.com"
defstruct [
:client_id,
:client_secret,
:app_name,
:environment,
:application_version,
:version_finder,
:token_ttl,
:mask_hook,
:base_url,
:log_base_url,
log_mode: :direct,
worker_count: 4,
cache_ttl: 300,
masking_rules: []
]
def start_link(_opts) do
Agent.start_link(fn -> %__MODULE__{} end, name: __MODULE__)
end
def get, do: Agent.get(__MODULE__, &resolve/1)
def update(opts) when is_list(opts) do
Agent.update(__MODULE__, fn config ->
Enum.reduce(opts, config, fn {k, v}, acc ->
if Map.has_key?(acc, k), do: Map.put(acc, k, v), else: acc
end)
end)
end
@doc false
def reset, do: Agent.update(__MODULE__, fn _ -> %__MODULE__{} end)
# Applies the ENDPOINTBLANK_* env-var fallback (and built-in defaults)
# to a stored config, without mutating what's actually stored. Reading
# System.get_env/1 here (rather than caching it in the struct) lets
# tests toggle env vars per-example.
defp resolve(config) do
%{
config
| client_id: config.client_id || System.get_env("ENDPOINTBLANK_CLIENT_ID"),
client_secret: config.client_secret || System.get_env("ENDPOINTBLANK_CLIENT_SECRET"),
base_url:
config.base_url || System.get_env("ENDPOINTBLANK_BASE_URL") || @default_base_url,
log_base_url:
config.log_base_url || System.get_env("ENDPOINTBLANK_LOG_BASE_URL") ||
@default_log_base_url,
app_name: config.app_name || System.get_env("ENDPOINTBLANK_APP_NAME"),
environment: config.environment || System.get_env("ENDPOINTBLANK_ENV")
}
end
# Config readers
def masking_rules, do: get().masking_rules
def mask_hook, do: get().mask_hook
@doc """
Max number of concurrent writes `DelayedWriter` performs per flush tick.
Falls back to the struct default (4) if unset or invalid.
"""
def worker_count do
case get().worker_count do
n when is_integer(n) and n > 0 -> n
_ -> 4
end
end
# URL builders
def authorize_url, do: get().base_url <> "/api/authorize"
def endpoint_update_url, do: get().base_url <> "/api/application_updates"
def access_token_url, do: get().base_url <> "/api/access_token"
def requests_url, do: get().log_base_url <> "/api/application_requests"
def responses_url, do: get().log_base_url <> "/api/application_responses"
def logs_url, do: get().log_base_url <> "/api/application_logs"
def errors_url, do: get().log_base_url <> "/api/application_errors"
end