diff --git a/src/bot.ts b/src/bot.ts
index a4ad3f165b76522bae8c7a28d2929214da578c02..388b017e47c9afb35ac0d58f50ab4ac1d85f2765 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -392,6 +392,7 @@ export class DiscordBot {
             }
             const channel = guild.channels.get(room);
             if (channel && channel.type === "text") {
+                this.ClientFactory.bindMetricsToChannel(channel as Discord.TextChannel);
                 const lookupResult = new ChannelLookupResult();
                 lookupResult.channel = channel as Discord.TextChannel;
                 lookupResult.botUser = this.bot.user.id === client.user.id;
@@ -451,6 +452,7 @@ export class DiscordBot {
                 // NOTE: Don't send replies to discord if we are a puppet.
                 msg = await chan.send(embed.description, opts);
             } else if (hook) {
+                MetricPeg.get.remoteCall("hook.send");
                 msg = await hook.send(embed.description, {
                     avatarURL: embed!.author!.icon_url,
                     embeds: embedSet.replyEmbed ? [embedSet.replyEmbed] : undefined,
@@ -542,6 +544,7 @@ export class DiscordBot {
         if (guild) {
             const channel = client.channels.get(entry.remote!.get("discord_channel") as string);
             if (channel) {
+                this.ClientFactory.bindMetricsToChannel(channel as Discord.TextChannel);
                 return channel;
             }
             throw Error("Channel given in room entry not found");
diff --git a/src/clientfactory.ts b/src/clientfactory.ts
index 54e2694ca422b4a611867f2eccb2c21dee170303..22ded344c65d527239db79d357ea56324f4c08a1 100644
--- a/src/clientfactory.ts
+++ b/src/clientfactory.ts
@@ -16,14 +16,12 @@ limitations under the License.
 
 import { DiscordBridgeConfigAuth } from "./config";
 import { DiscordStore } from "./store";
-import { Client as DiscordClient } from "discord.js";
+import { Client as DiscordClient, TextChannel } from "discord.js";
 import { Log } from "./log";
-import { Util } from "./util";
+import { MetricPeg } from "./metrics";
 
 const log = new Log("ClientFactory");
 
-const READY_TIMEOUT = 30000;
-
 export class DiscordClientFactory {
     private config: DiscordBridgeConfigAuth;
     private store: DiscordStore;
@@ -110,4 +108,12 @@ export class DiscordClientFactory {
             return this.botClient;
         }
     }
+
+    public bindMetricsToChannel(channel: TextChannel) {
+        // tslint:disable-next-line:only-arrow-functions
+        channel.send = function() {
+            MetricPeg.get.remoteCall("channel.send");
+            return channel.send.apply(channel, arguments);
+        };
+    }
 }
diff --git a/src/discordas.ts b/src/discordas.ts
index c39c2dba72f8d0add2ba3800b64788408cb3b363..2e989ceaab9566e27befd17dda64acb0c52db876 100644
--- a/src/discordas.ts
+++ b/src/discordas.ts
@@ -163,15 +163,14 @@ async function run(port: number, fileConfig: DiscordBridgeConfig) {
                + "The config option userStorePath no longer has any use.");
     }
 
-
     await bridge.run(port, config);
     log.info(`Started listening on port ${port}`);
 
     if (config.bridge.enableMetrics) {
         log.info("Enabled metrics");
-        MetricPeg.setMetrics(new PrometheusBridgeMetrics().init(bridge));
+        MetricPeg.set(new PrometheusBridgeMetrics().init(bridge));
     }
-    
+
     try {
         await store.init(undefined, bridge.getRoomStore(), bridge.getUserStore());
     } catch (ex) {
diff --git a/src/metrics.ts b/src/metrics.ts
index 698c0daf645d88173f8bba3a21cf9cd61d05bfbd..e322c77b54630f03f48867fcbdd6161bd8adab03 100644
--- a/src/metrics.ts
+++ b/src/metrics.ts
@@ -1,4 +1,4 @@
-import { PrometheusMetrics } from "matrix-appservice-bridge";
+import { PrometheusMetrics, Bridge } from "matrix-appservice-bridge";
 import { Gauge, Counter, Histogram } from "prom-client";
 import { Log } from "./log";
 
@@ -7,7 +7,7 @@ const log = new Log("BridgeMetrics");
 const REQUEST_EXPIRE_TIME_MS = 30000;
 
 interface IAgeCounter {
-    setGauge(gauge: Gauge, morelabels: any);
+    setGauge(gauge: Gauge, morelabels: string[]);
     bump(age: number);
 }
 
@@ -31,25 +31,24 @@ export interface IBridgeMetrics {
 }
 
 export class DummyBridgeMetrics implements IBridgeMetrics {
-    registerRequest() {}
-    requestOutcome() {}
-    remoteCall() {}
-    setPresenceCount() {}
-    storeCall() {}
+    public registerRequest() {}
+    public requestOutcome() {}
+    public remoteCall() {}
+    public setPresenceCount() {}
+    public storeCall() {}
 }
 
 export class MetricPeg {
-    private static _metrics: IBridgeMetrics = new DummyBridgeMetrics();
-    
-    public static get get() : IBridgeMetrics {
-        return this._metrics;
+    public static get get(): IBridgeMetrics {
+        return this.metrics;
     }
-    
-    public static setMetrics(metrics: IBridgeMetrics) {
-        this._metrics = metrics;
+
+    public static set(metrics: IBridgeMetrics) {
+        this.metrics = metrics;
     }
-}
 
+    private static metrics: IBridgeMetrics = new DummyBridgeMetrics();
+}
 
 export class PrometheusBridgeMetrics implements IBridgeMetrics {
     private metrics;
@@ -60,45 +59,46 @@ export class PrometheusBridgeMetrics implements IBridgeMetrics {
     private matrixRequest: Histogram;
     private requestsInFlight: Map<string, number>;
     private bridgeGauges: IBridgeGauges = {
-        matrixRoomConfigs: 0,
-        remoteRoomConfigs: 0,
         matrixGhosts: 0,
-        remoteGhosts: 0,
+        matrixRoomConfigs: 0,
         matrixRoomsByAge: new AgeCounters(),
-        remoteRoomsByAge: new AgeCounters(),
         matrixUsersByAge: new AgeCounters(),
+        remoteGhosts: 0,
+        remoteRoomConfigs: 0,
+        remoteRoomsByAge: new AgeCounters(),
         remoteUsersByAge: new AgeCounters(),
     };
 
-    public init(bridge: any) {
+    public init(bridge: Bridge) {
         this.metrics = new PrometheusMetrics();
         this.metrics.registerMatrixSdkMetrics();
         this.metrics.registerBridgeGauges(() => this.bridgeGauges);
         this.metrics.addAppServicePath(bridge);
         this.remoteCallCounter = this.metrics.addCounter({
-            name: "remote_api_calls",
             help: "Count of remote API calls made",
             labels: ["method"],
+            name: "remote_api_calls",
         });
         this.storeCallCounter = this.metrics.addCounter({
-            name: "store_calls",
             help: "Count of store function calls made",
             labels: ["method", "cached"],
+            name: "store_calls",
         });
         this.presenceGauge = this.metrics.addGauge({
-            name: "active_presence_users",
             help: "Count of users in the presence queue",
             labels: [],
+
+            name: "active_presence_users",
         });
         this.matrixRequest = this.metrics.addTimer({
-            name: "matrix_request_seconds",
             help: "Histogram of processing durations of received Matrix messages",
             labels: ["outcome"],
+            name: "matrix_request_seconds",
         });
         this.remoteRequest = this.metrics.addTimer({
-            name: "remote_request_seconds",
             help: "Histogram of processing durations of received remote messages",
             labels: ["outcome"],
+            name: "remote_request_seconds",
         });
         this.requestsInFlight = new Map();
         setInterval(() => {
@@ -107,7 +107,7 @@ export class PrometheusBridgeMetrics implements IBridgeMetrics {
                     this.requestsInFlight.delete(id);
                 }
             });
-        }, REQUEST_EXPIRE_TIME_MS)
+        }, REQUEST_EXPIRE_TIME_MS);
         return this;
     }
 
@@ -121,7 +121,7 @@ export class PrometheusBridgeMetrics implements IBridgeMetrics {
         if (!startTime) {
             log.verbose(`Got "requestOutcome" for ${id}, but this request was never started`);
             return;
-        } 
+        }
         const duration = Date.now() - startTime;
         (isRemote ? this.remoteRequest : this.matrixRequest).observe({outcome}, duration / 1000);
     }
@@ -137,5 +137,4 @@ export class PrometheusBridgeMetrics implements IBridgeMetrics {
     public storeCall(method: string, cached: boolean) {
         this.storeCallCounter.inc({method, cached: cached ? "yes" : "no"});
     }
-};
-
+}
diff --git a/test/mocks/discordclientfactory.ts b/test/mocks/discordclientfactory.ts
index 803dedc118f7cacbb9c44443840dee85c06c4c4b..b174f3d5f9455581b13c2a3460f4eee4a32caa7d 100644
--- a/test/mocks/discordclientfactory.ts
+++ b/test/mocks/discordclientfactory.ts
@@ -31,4 +31,6 @@ export class DiscordClientFactory {
         }
         return this.botClient;
     }
+
+    public bindMetricsToChannel() {}
 }
diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts
index f6208be1d18c3d8d32377f56c27a94458ddcde8f..173517038ad91f19d6b10305187c00862ec3ae97 100644
--- a/test/test_discordbot.ts
+++ b/test/test_discordbot.ts
@@ -453,7 +453,7 @@ describe("DiscordBot", () => {
             bot.lockChannel(chan);
             await bot.waitUnlock(chan);
             const diff = Date.now() - t;
-            expect(diff).to.be.greaterThan(SHORTDELAY - 1);
+            expect(diff).to.be.greaterThan(SHORTDELAY - 5);
         });
     });
   // });
diff --git a/tslint.json b/tslint.json
index cd7de561c3b3ba02450df7cb5bf011afd9c73be2..ff80b039be7c4830651871937b672e77c31faca3 100644
--- a/tslint.json
+++ b/tslint.json
@@ -9,7 +9,7 @@
     "object-literal-sort-keys": "off",
     "no-any": true,
     "arrow-return-shorthand": true,
-    "no-magic-numbers": true,
+    "no-magic-numbers": [true, -1, 0, 1, 1000],
     "prefer-for-of": true,
     "typedef": {
       "severity": "warning"