forked from DavidHavl/DhErrorLogging
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathModule.php
153 lines (123 loc) · 5.32 KB
/
Module.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?php
namespace DhErrorLogging;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Log\Logger;
use Zend\Db\Adapter;
class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
// set logging of errors
$this->initErrorLogger($e);
}
public function initErrorLogger($e)
{
$app = $e->getApplication();
$serviceManager = $app->getServiceManager();
$config = $serviceManager->get('config');
// return if there is no config
if (empty($config['dherrorlogging']['enabled'])) {
return;
}
// get logger
$logger = $serviceManager->get('DhErrorLogging\Logger');
$generator = $serviceManager->get('DhErrorLogging\ErrorReferenceGenerator');
// Handle native PHP errors
// convert php errors into exceptions so that it is caught by same process as exceptions.
set_error_handler(function ($level, $message, $file, $line) use ($logger) {
$minErrorLevel = error_reporting();
if ($minErrorLevel & $level) {
throw new \ErrorException($message, $code = 0, $level, $file, $line);
}
// return false to not continue native handler
return false;
});
// Get shared event manager
$sharedEventManager = $app->getEventManager()->getSharedManager();
// Handle framework specific errors
$sharedEventManager->attach('Zend\Mvc\Application', array(MvcEvent::EVENT_DISPATCH_ERROR, MvcEvent::EVENT_RENDER_ERROR), function($event) use ($logger, $generator, $config) {
// check if event is error
if (!$event->isError()) {
return;
}
// get message and exception (if present)
$message = $event->getError();
$exception = $event->getParam('exception');
// generate unique reference for this error
$errorReference = $generator->generate();
$extras = array(
'reference' => $errorReference
);
// check if event has exception and populate extras array.
if (!empty($exception)) {
$message = $exception->getMessage();
$extras['file'] = $exception->getFile();
$extras['line'] = $exception->getLine();
$extras['trace'] = $exception->getTraceAsString();
// check if xdebug is enabled and message present in which case add it to the extras
if (isset($exception->xdebug_message)) {
$extra['xdebug'] = $exception->xdebug_message;
}
}
// log it
$priority = $config['dherrorlogging']['priority'];
$logger->log($priority, $message, $extras);
// hijack error view and add error reference to the message
$originalMessage = $event->getResult()->getVariable('message');
$event->getResult()->setVariable('message', $originalMessage . '<br /> Error Reference: ' . $errorReference);
});
// catch also fatal errors which woud not show the error template.
register_shutdown_function(function () use ($logger, $generator, $config) {
$error = error_get_last();
// log only errors
if (null === $error || !isset($error['type']) || $error['type'] !== E_ERROR) {
return;
}
// clean any previous output from buffer
while( ob_get_level() > 0 ) {
ob_end_clean();
}
$errorReference = $generator->generate();
$extras = array(
'reference' => $errorReference,
'file' => $error['file'],
'line' => $error['line']
);
// log error using logger
$logger->log(Logger::$errorPriorityMap[$error['type']], $error['message'], $extras);
// get absolute path of the template to render (the shutdown method sometimes changes relative path).
$fatalTemplatePath = dirname(__FILE__) . '/view/error/fatal.html';
if (!empty($config['dherrorlogging']['templates']['fatal'])
&& file_exists($config['dherrorlogging']['templates']['fatal'])) {
$fatalTemplatePath = $config['dherrorlogging']['templates']['fatal'];
}
// read content of file
$body = file_get_contents($fatalTemplatePath);
// inject error reference
$body = str_replace('%__ERROR_REFERENCE__%', 'Error Reference: ' . $errorReference, $body);
echo $body;
die(1);
});
}
}