Compare commits

..

3 Commits

Author SHA1 Message Date
0f50e874d4
Added Dockerfile for PHP with Apache
This commit introduces a new Dockerfile that sets up a PHP 8.3 environment with Apache. It includes the following significant changes:
- Sets the working directory to /var/www/html
- Copies current directory contents into the container
- Installs Composer and activates mod_rewrite
- Installs Process Control extension using curl command
- Runs composer install to fetch dependencies
- Exposes port 9050 and modifies Apache configuration to listen on this port
- Adds environment variables to Apache configuration 
- Changes ownership of /var/www/html to www-data user 
- Starts the Apache server using apache2-foreground command
2024-06-13 13:42:19 +02:00
f367958d69
Introduced .htaccess file and refactored index.php
A new .htaccess file has been added to handle URL rewriting. The index.php file has been significantly refactored for improved readability and performance. A large portion of the original code was moved to a separate script.php file, which is now executed from within index.php. This change simplifies the main entry point of the application and separates concerns more effectively. Additionally, minor changes were made to cache handling in script.php.
2024-06-13 13:41:31 +02:00
3021ec4436
Added newline for better readability in metrics template
A newline has been added to the metrics.twig template to improve code readability. This change separates different sections of the code, making it easier to understand and maintain.
2024-06-13 13:40:35 +02:00
5 changed files with 190 additions and 138 deletions

4
.htaccess Normal file
View File

@ -0,0 +1,4 @@
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]

42
dockerfile Normal file
View File

@ -0,0 +1,42 @@
# Gebruik een officiële PHP-image met Apache
FROM php:8.3-apache
# Stel de werkdirectory in
WORKDIR /var/www/html
# Kopieer de huidige directory inhoud naar /var/www/html in de container
COPY . /var/www/html
# Installeer Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Activeer mod_rewrite
RUN a2enmod rewrite
# Installeer de Process Control extension
RUN curl -sSL https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions -o - | sh -s pcntl zip
# Voer composer install uit om de afhankelijkheden te installeren
RUN composer install
# Stel de poort in die de container zal exposeren
EXPOSE 9050
# Wijzig de Apache configuratie om op poort 9050 te luisteren
RUN sed -i 's/Listen 80/Listen 9050/' /etc/apache2/ports.conf
RUN sed -i 's/<VirtualHost *:80>/<VirtualHost *:9050>/' /etc/apache2/sites-available/000-default.conf
# Voeg environment variables toe aan de Apache configuratie
ENV PHP_BINARY=/usr/local/bin/php
ENV CONFIG_FILE=/var/www/html/config.php
# Activeer mod_rewrite
RUN a2enmod rewrite
# Start de Apache server
RUN mkdir -p /var/www/html/twig_cache
RUN chown -R www-data:www-data /var/www/html
USER www-data
# Start de Apache server
CMD ["apache2-foreground"]

143
index.php
View File

@ -1,139 +1,6 @@
<?php
require 'vendor/autoload.php';
$configFile = getenv('CONFIG_FILE') ?: 'config.php';
$cacheFile = $configFile . '.cache.json';
if (file_exists($configFile)) {
require ($configFile);
} else {
echo ("Configuration file not found: " . $configFile);
exit(1);
}
if(file_exists($cacheFile)) {
$oldconfig = json_decode(file_get_contents($cacheFile), true);
} else {
$oldconfig = [];
}
if(php_sapi_name() == 'cli' || $_SERVER["REQUEST_URI"] == '/metrics') {
header('Content-Type: text/plain; version=0.0.4');
foreach ($config as $key => &$metric) {
if (!isset($metric['submetrics'])) {
$metric['submetrics'] = [$metric];
}
foreach ($metric['submetrics'] as $subkey => &$submetric) {
$pid = pcntl_fork();
if ($pid > 0) {
$pids[] = $pid;
} else {
if (isset($submetric['command'])) {
$output = null;
$retval = null;
try {
exec($submetric['command'], $output, $retval);
$output = implode("\n", $output);
} catch (Exception $e) {
$output = '';
}
} elseif (isset($submetric['http'])) {
$client = new GuzzleHttp\Client();
$options = [];
$output = NULL;
if (isset($submetric['http']['proxy'])) {
$options['proxy'] = $submetric['http']['proxy'];
}
if (isset($submetric['http']['data']) && $submetric['http']['data'] == 'responsetime') {
$options['on_stats'] = function (GuzzleHttp\TransferStats $stats) use (&$output) {
$output = $stats->getTransferTime();
};
}
$hasresponse = NULL;
try {
$res = $client->request('GET', $submetric['http']['url'], $options);
$hasresponse = true;
} catch (GuzzleHttp\Exception\GuzzleException $e) {
if (method_exists($e, 'getResponse')) {
$res = $e->getResponse();
$hasresponse = true;
} else {
$hasresponse = false;
}
}
if (isset($submetric['http']['data']) && $submetric['http']['data'] == 'responsebody') {
if ($hasresponse) {
$output = $res->getBody()->getContents();
} else {
$output = '';
}
} elseif ((isset($submetric['http']['statuscode'])) && (isset($submetric['http']['data']) && $submetric['http']['data'] == 'hasresponse')) {
if ($hasresponse) {
$output = $output = (int)in_array($res->getStatusCode(), $submetric['http']['statuscode']);;
} else {
$output = 0;
}
} elseif (isset($submetric['http']['data']) && $submetric['http']['data'] == 'hasresponse') {
$output = (int)$hasresponse;
}
}
if (isset($submetric['jsonelem'])) {
$submetric['value'] = getArrayValue($submetric['jsonelem'], json_decode($output, true));
} else {
$submetric['value'] = $output;
}
if (is_bool($submetric['value'])) $submetric['value'] = $submetric['value'] ? 1 : 0;
file_put_contents('/tmp/.metrics.' . $key . '.' . $subkey, $submetric['value']);
exit();
}
}
}
foreach ($pids as $pid) {
pcntl_waitpid($pid, $none);
}
foreach ($config as $key => &$metric) {
foreach ($metric['submetrics'] as $subkey => &$submetric) {
$submetric['value'] = file_get_contents('/tmp/.metrics.' . $key . '.' . $subkey);
if (!empty($oldconfig) && !isset($submetric['value']) && (isset($submetric['fallback']) && !empty($submetric['fallback']))) {
if (!isset($submetric['fallback']['maxage']) || time() < ($oldconfig[$key]['submetrics'][$subkey]['time'] + $submetric['fallback']['maxage'])) {
if ($submetric['fallback']['type'] == 'previous') {
$submetric['value'] = $oldconfig[$key]['submetrics'][$subkey]['value'];
} elseif ($submetric['fallback']['type'] == 'static') {
$submetric['value'] = $submetric['fallback']['value'];
}
$submetric['time'] = $oldconfig[$key]['submetrics'][$subkey]['time'];
} else {
$submetric['value'] = '';
$submetric['time'] = 0;
}
} else {
$submetric['time'] = time();
}
unlink('/tmp/.metrics.' . $key . '.' . $subkey);
}
}
file_put_contents($cacheFile, json_encode($config, JSON_PRETTY_PRINT));
$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader, [
'cache' => 'twig_cache',
]);
echo $twig->render('metrics.twig', ['config' => $config]);
}
function getArrayValue($elem, $array) {
$elem = explode('.', $elem);
$new_array = $array;
foreach ($elem as $i) {
if(empty($new_array)) break;
$new_array = $new_array[$i];
}
return $new_array;
}
header('Content-Type: text/plain; version=0.0.4');
$config = getenv('CONFIG_FILE');
$phpbin = getenv('PHP_BINARY');
$output = shell_exec('CONFIG_FILE="' . $config . '" ' . $phpbin . ' script.php');
echo $output;

138
script.php Normal file
View File

@ -0,0 +1,138 @@
<?php
require 'vendor/autoload.php';
$configFile = getenv('CONFIG_FILE') ?: 'config.php';
$cacheFile = 'twig_cache/' . hash('murmur3f', $configFile);
if (file_exists($configFile)) {
require ($configFile);
} else {
echo ("Configuration file not found: " . $configFile);
exit(1);
}
if(file_exists($cacheFile)) {
$oldconfig = json_decode(file_get_contents($cacheFile), true);
} else {
$oldconfig = [];
}
if(php_sapi_name() == 'cli' || $_SERVER["REQUEST_URI"] == '/metrics') {
foreach ($config as $key => &$metric) {
if (!isset($metric['submetrics'])) {
$metric['submetrics'] = [$metric];
}
foreach ($metric['submetrics'] as $subkey => &$submetric) {
$pid = pcntl_fork();
if ($pid > 0) {
$pids[] = $pid;
} else {
if (isset($submetric['command'])) {
$output = null;
$retval = null;
try {
exec($submetric['command'], $output, $retval);
$output = implode("\n", $output);
} catch (Exception $e) {
$output = '';
}
} elseif (isset($submetric['http'])) {
$client = new GuzzleHttp\Client();
$options = [];
$output = NULL;
if (isset($submetric['http']['proxy'])) {
$options['proxy'] = $submetric['http']['proxy'];
}
if (isset($submetric['http']['data']) && $submetric['http']['data'] == 'responsetime') {
$options['on_stats'] = function (GuzzleHttp\TransferStats $stats) use (&$output) {
$output = $stats->getTransferTime();
};
}
$hasresponse = NULL;
try {
$res = $client->request('GET', $submetric['http']['url'], $options);
$hasresponse = true;
} catch (GuzzleHttp\Exception\GuzzleException $e) {
if (method_exists($e, 'getResponse')) {
$res = $e->getResponse();
$hasresponse = true;
} else {
$hasresponse = false;
}
}
if (isset($submetric['http']['data']) && $submetric['http']['data'] == 'responsebody') {
if ($hasresponse) {
$output = $res->getBody()->getContents();
} else {
$output = '';
}
} elseif ((isset($submetric['http']['statuscode'])) && (isset($submetric['http']['data']) && $submetric['http']['data'] == 'hasresponse')) {
if ($hasresponse) {
$output = $output = (int)in_array($res->getStatusCode(), $submetric['http']['statuscode']);;
} else {
$output = 0;
}
} elseif (isset($submetric['http']['data']) && $submetric['http']['data'] == 'hasresponse') {
$output = (int)$hasresponse;
}
}
if (isset($submetric['jsonelem'])) {
$submetric['value'] = getArrayValue($submetric['jsonelem'], json_decode($output, true));
} else {
$submetric['value'] = $output;
}
if (is_bool($submetric['value'])) $submetric['value'] = $submetric['value'] ? 1 : 0;
file_put_contents('/tmp/.metrics.' . $key . '.' . $subkey, $submetric['value']);
exit();
}
}
}
foreach ($pids as $pid) {
pcntl_waitpid($pid, $none);
}
foreach ($config as $key => &$metric) {
foreach ($metric['submetrics'] as $subkey => &$submetric) {
$submetric['value'] = file_get_contents('/tmp/.metrics.' . $key . '.' . $subkey);
if (!empty($oldconfig) && !isset($submetric['value']) && (isset($submetric['fallback']) && !empty($submetric['fallback']))) {
if (!isset($submetric['fallback']['maxage']) || time() < ($oldconfig[$key]['submetrics'][$subkey]['time'] + $submetric['fallback']['maxage'])) {
if ($submetric['fallback']['type'] == 'previous') {
$submetric['value'] = $oldconfig[$key]['submetrics'][$subkey]['value'];
} elseif ($submetric['fallback']['type'] == 'static') {
$submetric['value'] = $submetric['fallback']['value'];
}
$submetric['time'] = $oldconfig[$key]['submetrics'][$subkey]['time'];
} else {
$submetric['value'] = '';
$submetric['time'] = 0;
}
} else {
$submetric['time'] = time();
}
unlink('/tmp/.metrics.' . $key . '.' . $subkey);
}
}
file_put_contents($cacheFile, json_encode($config, JSON_PRETTY_PRINT));
$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader, [
'cache' => 'twig-cache',
]);
echo $twig->render('metrics.twig', ['config' => $config]);
}
function getArrayValue($elem, $array) {
$elem = explode('.', $elem);
$new_array = $array;
foreach ($elem as $i) {
if(empty($new_array)) break;
$new_array = $new_array[$i];
}
return $new_array;
}

View File

@ -3,6 +3,7 @@
# HELP {{ key }} {{ metric.help }}
{% endif %}
# TYPE {{ key }} {% if metric.type is defined and metric.type is not empty %}{{ metric.help }}{% else %}gauge{% endif %}
{% for subkey, submetric in metric.submetrics %}
{{ key }}{% if submetric.labels is defined and submetric.labels is not empty %}{{ '{' }}{% for label, value in submetric.labels %}{{ label }}="{{ value }}"{% if not loop.last %},{% endif %}{% endfor %}{{ '}' }}{% endif %} {{ submetric.value }}
{% endfor %}