Skip to content

Instantly share code, notes, and snippets.

@andrewpage
Last active April 12, 2022 22:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andrewpage/ddaa21ad929027c849e85aa5ba1acac7 to your computer and use it in GitHub Desktop.
Save andrewpage/ddaa21ad929027c849e85aa5ba1acac7 to your computer and use it in GitHub Desktop.
Report Phusion Passenger metrics to AWS CloudWatch.
#!/usr/bin/env ruby
#
# Report Instance Count and Request Queue Size metrics from locally running Phusion Passenger instance.
# Author: Andrew Page <andrew@andrewpage.me>
# ==
# Phusion Passenger: https://www.phusionpassenger.com
require 'net/http'
require 'phusion_passenger'
require 'aws-sdk'
PhusionPassenger.locate_directories
PhusionPassenger.require_passenger_lib 'admin_tools/instance_registry'
include PhusionPassenger::AdminTools
# Extract a parameter from the Passenger pool status output.
def extract_metric(parameter, output)
pattern = %r{#{parameter}\s+:\s+(?<result>\d+)}
match = output.match(pattern)
match['result'] if match
end
# Get the Passenger pool status for our active instance,
def get_pool_status(instance)
request = Net::HTTP::Get.new('/pool.txt')
# Authenticate the HTTP request to the Passenger API.
request.basic_auth('ro_admin', instance.read_only_admin_password)
# Request pool status
response = instance.http_request('agents.s/core_api', request)
response.body
end
# Generate the metric to report to CloudWatch.
def build_cloudwatch_metric(metric_name, value, instance_id:, timestamp: Time.now)
{
metric_name: metric_name,
timestamp: timestamp,
value: value,
storage_resolution: 1,
dimensions: [
{
name: 'InstanceId',
value: instance_id
}
]
}
end
instances = InstanceRegistry.new.list
if instances.count > 1
$stderr.puts 'Multiple Passenger instances... not sure which to use. Exiting.'
exit(1)
end
# Get pool status from Passenger instance.
instance = instances.first
output = get_pool_status(instance)
# Extract key metrics from Passenger output.
timestamp = Time.now
process_count = extract_metric('Processes', output)
request_queue_size = extract_metric('Requests in queue', output)
# Get current instance ID
instance_id = Net::HTTP.get(URI('http://169.254.169.254/latest/meta-data/instance-id'))
# Report metrics to AWS CloudWatch.
cloudwatch = Aws::CloudWatch::Client.new
cloudwatch.put_metric_data(
namespace: 'Passenger',
metric_data: [
build_cloudwatch_metric('ProcessCount', process_count, instance_id: instance_id, timestamp: timestamp),
build_cloudwatch_metric('RequestQueueSize', request_queue_size, instance_id: instance_id, timestamp: timestamp)
]
)
$stderr.puts "Reported Passenger process count of #{process_count} and request queue size of #{request_queue_size} to CloudWatch."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment