Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.99 KB | None | 0 0
  1. <?php
  2.  
  3. namespace application\components;
  4.  
  5. use \Monolog\Handler\NullHandler;
  6. use \Monolog\Handler\StreamHandler;
  7. use \Monolog\Formatter\LineFormatter;
  8. use \Phoenix\ErrorsLog\RavenHandler;
  9. use \Phoenix\ErrorsLog\DbHandler;
  10. use \Phoenix\ErrorsLog\DbPaymentHandler;
  11. use \Psr\Log\LogLevel as LogLevel;
  12.  
  13. class Logger extends \CComponent implements \Psr\Log\LoggerInterface
  14. {
  15. private $loggers = [];
  16. private $defaultName = 'php';
  17. private $sentryStatus = false;
  18. private $sentrySkipPercent = 0;
  19. private $allowDebugLevel = true;
  20. private $allowInfoLevel = true;
  21. private $doubleLogging = false;
  22. private $lowPriorityLevels = [
  23. 'error',
  24. 'warning',
  25. 'notice',
  26. 'info',
  27. 'debug'
  28. ];
  29. private $maxDepth = 4;
  30.  
  31. const EVENT_LOG_FILE = 'event.log';
  32.  
  33. public function __construct()
  34. {
  35. }
  36.  
  37. public function setSentryStatus($sentryStatus)
  38. {
  39. $this->sentryStatus = $sentryStatus;
  40. }
  41.  
  42. public function setSentrySkipPercent($sentrySkipPercent)
  43. {
  44. $this->sentrySkipPercent = $sentrySkipPercent;
  45. }
  46.  
  47. public function setAllowDebugLevel($allowDebugLevel)
  48. {
  49. $this->allowDebugLevel = $allowDebugLevel;
  50. }
  51.  
  52. public function setAllowInfoLevel(bool $allowInfoLevel)
  53. {
  54. $this->allowInfoLevel = $allowInfoLevel;
  55. }
  56.  
  57. public function setDoubleLogging($doubleLogging)
  58. {
  59. $this->doubleLogging = $doubleLogging;
  60. }
  61.  
  62. public function setMaxDepth($depth)
  63. {
  64. $this->maxDepth = $depth;
  65. }
  66.  
  67. public function init()
  68. {
  69. }
  70.  
  71. private function loggerInstance($loggerName)
  72. {
  73. if (!isset($this->loggers[$loggerName])) {
  74. $logger = new \Monolog\Logger($loggerName);
  75. if ($this->sentryStatus) {
  76. $ravenClient = \application\components\ErrorLogger::getInstance()->getLoggerClient();
  77. $app = \Yii::app();
  78. if (empty($ravenClient) && !empty($app)) {
  79. $ravenClient = \Yii::app()->dic['sentryClient'];
  80. }
  81. if (!empty($ravenClient)) {
  82. $ravenClient->setLoggerName($loggerName);
  83. $ravenHandler = new RavenHandler($ravenClient);
  84. $logger->pushHandler($ravenHandler);
  85. } else {
  86. $nullHandler = new NullHandler();
  87. $logger->pushHandler($nullHandler);
  88. }
  89. if ($this->doubleLogging) {
  90. $dbHandler = new DbHandler();
  91. $logger->pushHandler($dbHandler);
  92. }
  93. } else {
  94. $dbHandler = new DbHandler();
  95. $logger->pushHandler($dbHandler);
  96. }
  97.  
  98. $dbHandler = new DbPaymentHandler();
  99. $logger->pushHandler($dbHandler);
  100.  
  101. $this->loggers[$loggerName] = $logger;
  102. }
  103.  
  104. return $this->loggers[$loggerName];
  105. }
  106.  
  107. private function arrayCopy($array, $maxDepth = -1)
  108. {
  109. if (is_object($array) && $maxDepth === 0) {
  110. return '[object]';
  111. }
  112. if (!is_array($array)) {
  113. return $array;
  114. }
  115. if ($maxDepth === 0) {
  116. return '[array]';
  117. }
  118.  
  119. $result = [];
  120. foreach ($array as $k => $v) {
  121. if (is_object($v)) {
  122. $result[$k] = '[Class] ' . get_class($v);
  123. } elseif (is_array($v)) {
  124. $result[$k] = $this->arrayCopy($v, $maxDepth - 1);
  125. } else {
  126. $result[$k] = $v;
  127. }
  128. }
  129. return $result;
  130. }
  131.  
  132. /**
  133. * Logs with an arbitrary level.
  134. *
  135. * @param mixed $level
  136. * @param string $message
  137. * @param array $context
  138. * @return null
  139. */
  140. public function log($level, $message, array $context = array())
  141. {
  142. if ($this->sentryStatus
  143. && $this->sentrySkipPercent > 0
  144. && in_array($level, $this->lowPriorityLevels)
  145. && (rand(1, 10000) / 100) <= $this->sentrySkipPercent
  146. ) {
  147. return;
  148. }
  149.  
  150. if (!$this->allowDebugLevel && $level === 'debug') {
  151. return;
  152. }
  153.  
  154. if (!$this->allowInfoLevel && $level === 'info') {
  155. return;
  156. }
  157.  
  158. if (!empty($context['error_source'])) {
  159. $loggerName = $context['error_source'];
  160. } else {
  161. $loggerName = $this->defaultName;
  162. }
  163.  
  164. if ((empty($context['file']) && empty($context['line'])) || empty($context['backtrace'])) {
  165. $errorTrace = debug_backtrace();
  166. foreach ($errorTrace as $errorTraceDepth => $errorTraceData) {
  167. if (isset($errorTraceData['function']) &&
  168. isset($errorTraceData['class']) &&
  169. ($errorTraceData['function'] == __FUNCTION__) &&
  170. ($errorTraceData['class'] == __CLASS__)
  171. ) {
  172. break;
  173. }
  174. }
  175.  
  176. if (empty($context['file'])) {
  177. $errorFile = null;
  178. $errorLine = null;
  179. if (isset($errorTrace[$errorTraceDepth + 1])) {
  180. if (!empty($errorTrace[$errorTraceDepth + 1]['file'])) {
  181. $errorFile = $errorTrace[$errorTraceDepth + 1]['file'];
  182. }
  183. if (!empty($errorTrace[$errorTraceDepth + 1]['line'])) {
  184. $errorLine = $errorTrace[$errorTraceDepth + 1]['line'];
  185. }
  186. }
  187. $context['file'] = $errorFile;
  188. $context['line'] = $errorLine;
  189. }
  190.  
  191. if (empty($context['backtrace'])) {
  192. if ($loggerName === $this->defaultName && !isset($context['fatal_error'])) {
  193. $backtrace = [];
  194. //dont store entire object, just class name
  195. foreach ($errorTrace as $traceRow) {
  196. $row = [
  197. 'file' => isset($traceRow['file']) ? $traceRow['file'] : null,
  198. 'line' => isset($traceRow['line']) ? $traceRow['line'] : null,
  199. 'type' => isset($traceRow['type']) ? $traceRow['type'] : null,
  200. 'class' => isset($traceRow['class']) ? $traceRow['class'] : null,
  201. 'function' => isset($traceRow['function']) ? $traceRow['function'] : null,
  202. ];
  203. if (isset($traceRow['args']) && is_array($traceRow['args'])) {
  204. $row['args'] = $this->arrayCopy($traceRow['args'], $this->maxDepth);
  205. }
  206. $backtrace[] = $row;
  207. }
  208. $context['backtrace'] = array_slice($backtrace, $errorTraceDepth + 1);
  209. } else {
  210. $context['backtrace'] = false;
  211. }
  212. }
  213. }
  214.  
  215. $this->loggerInstance($loggerName)->log($level, $message, $context);
  216. }
  217.  
  218. /**
  219. * System is unusable.
  220. *
  221. * @param string $message
  222. * @param array $context
  223. * @return null
  224. */
  225. public function emergency($message, array $context = array())
  226. {
  227. $this->log(LogLevel::EMERGENCY, $message, $context);
  228. }
  229.  
  230. /**
  231. * Event on phoenix platform
  232. *
  233. * @param json_encode $message - array('type' => string, 'body' => array, 'eventAt' => string)
  234. * eventAt is optionality and use for past events
  235. * @return null
  236. */
  237. public function logEvent($message)
  238. {
  239. $logger = new \Monolog\Logger(__FUNCTION__);
  240. $streamHandler = new StreamHandler($this->getLogEventFilePath(), LogLevel::INFO, true, 0666);
  241. $output = "%datetime% %eventType% %body%\n";
  242. $formatter = new LineFormatter($output, 'Y-m-d H:i:s');
  243. $streamHandler->setFormatter($formatter);
  244. $logger->pushHandler($streamHandler);
  245. $logger->pushProcessor(function ($record) {
  246. $message = json_decode($record['message'], true);
  247. $record['eventType'] = $message['type'];
  248. $record['body'] = json_encode($message['body']);
  249. if (isset($message['eventAt'])) {
  250. $record['datetime'] = $message['eventAt'];
  251. }
  252. return $record;
  253. });
  254. $logger->addInfo($message);
  255. }
  256.  
  257. public function getLogEventFilePath()
  258. {
  259. return \Yii::app()->basePath .'/runtime/logs/' . self::EVENT_LOG_FILE;
  260. }
  261.  
  262. /**
  263. * Action must be taken immediately.
  264. *
  265. * Example: Entire website down, database unavailable, etc. This should
  266. * trigger the SMS alerts and wake you up.
  267. *
  268. * @param string $message
  269. * @param array $context
  270. * @return null
  271. */
  272. public function alert($message, array $context = array())
  273. {
  274. $this->log(LogLevel::ALERT, $message, $context);
  275. }
  276.  
  277. /**
  278. * Critical conditions.
  279. *
  280. * Example: Application component unavailable, unexpected exception.
  281. *
  282. * @param string $message
  283. * @param array $context
  284. * @return null
  285. */
  286. public function critical($message, array $context = array())
  287. {
  288. $this->log(LogLevel::CRITICAL, $message, $context);
  289. }
  290.  
  291. /**
  292. * Runtime errors that do not require immediate action but should typically
  293. * be logged and monitored.
  294. *
  295. * @param string $message
  296. * @param array $context
  297. * @return null
  298. */
  299. public function error($message, array $context = array())
  300. {
  301. $this->log(LogLevel::ERROR, $message, $context);
  302. }
  303.  
  304. /**
  305. * Exceptional occurrences that are not errors.
  306. *
  307. * Example: Use of deprecated APIs, poor use of an API, undesirable things
  308. * that are not necessarily wrong.
  309. *
  310. * @param string $message
  311. * @param array $context
  312. * @return null
  313. */
  314. public function warning($message, array $context = array())
  315. {
  316. $this->log(LogLevel::WARNING, $message, $context);
  317. }
  318.  
  319. /**
  320. * Normal but significant events.
  321. *
  322. * @param string $message
  323. * @param array $context
  324. * @return null
  325. */
  326. public function notice($message, array $context = array())
  327. {
  328. $this->log(LogLevel::NOTICE, $message, $context);
  329. }
  330.  
  331. /**
  332. * Interesting events.
  333. *
  334. * Example: User logs in, SQL logs.
  335. *
  336. * @param string $message
  337. * @param array $context
  338. * @return null
  339. */
  340. public function info($message, array $context = array())
  341. {
  342. $this->log(LogLevel::INFO, $message, $context);
  343. }
  344.  
  345. /**
  346. * Detailed debug information.
  347. *
  348. * @param string $message
  349. * @param array $context
  350. * @return null
  351. */
  352. public function debug($message, array $context = array())
  353. {
  354. $this->log(LogLevel::DEBUG, $message, $context);
  355. }
  356. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement