Runtime diagnostics that run inside a Dala app's BEAM. Designed to be invoked via Erlang RPC from a developer's machine to inspect the actual state of a deployed app.
Pairs with dala_dev's tooling — mix dala.verify_strip calls into
verify_loaded_modules/0. Kept in the dala library (not dala_dev)
so the functions are present in every shipped app, not just at build
time on the developer's machine.
Security warnings
This module is a permanent target for remote execution if distribution credentials leak. Any node that can connect to your app's Erlang node can call these functions.
Mitigation strategies
Use strong, unique cookies — generate per-app random cookies:
cookie = Dala.Dist.cookie_from_env("MY_APP_DIST_COOKIE", "my_app")Never commit cookies to source control.
Rotate cookies periodically using
Node.set_cookie/1.Limit network exposure — use firewalls/VPC to restrict port 9100 and 4369 access to trusted machines only.
Strip in production — consider removing or disabling this module in release builds by setting
dala_RELEASE=1or using code trimming.Monitor connections — log and alert on unexpected
Node.connectattempts in production.
Don't expand the API surface here without thinking — anything added is permanently shipped to every Dala app and a permanent target for remote-execution if dist credentials leak.
Summary
Functions
Snapshot of what's currently loaded in the running BEAM, plus what's shipped-but-never-loaded (the empirical strip candidates).
Force-load every .beam file under the running app's OTP tree and
report any that fail. Used by mix dala.verify_strip to validate
that an aggressive strip didn't remove a module something else
needed.
Types
@type load_report() :: %{ total: non_neg_integer(), loaded: non_neg_integer(), failed: [load_failure()], elapsed_us: non_neg_integer(), otp_root: String.t() | nil }
@type loaded_snapshot() :: %{ loaded: [module()], loaded_count: non_neg_integer(), shipped_count: non_neg_integer(), unloaded_in_bundle: [module()], otp_root: String.t() | nil, captured_at: DateTime.t() }
Functions
@spec loaded_snapshot() :: loaded_snapshot()
Snapshot of what's currently loaded in the running BEAM, plus what's shipped-but-never-loaded (the empirical strip candidates).
In interactive mode (Dala's default), a module is loaded only when something calls into it. So the loaded set after a representative user session is "what the app actually needs." Anything in the bundle but not in the loaded set is a strong strip candidate.
Better than tracing for our purposes: zero overhead, no rate-limit worries, no risk of mailbox-overflowing a busy app.
Workflow:
- Deploy the app
- User exercises every flow they care about
- RPC
Dala.Diag.loaded_snapshot/0from a Mix task - Cross-reference
:unloaded_in_bundlewith the static audit: shipped + statically-reachable + never-loaded = high-confidence strip candidates.
Caveats: a flow that wasn't exercised won't show up. Run after a thorough session, not after just opening the app.
@spec verify_loaded_modules() :: load_report()
Force-load every .beam file under the running app's OTP tree and
report any that fail. Used by mix dala.verify_strip to validate
that an aggressive strip didn't remove a module something else
needed.
Walks all entries in :code.get_path/0, finds the OTP root from
the first matching .../otp/lib/... path, and enumerates .beam
files under it.
Returns load_report/0. Failures usually mean a stripped lib
contained a transitive dependency of a kept module.