Skip to content

Instantly share code, notes, and snippets.

@ReallyNotARussianSpy
Last active December 15, 2017 14:16
Show Gist options
  • Save ReallyNotARussianSpy/c4612c666bd1f95095506b833bfd107c to your computer and use it in GitHub Desktop.
Save ReallyNotARussianSpy/c4612c666bd1f95095506b833bfd107c to your computer and use it in GitHub Desktop.
Basic script to monitor /var/log/nginx/error.log and insert entries into New Relic
<?php
/*
Monitor /var/log/nginx/error.log and insert entries into New Relic
Place in cron to run every minute
This script matches the following error.log format:
2017/12/15 03:35:11 [error] 64972#64972: *12659427 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: dynamiccatholic.com, request: "POST / HTTP/1.0", upstream: "fastcgi://127.0.0.1:9000", host: "dynamiccatholic.com", referrer: "https://dynamiccatholic.com/"
<[email protected]> - 11/28/17
*/
if(!extension_loaded('newrelic')) {
die('New Relic extension not loaded');
}
date_default_timezone_set('UTC');
class NGINX_Error extends Exception {
public function setFile($file) {
$this->file = $file;
}
}
$error_file_lines = file('/var/log/nginx/error.log');
$last_run = file_get_contents(__DIR__ . '/newrelic_error_lastrun.txt');
if(!$last_run) {
$last_run = 0;
}
file_put_contents(__DIR__ . '/newrelic_error_lastrun.txt', time());
foreach ($error_file_lines as $error_raw) {
$error_details = array();
$error_exploded = explode(',', $error_raw);
// Get the date and time
$str_error_pos = strpos($error_exploded[0], '[error]');
$error_details['log_timestamp'] = strtotime(trim(substr($error_exploded[0], 0, $str_error_pos)));
if(!$error_details['log_timestamp'] || $error_details['log_timestamp'] < $last_run) {
continue;
}
// Get the error message
$str_cid_pos_start = strpos($error_exploded[0], '*');
$str_cid_pos_end = strpos($error_exploded[0], ' ', $str_cid_pos_start);
$error_details['message'] = trim(substr($error_exploded[0], $str_cid_pos_end));
if(strpos($error_details['message'], 'access forbidden by rule') !== false
|| strpos($error_details['message'], 'No such file or directory') !== false) {
continue;
}
unset($error_exploded[0]);
// Get the rest of the details
foreach ($error_exploded as $str_error_part) {
$str_error_part = explode(':', $str_error_part, 2);
if(!isset($str_error_part[1])) {
continue;
}
$str_error_part[0] = trim($str_error_part[0]);
$str_error_part[1] = trim(str_replace('"', '', $str_error_part[1]));
$str_error_part[1] = trim(str_replace('HTTP/1.0', '', $str_error_part[1]));
$error_details[$str_error_part[0]] = $str_error_part[1];
}
foreach ($error_details as $key => $value) {
newrelic_add_custom_parameter($key, $value);
}
$error_details['request'] = trim(str_replace('GET', '', $error_details['request']));
$error_details['request'] = trim(str_replace('POST', '', $error_details['request']));
$exception = new NGINX_Error($error_details['message']);
$exception->setFile($error_details['request']);
newrelic_notice_error($error_details['message'], $exception);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment