(MAINT) Add optional API Request Logging

This was partially an exercise to use middleware, but also to enable
basic logging for the API by logging all the API calls to the logger.
This commit is contained in:
John O'Connor 2020-06-26 20:49:17 +01:00
parent a21d8c5642
commit 85ff3f7022
17 changed files with 85 additions and 24 deletions

View file

@ -84,6 +84,7 @@ module Vmpooler
parsed_config[:config]['experimental_features'] = ENV['EXPERIMENTAL_FEATURES'] if ENV['EXPERIMENTAL_FEATURES']
parsed_config[:config]['purge_unconfigured_folders'] = ENV['PURGE_UNCONFIGURED_FOLDERS'] if ENV['PURGE_UNCONFIGURED_FOLDERS']
parsed_config[:config]['usage_stats'] = ENV['USAGE_STATS'] if ENV['USAGE_STATS']
parsed_config[:config]['request_logger'] = ENV['REQUEST_LOGGER'] if ENV['REQUEST_LOGGER']
parsed_config[:redis] = parsed_config[:redis] || {}
parsed_config[:redis]['server'] = ENV['REDIS_SERVER'] || parsed_config[:redis]['server'] || 'localhost'

View file

@ -9,7 +9,7 @@ module Vmpooler
# Load dashboard components
require 'vmpooler/dashboard'
def self.execute(torun, config, redis, metrics)
def self.execute(torun, config, redis, metrics, logger)
self.settings.set :config, config
self.settings.set :redis, redis unless redis.nil?
self.settings.set :metrics, metrics
@ -43,6 +43,9 @@ module Vmpooler
end
if torun.include? :api
# Enable API request logging only if required
use Vmpooler::API::RequestLogger, logger: logger if config[:config]['request_logger']
use Vmpooler::Dashboard
use Vmpooler::API::Dashboard
use Vmpooler::API::Reroute

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Vmpooler
class API
class RequestLogger
attr_reader :app
def initialize(app, options = {})
@app = app
@logger = options[:logger]
end
def call(env)
status, headers, body = @app.call(env)
@logger.log('s', "[ ] API: Method: #{env['REQUEST_METHOD']}, Status: #{status}, Path: #{env['PATH_INFO']}, Body: #{body}")
[status, headers, body]
end
end
end
end

View file

@ -6,9 +6,10 @@
#
# The code was also failing Rubocop on PR check, so have addressed all the offenses.
#
# The method strip_ids_from_path has been adapted to add a match for hostnames in paths
# to replace with a single ":hostname" string to avoid proliferation of stat lines for
# each new vm hostname deleted, modified or otherwise queried.
# The method strip_hostnames_from_path (originally strip_ids_from_path) has been adapted
# to add a match for hostnames in paths # to replace with a single ":hostname" string to
# avoid # proliferation of stat lines for # each new vm hostname deleted, modified or
# otherwise queried.
require 'benchmark'
require 'prometheus/client'
@ -91,12 +92,12 @@ module Vmpooler
counter_labels = {
code: code,
method: env['REQUEST_METHOD'].downcase,
path: strip_ids_from_path(env['PATH_INFO'])
path: strip_hostnames_from_path(env['PATH_INFO'])
}
duration_labels = {
method: env['REQUEST_METHOD'].downcase,
path: strip_ids_from_path(env['PATH_INFO'])
path: strip_hostnames_from_path(env['PATH_INFO'])
}
@requests.increment(labels: counter_labels)
@ -105,10 +106,11 @@ module Vmpooler
nil
end
def strip_ids_from_path(path)
def strip_hostnames_from_path(path)
# Custom for /vm path - so we just collect aggrate stats for all usage along this one
# path. Custom counters are then added more specific endpoints in v1.rb
# Since we aren't parsing UID/GIDs as in the original example, these are removed.
# Similarly, request IDs are also stripped from the /ondemand path.
path
.gsub(%r{/vm/.+$}, '/vm')
.gsub(%r{/ondemand/.+$}, '/ondemand')