FEATURE: Add 'verb' field to web metric. (#2)

FEATURE: Add ‘verb’ field to web metric. (#2)

diff --git a/lib/collector.rb b/lib/collector.rb
index a20a57b..bab3206 100644
--- a/lib/collector.rb
+++ b/lib/collector.rb
@@ -243,7 +243,7 @@ module ::DiscoursePrometheus
           "web"
         end
 
-      hash = { db: db, api: api_type }
+      hash = { db: db, api: api_type, verb: metric.verb }
       if metric.background
         hash[:type] = "background"
         # hijacked but never got the actual status, message bus
diff --git a/lib/internal_metric/web.rb b/lib/internal_metric/web.rb
index 0e7463f..d21d014 100644
--- a/lib/internal_metric/web.rb
+++ b/lib/internal_metric/web.rb
@@ -32,6 +32,7 @@ module DiscoursePrometheus::InternalMetric
     }
 
     STRING_ATTRS = %w{
+      verb
       controller
       action
       host
@@ -42,6 +43,8 @@ module DiscoursePrometheus::InternalMetric
       attribute attr
     end
 
+    ALLOWED_REQUEST_METHODS = Set["HEAD", "GET", "PUT", "POST", "DELETE"]
+
     def self.get(hash)
       metric = new
       hash.each do |k, v|
@@ -77,6 +80,9 @@ module DiscoursePrometheus::InternalMetric
       metric.admin_api = !!env['_DISCOURSE_API']
       metric.user_api = !!env['_DISCOURSE_USER_API']
 
+      metric.verb = env['REQUEST_METHOD']
+      metric.verb = 'OTHER' if !ALLOWED_REQUEST_METHODS.include?(metric.verb)
+
       if ad_params = env['action_dispatch.request.parameters']
         metric.controller = ad_params['controller']
         metric.action = ad_params['action']
diff --git a/spec/lib/collector_spec.rb b/spec/lib/collector_spec.rb
index 0633f9b..912cc4a 100644
--- a/spec/lib/collector_spec.rb
+++ b/spec/lib/collector_spec.rb
@@ -111,14 +111,14 @@ module DiscoursePrometheus
 
     it "Can count metrics correctly" do
       metrics = []
-      metrics << InternalMetric::Web.get(tracked: true, status_code: 200, db: "bob")
-      metrics << InternalMetric::Web.get(tracked: true, status_code: 200, db: "bob")
-      metrics << InternalMetric::Web.get(tracked: true, logged_in: true, status_code: 200, db: "bill")
-      metrics << InternalMetric::Web.get(tracked: true, mobile: true, status_code: 200, db: "jake")
-      metrics << InternalMetric::Web.get(tracked: false, status_code: 200, db: "bob", user_api: true)
-      metrics << InternalMetric::Web.get(tracked: false, status_code: 300, db: "bob", admin_api: true)
-      metrics << InternalMetric::Web.get(tracked: false, background: true, status_code: 418, db: "bob")
-      metrics << InternalMetric::Web.get(tracked: false, background: true, status_code: 200, db: "bob")
+      metrics << InternalMetric::Web.get(tracked: true, verb: "GET", status_code: 200, db: "bob")
+      metrics << InternalMetric::Web.get(tracked: true, verb: "GET", status_code: 200, db: "bob")
+      metrics << InternalMetric::Web.get(tracked: true, verb: "GET", logged_in: true, status_code: 200, db: "bill")
+      metrics << InternalMetric::Web.get(tracked: true, verb: "GET", mobile: true, status_code: 200, db: "jake")
+      metrics << InternalMetric::Web.get(tracked: false, verb: "GET", status_code: 200, db: "bob", user_api: true)
+      metrics << InternalMetric::Web.get(tracked: false, verb: "GET", status_code: 300, db: "bob", admin_api: true)
+      metrics << InternalMetric::Web.get(tracked: false, verb: "GET", background: true, status_code: 418, db: "bob")
+      metrics << InternalMetric::Web.get(tracked: false, verb: "GET", background: true, status_code: 200, db: "bob")
 
       collector = Collector.new
       metrics.each do |metric|
@@ -139,13 +139,13 @@ module DiscoursePrometheus
 
       http_requests = exported.find { |m| m.name == "http_requests" }
       expected = {
-        { db: "bob", api: "web", type: "regular", status: 200 } => 2,
-        { db: "bill", api: "web", type: "regular", status: 200 } => 1,
-        { db: "jake", api: "web", type: "regular", status: 200 } => 1,
-        { db: "bob", api: "user", type: "regular", status: 200 } => 1,
-        { db: "bob", api: "admin", type: "regular", status: 300 } => 1,
-        { db: "bob", api: "web", type: "background", status: "-1" } => 1,
-        { db: "bob", api: "web", type: "background", status: 200 } => 1
+        { db: "bob", api: "web", verb: "GET", type: "regular", status: 200 } => 2,
+        { db: "bill", api: "web", verb: "GET", type: "regular", status: 200 } => 1,
+        { db: "jake", api: "web", verb: "GET", type: "regular", status: 200 } => 1,
+        { db: "bob", api: "user", verb: "GET", type: "regular", status: 200 } => 1,
+        { db: "bob", api: "admin", verb: "GET", type: "regular", status: 300 } => 1,
+        { db: "bob", api: "web", verb: "GET", type: "background", status: "-1" } => 1,
+        { db: "bob", api: "web", verb: "GET", type: "background", status: 200 } => 1
       }
       expect(http_requests.data).to eq(expected)
     end
diff --git a/spec/lib/internal_metric/web_spec.rb b/spec/lib/internal_metric/web_spec.rb
index 4878bc6..8a087f0 100644
--- a/spec/lib/internal_metric/web_spec.rb
+++ b/spec/lib/internal_metric/web_spec.rb
@@ -102,6 +102,24 @@ module DiscoursePrometheus::InternalMetric
         expect(metric.json).to eq(true)
       end
 
+      it "Can detect request method" do
+        env = {
+          "REQUEST_METHOD" => "GET"
+        }
+
+        metric = Web.from_env_data(env, {}, "")
+
+        expect(metric.verb).to eq("GET")
+
+        env = {
+          "REQUEST_METHOD" => "TEST"
+        }
+
+        metric = Web.from_env_data(env, {}, "")
+
+        expect(metric.verb).to eq("OTHER")
+      end
+
       it "Can fish out timings if available" do
         data = {
           timing: {

GitHub sha: c1b752f2

1 Like

Nice, next step is to upgrade our graphs to show this!

1 Like