Skip to content

Instantly share code, notes, and snippets.

@jeroneemou
Created June 4, 2019 16:30
Show Gist options
  • Save jeroneemou/81787383360496ff0c1ef31bc18fb0ed to your computer and use it in GitHub Desktop.
Save jeroneemou/81787383360496ff0c1ef31bc18fb0ed to your computer and use it in GitHub Desktop.
Health check with memory monitoring of Elastic Beanstalk instance and push to CloudWatch (SDK v2)
<?php
namespace Curved\Health;
use Aws\CloudWatch\CloudWatchClient;
require __DIR__ . '/../vendor/autoload.php';
class HealthInfo
{
/**
* @var Aws\CloudWatch\CloudWatchClient
*/
private $client;
/**
* @var String
*/
private $instanceId;
/**
* WARNING: Only works on linux!
*/
const MEMORY_INFO_FILE = '/proc/meminfo';
const MEM_TOTAL = 'MemTotal';
const MEM_FREE = 'MemFree';
const MEM_USAGE = 'Usage';
const MEM_PUSH = 'MetricPush';
const ERR_FETCH = 'Unable to fetch memory information';
/**
* HealthInfo constructor.
*/
public function __construct()
{
$this->client = CloudWatchClient::factory([
'profile' => 'default',
'region' => 'eu-central-1',
'version' => '2010-08-01'
]);
$this->instanceId = $this->getInstanceId();
}
/**
* Try to figure out the ec2 instance ID
*
* @return string
*/
private function getInstanceId()
{
// Default so we know its wrong but still value
$instanceId = 'empty';
$instanceInformation = file_get_contents('http://169.254.169.254/latest/dynamic/instance-identity/document');
if (!$instanceInformation) {
return $instanceId;
}
// More info on https://stackoverflow.com/questions/625644/how-to-get-the-instance-id-from-within-an-ec2-instance/19912843
$instance = json_decode($instanceInformation,true);
if (isset($instance['instanceId'])) {
$instanceId = $instance['instanceId'];
}
return $instanceId;
}
/**
* @return array|string
*/
private function getSystemMemInfo()
{
$memoryInfo = [];
try {
$usage = $this->getMemoryUsage();
$memoryInfo[self::MEM_USAGE] = $usage;
$result = $this->client->putMetricData(array(
'Namespace' => 'Portal Application',
'MetricData' => array(
array(
'MetricName' => 'FreeMemory',
'Dimensions' => [
[
'Name' => 'InstanceId',
'Value' => $this->instanceId,
],
],
'Timestamp' => time(),
'Value' => $usage,
'Unit' => 'Percent'
)
)
));
$memoryInfo[self::MEM_PUSH] = $result;
} catch (\Exception $e) {
$memoryInfo[self::MEM_PUSH] = $e->getMessage();
}
return $memoryInfo;
}
/**
* @return float|int
* @throws \Exception
*/
private function getMemoryUsage()
{
if (!file_exists(self::MEMORY_INFO_FILE)) {
throw new \Exception(self::ERR_FETCH . ' :: File does not exists: ' . self::MEMORY_INFO_FILE);
}
$file = file_get_contents(self::MEMORY_INFO_FILE);
if (!$file) {
throw new \Exception(self::ERR_FETCH . ' :: File could not be opened: ' . self::MEMORY_INFO_FILE);
}
$data = explode("\n", $file);
$parsedData = [];
foreach ($data as $line) {
$keyValue = explode(":", $line);
if (count($keyValue) < 2) continue; // To be sure there is key / value within a row
list($key, $val) = $keyValue;
$parsedData[$key] = trim($val);
}
if (!isset($parsedData[self::MEM_TOTAL]) || !isset($parsedData[self::MEM_FREE])) {
throw new \Exception(self::ERR_FETCH . ' :: Data unavailable.');
}
$total = $parsedData[self::MEM_TOTAL];
$free = $parsedData[self::MEM_FREE];
return round((100 / $total) * $free);
}
/**
* @return false|mixed|string|void
*/
public function report()
{
$report = [
'status' => 'OK',
'system' => [
'instanceId' => $this->instanceId,
'memory' => $this->getSystemMemInfo(),
],
];
return json_encode($report);
}
}
$info = new HealthInfo();
echo $info->report();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment