diff --git a/README.md b/README.md
index 5f0bf883f79df7b447d8c9fbd3b4102072a8efbc..a3e7026c4e4d15a72fbdef4629ddc756f579f112 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,9 @@ yarn build
 - `mobile` - Force mobile mode
 - `no_stats` - Disable performance stats
 - `vr_entry_type` - Either "gearvr" or "daydream". Used internally to force a VR entry type
+- `disable_telemetry` - If `true` disables Sentry telemetry.
+- `log_filter` - A `debug` style filter for setting the logging level.
+- `debug` - If `true` performs verbose logging of Janus and NAF traffic.
 
 ## Additional Resources
 
diff --git a/src/hub.js b/src/hub.js
index 8bd8e2a29f9dbe957b0c20cd2798c160fbe7ede0..97470e1db7add15cec671b179c3e4f3568c087a6 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -6,6 +6,7 @@ import { patchWebGLRenderingContext } from "./utils/webgl";
 patchWebGLRenderingContext();
 
 import "aframe-xr";
+import debug from "debug";
 import "./vendor/GLTFLoader";
 import "networked-aframe/src/index";
 import "naf-janus-adapter";
@@ -129,11 +130,19 @@ function qsTruthy(param) {
 }
 
 const isBotMode = qsTruthy("bot");
+const isTelemetryDisabled = qsTruthy("disable_telemetry");
+const isDebug = qsTruthy("debug");
+const logFilter = qs["log_filter"] || (isDebug && "naf-janus-adapter:*");
 
-if (!isBotMode) {
+if (!isBotMode && !isTelemetryDisabled) {
   registerTelemetry();
 }
 
+// NOTE: this needs to happen after a-frame's `utils/debug.js` file has been eval'ed because it overwrites any prior debug settings :/
+if (logFilter) {
+  debug.enable(logFilter);
+}
+
 disableiOSZoom();
 
 AFRAME.registerInputBehaviour("trackpad_dpad4", trackpad_dpad4);
@@ -240,6 +249,10 @@ const onReady = async () => {
       serverURL: process.env.JANUS_SERVER
     });
 
+    if (isDebug) {
+      scene.setAttribute("networked-scene", { debug: true });
+    }
+
     scene.setAttribute("stats-plus", false);
 
     if (isMobile || qsTruthy("mobile")) {
@@ -310,12 +323,17 @@ const onReady = async () => {
       scene.components["networked-scene"].connect().catch(connectError => {
         // hacky until we get return codes
         const isFull = connectError.error && connectError.error.msg.match(/\bfull\b/i);
+        console.error(connectError);
         remountUI({ roomUnavailableReason: isFull ? "full" : "connect_error" });
         exitScene();
 
         return;
       });
 
+      if (isDebug) {
+        NAF.connection.adapter.session.options.verbose = true;
+      }
+
       if (isBotMode) {
         playerRig.setAttribute("avatar-replay", {
           camera: "#player-camera",