/** * @param CM_Log_Handler_HandlerInterface $handler * @return CM_Log_Logger */ protected function _createLogger(CM_Log_Handler_HandlerInterface $handler) { $computerInfo = new CM_Log_Context_ComputerInfo(CM_Util::getFqdn(), phpversion()); $globalContext = new CM_Log_Context(); $globalContext->setComputerInfo($computerInfo); return new CM_Log_Logger($globalContext, $handler); }
public function testGetHttpRequest() { /** @var CM_Http_Request_Abstract $request */ $request = $this->mockClass('CM_Http_Request_Abstract')->newInstanceWithoutConstructor(); $context = new CM_Log_Context(); $context->setHttpRequest($request); $this->assertSame($request, $context->getHttpRequest()); }
public function testFormattingWithExtra() { $extra = ['foo', 'bar' => true, 'foo' => ['foobar' => 1], 'baz' => [1, 2, true, null]]; $context = new CM_Log_Context(); $context->setExtra($extra); $record = new CM_Log_Record(CM_Log_Logger::INFO, 'foo', $context); $formatter = new CM_Log_Formatter_Text(); $this->assertSame(join(PHP_EOL, [' - extra: {', ' "0": "foo",', ' "bar": true,', ' "foo": {', ' "foobar": 1', ' },', ' "baz": [', ' 1,', ' 2,', ' true,', ' null', ' ]', '}']), $formatter->renderContext($record)); }
/** * @param Swift_Mime_Message $message * @param array|null $failedRecipients * @param Exception|null $exception */ protected function _logSendError(Swift_Mime_Message $message, array $failedRecipients = null, Exception $exception = null) { $context = new CM_Log_Context(); $context->setExtra(['message' => ['subject' => $message->getSubject(), 'from' => $message->getFrom(), 'to' => $message->getTo(), 'cc' => $message->getCc(), 'bcc' => $message->getBcc()], 'failedRecipients' => $failedRecipients]); if ($exception) { $context->setException($exception); } $this->getServiceManager()->getLogger()->error('Failed to send email', $context); }
public function formatAppContext(CM_Log_Context $context) { $result = []; $appAttributes = $context->getExtra(); if ($user = $context->getUser()) { $appAttributes['user'] = ['id' => $user->getId(), 'displayName' => $user->getDisplayName()]; } $request = $context->getHttpRequest(); if (null !== $request) { $appAttributes['client'] = ['id' => $request->getClientId()]; } $result[$this->_appName] = $appAttributes; return $result; }
/** * @param string $message * @param int $level * @param CM_Log_Context|null $context * @return CM_Log_Logger */ public function addMessage($message, $level, CM_Log_Context $context = null) { $message = (string) $message; $level = (int) $level; if ($this->_context) { $recordContext = clone $this->_context; } else { $recordContext = new CM_Log_Context(); } if ($context) { $recordContext->merge($context); } return $this->_addRecord(new CM_Log_Record($level, $message, $recordContext)); }
protected function _process() { $request = $this->getRequest(); if (!$request->isBotCrawler() && $request->isSupported()) { $query = $request->getQuery(); if (!isset($query['error']) || !isset($query['error']['message'])) { throw new CM_Exception_Invalid('Failed to process a JS Error, "error.message" expected', CM_Exception::WARN, ['query' => $query]); } $context = new CM_Log_Context(); $context->setExtra(array_merge($query, ['type' => CM_Paging_Log_Javascript::getTypeStatic()])); $this->getServiceManager()->getLogger()->warning('JS Error - ' . $query['error']['message'], $context); } $this->setHeader('Content-Type', 'application/json'); $this->_setContent(json_encode(['status' => 'ok'])); }
public function send(Swift_Mime_Message $message, &$failedRecipients = null) { $failedRecipients = (array) $failedRecipients; $msg = '* ' . $message->getSubject() . ' *' . PHP_EOL . PHP_EOL; if ($message instanceof CM_Mail_Message) { $msg .= $message->getText() . PHP_EOL; } else { $msg .= $message->getBody() . PHP_EOL; } $logger = $this->getLogger(); $context = new CM_Log_Context(); $context->setExtra(['type' => CM_Paging_Log_Mail::getTypeStatic(), 'sender' => $message->getSender(), 'replyTo' => $message->getReplyTo(), 'to' => $message->getTo(), 'cc' => $message->getCc(), 'bcc' => $message->getBcc()]); $logger->addMessage($msg, $this->_logLevel, $context); return count($message->getTo()) + count($message->getCc()) + count($message->getBcc()); }
public function testWriting() { $collection = 'cm_event_log'; $level = CM_Log_Logger::DEBUG; $message = 'foo'; $ttl = 30; $user = CMTest_TH::createUser(); $httpRequest = CM_Http_Request_Abstract::factory('post', '/foo?bar=1&baz=quux', ['bar' => 'baz'], ['foo' => 'quux'], '{"bar":"2", "quux":"baz"}'); $clientId = $httpRequest->getClientId(); $computerInfo = new CM_Log_Context_ComputerInfo('www.example.com', 'v7.0.1'); $mongoClient = $this->getServiceManager()->getMongoDb(); $this->assertSame(0, $mongoClient->count($collection)); $mongoClient->createIndex($collection, ['expireAt' => 1], ['expireAfterSeconds' => 0]); $recordContext = new CM_Log_Context(); $recordContext->setExtra(['bar' => ['baz' => 'quux']]); $recordContext->setUser($user); $recordContext->setHttpRequest($httpRequest); $recordContext->setComputerInfo($computerInfo); $record = new CM_Log_Record($level, $message, $recordContext); $encoder = $this->mockObject(CM_Log_Encoder_MongoDb::class); /** @var CM_Log_Encoder_MongoDb $encoder */ $handler = new CM_Log_Handler_MongoDb($mongoClient, $encoder, $collection, $ttl, ['w' => 0], $level); $this->callProtectedMethod($handler, '_writeRecord', [$record]); $this->assertSame(1, $mongoClient->count($collection)); $savedRecord = $mongoClient->findOne($collection); $this->assertSame($level, $savedRecord['level']); $this->assertSame($message, $savedRecord['message']); /** @var MongoDate $createdAt */ $createdAt = $savedRecord['createdAt']; /** @var MongoDate $expireAt */ $expireAt = $savedRecord['expireAt']; $this->assertInstanceOf('MongoDate', $createdAt); $this->assertInstanceOf('MongoDate', $expireAt); $this->assertSame($ttl, $expireAt->sec - $createdAt->sec); $context = $savedRecord['context']; $this->assertSame(['id' => $user->getId(), 'name' => $user->getDisplayName()], $context['user']); $this->assertSame('POST', $context['httpRequest']['method']); $this->assertSame('/foo?bar=1&baz=quux', $context['httpRequest']['uri']); $this->assertSame(['bar' => '2', 'baz' => 'quux', 'quux' => 'baz'], $context['httpRequest']['query']); $this->assertSame(['bar' => 'baz'], $context['httpRequest']['headers']); $this->assertSame(['foo' => 'quux'], $context['httpRequest']['server']); $this->assertSame($clientId, $context['httpRequest']['clientId']); $this->assertSame('www.example.com', $context['computerInfo']['fqdn']); $this->assertSame('v7.0.1', $context['computerInfo']['phpVersion']); $this->assertSame(['bar' => ['baz' => 'quux'], 'type' => CM_Log_Handler_MongoDb::DEFAULT_TYPE], $context['extra']); $this->assertSame('{"bar":"2", "quux":"baz"}', $context['httpRequest']['body']); }
public function testGetRecordContext() { $user = CMTest_TH::createUser(); $httpRequest = CM_Http_Request_Abstract::factory('post', '/foo?bar=1&baz=quux&viewInfoList=fooBar', ['bar' => 'baz', 'host' => 'foo.bar:8080'], ['http_referer' => 'http://bar/baz', 'http_user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_10)', 'foo' => 'quux'], '{"foo" : "bar", "quux" : "baz"}'); $clientId = $httpRequest->getClientId(); $computerInfo = new CM_Log_Context_ComputerInfo('www.example.com', 'v7.0.1'); $exception = new CM_Exception_Invalid('Bad', null, ['foo' => 'bar']); $context = new CM_Log_Context(); $context->setExtra(['bar' => 'baz', 'baz' => 'quux']); $context->setUser($user); $context->setException($exception); $context->setComputerInfo($computerInfo); $context->setHttpRequest($httpRequest); $contextFormatter = new CM_Log_ContextFormatter_Cargomedia('appName'); $formattedContext = $contextFormatter->formatContext($context); $this->assertSame('www.example.com', $formattedContext['computerInfo']['fqdn']); $this->assertSame('v7.0.1', $formattedContext['computerInfo']['phpVersion']); $this->assertSame('/foo?bar=1&baz=quux&viewInfoList=fooBar', $formattedContext['httpRequest']['uri']); $this->assertSame(join("\n", ['{', ' "bar": "1",', ' "baz": "quux",', ' "foo": "bar",', ' "quux": "baz"', '}']), $formattedContext['httpRequest']['query']); $this->assertSame('POST', $formattedContext['httpRequest']['method']); $this->assertSame('http://bar/baz', $formattedContext['httpRequest']['referer']); $this->assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_10)', $formattedContext['httpRequest']['useragent']); $this->assertSame('foo.bar', $formattedContext['httpRequest']['hostname']); $this->assertSame(['id' => $user->getId(), 'displayName' => 'user' . $user->getId()], $formattedContext['appName']['user']); $this->assertSame($clientId, $formattedContext['appName']['client']['id']); $this->assertSame('baz', $formattedContext['appName']['bar']); $this->assertSame('quux', $formattedContext['appName']['baz']); $this->assertSame('CM_Exception_Invalid', $formattedContext['exception']['type']); $this->assertSame('Bad', $formattedContext['exception']['message']); $this->assertArrayHasKey('stack', $formattedContext['exception']); $this->assertInternalType('string', $formattedContext['exception']['stack']); $this->assertSame(['foo' => "'bar'"], $formattedContext['exception']['metaInfo']); $this->assertRegExp('/library\\/CM\\/Log\\/ContextFormatter\\/CargomediaTest\\.php\\(\\d+\\)/', $formattedContext['exception']['stack']); }
/** * @param string $className * @return CM_Jobdistribution_Job_Abstract|null */ protected function _instantiateJob($className) { try { /** @var CM_Jobdistribution_Job_Abstract $job */ $job = new $className(); if ($job instanceof CM_Service_ManagerAwareInterface) { /** @var CM_Service_ManagerAwareInterface $job */ $job->setServiceManager($this->getServiceManager()); } return $job; } catch (Exception $e) { $logLevel = CM_Log_Logger::exceptionToLevel($e); $context = new CM_Log_Context(); $context->setException($e); $this->getServiceManager()->getLogger()->addMessage('Delayed queue error', $logLevel, $context); return null; } }
/** * @param string $streamChannelMediaId * @param CM_File $archiveSource * @throws CM_Exception_Invalid */ public function importArchive($streamChannelMediaId, CM_File $archiveSource) { $streamChannelMediaId = (string) $streamChannelMediaId; $streamChannelArchive = CM_Model_StreamChannelArchive_Media::findByMediaId($streamChannelMediaId); if (!$streamChannelArchive) { $streamChannel = CM_Model_StreamChannel_Media::findByMediaId($streamChannelMediaId); if ($streamChannel) { throw new CM_Exception_Invalid('Archive not created, please try again later', null, ['streamChannelMediaId' => $streamChannelMediaId]); } $exception = new CM_Exception_Invalid('Archive not found, stream channel not found, skipping', CM_Exception::WARN, ['streamChannelMediaId' => $streamChannelMediaId]); $context = new CM_Log_Context(); $context->setException($exception); $this->getServiceManager()->getLogger()->warning('Archive creating error', $context); return; } $filename = $streamChannelArchive->getId() . '-' . $streamChannelArchive->getHash() . '-original.' . $archiveSource->getExtension(); $archiveDestination = new CM_File_UserContent('streamChannels', $filename, $streamChannelArchive->getId()); $archiveDestination->ensureParentDirectory(); $archiveSource->copyToFile($archiveDestination); $streamChannelArchive->setFile($archiveDestination); }
public function testAddDelete() { $logger = CM_Service_Manager::getInstance()->getLogger(); $this->assertSame(0, (new CM_Paging_Log_Mail([CM_Log_Logger::INFO]))->getCount()); $this->assertSame(0, (new CM_Paging_Log([CM_Log_Logger::INFO]))->getCount()); $context1 = new CM_Log_Context(); $context1->setExtra(['type' => CM_Paging_Log_Mail::getTypeStatic(), 'foo' => 'foo']); $logger->info('mail foo', $context1); $context2 = new CM_Log_Context(); $context2->setExtra(['type' => CM_Paging_Log_Mail::getTypeStatic(), 'bar' => 'bar']); $logger->info('mail bar', $context2); $context3 = new CM_Log_Context(); $context3->setExtra(['baz' => 'baz']); $logger->info('not mail', $context3); $this->assertSame(2, (new CM_Paging_Log_Mail([CM_Log_Logger::INFO]))->getCount()); $this->assertSame(3, (new CM_Paging_Log([CM_Log_Logger::INFO]))->getCount()); $age = 7 * 86400 + 1; CMTest_TH::timeForward($age); (new CM_Paging_Log_Mail([CM_Log_Logger::INFO]))->cleanUp(); $this->assertSame(0, (new CM_Paging_Log_Mail([CM_Log_Logger::INFO]))->getCount()); $this->assertSame(1, (new CM_Paging_Log([CM_Log_Logger::INFO]))->getCount()); }
public function testWriteRecordWithContext() { $message = 'foo'; $exceptionMessage = 'foo!'; $extra = ['foo', 'bar' => true, 'foo' => ['foobar' => 1]]; /** @var CM_OutputStream_Interface|Mocka\ClassMock $mockStreamInterface */ $mockStreamInterface = $this->mockInterface('CM_OutputStream_Interface')->newInstanceWithoutConstructor(); /** @var Mocka\FunctionMock $mockWritelnMethod */ $mockWritelnMethod = $mockStreamInterface->mockMethod('writeln'); $mockWritelnMethod->set(function ($outputText) use($message, $exceptionMessage, $extra) { $this->assertRegExp('/^\\[[0-9T\\:\\-\\+]+ - none - php none - INFO\\] ' . $message . '\\n/s', $outputText); $this->assertRegExp('/\\n - extra: ' . json_encode($extra, JSON_PRETTY_PRINT) . '/s', $outputText); $this->assertRegExp('/\\n - exception:(?:\\s+) - message: ' . $exceptionMessage . '.*$/s', $outputText); }); $context = new CM_Log_Context(); $context->setExtra($extra); $context->setException(new Exception($exceptionMessage)); $record = new CM_Log_Record(CM_Log_Logger::INFO, $message, $context); $formatter = new CM_Log_Formatter_Text(); $handler = new CM_Log_Handler_Stream($mockStreamInterface, $formatter); $this->forceInvokeMethod($handler, '_writeRecord', [$record]); $this->assertSame(1, $mockWritelnMethod->getCallCount()); }
public function testAggregate() { $client = $this->getServiceManager()->getMongoDb(); $encoder = new CM_Log_Encoder_MongoDb(); $handler = new CM_Log_Handler_MongoDb($client, $encoder, CM_Paging_Log::COLLECTION_NAME); $context1 = new CM_Log_Context(); $context1->setExtra(['bar' => 'quux']); $record1 = new CM_Log_Record(CM_Log_Logger::DEBUG, 'foo', $context1); $context2 = new CM_Log_Context(); $record2 = new CM_Log_Record(CM_Log_Logger::DEBUG, 'baz', $context2); $exception = new CM_Exception_Invalid('Bad news', CM_Exception::WARN, ['baz' => 'bar']); $context3 = new CM_Log_Context(); $context3->setException($exception); $record3 = new CM_Log_Record(CM_Log_Logger::WARNING, 'bar', $context3); //they will not be found $handler->handleRecord($record1); $handler->handleRecord($record2); $handler->handleRecord($record3); CMTest_TH::timeDaysForward(2); //recreate records to correctly set up CM_Log_Record::createdAt $context1 = new CM_Log_Context(); $context1->setExtra(['bar' => 'quux']); $record1 = new CM_Log_Record(CM_Log_Logger::DEBUG, 'foo', $context1); $context3 = new CM_Log_Context(); $context3->setException($exception); $record3 = new CM_Log_Record(CM_Log_Logger::WARNING, 'bar', $context3); $handler->handleRecord($record1); $handler->handleRecord($record3); $handler->handleRecord($record3); CMTest_TH::timeDaysForward(1); $exception2 = new CM_Exception_Invalid('Some info', CM_Exception::FATAL, ['foo' => 'bar']); //recreate records to correctly set up CM_Log_Record::createdAt $context1 = new CM_Log_Context(); $context1->setExtra(['bar' => 'quux']); $record1 = new CM_Log_Record(CM_Log_Logger::DEBUG, 'foo', $context1); $context2 = new CM_Log_Context(); $record2 = new CM_Log_Record(CM_Log_Logger::DEBUG, 'baz', $context2); $context3 = new CM_Log_Context(); $context3->setException($exception); $record3 = new CM_Log_Record(CM_Log_Logger::DEBUG, 'Error bar', $context3); $context4 = new CM_Log_Context(); $context4->setException($exception2); $record4 = new CM_Log_Record(CM_Log_Logger::DEBUG, 'Error bar', $context4); $handler->handleRecord($record2); $handler->handleRecord($record2); $handler->handleRecord($record2); $handler->handleRecord($record3); $handler->handleRecord($record3); $handler->handleRecord($record4); $handler->handleRecord($record1); $handler->handleRecord($record1); $handler->handleRecord($record1); $paging = new CM_Paging_Log([CM_Log_Logger::DEBUG], null, true, 2 * 86400); $this->assertSame(4, $paging->getCount()); $foundRecord1 = $paging->getItem(0); $foundRecord2 = $paging->getItem(1); $foundRecord3 = $paging->getItem(2); $foundRecord4 = $paging->getItem(3); $this->assertSame(4, $foundRecord1['count']); $this->assertSame(3, $foundRecord2['count']); $this->assertSame(2, $foundRecord3['count']); $this->assertSame(1, $foundRecord4['count']); $this->assertSame('foo', $foundRecord1['message']); $this->assertSame('baz', $foundRecord2['message']); $this->assertSame('Error bar', $foundRecord3['message']); $this->assertSame('Bad news', $foundRecord3['exception']['message']); $this->assertSame('Error bar', $foundRecord4['message']); $this->assertSame('Some info', $foundRecord4['exception']['message']); }
/** * @param float|null $timeoutKill */ public function killChildren($timeoutKill = null) { if (null === $timeoutKill) { $timeoutKill = 30; } $timeoutKill = (double) $timeoutKill; $signal = SIGTERM; $timeStart = microtime(true); $timeoutReached = false; $timeOutput = $timeStart; while (!empty($this->_forkHandlerList)) { $timeNow = microtime(true); $timePassed = $timeNow - $timeStart; if ($timePassed > $timeoutKill) { $signal = SIGKILL; $timeoutReached = true; } if ($timeNow > $timeOutput + 2 || $timeoutReached) { $message = join(' ', [count($this->_forkHandlerList) . ' children remaining', 'after ' . round($timePassed, 1) . ' seconds,', 'killing with signal `' . $signal . '`...']); echo $message . PHP_EOL; if ($timeoutReached) { $logContext = new CM_Log_Context(); $logContext->setExtra(['pid' => $this->getProcessId(), 'argv' => join(' ', $this->getArgv())]); CM_Service_Manager::getInstance()->getLogger()->error($message, $logContext); } $timeOutput = $timeNow; } foreach ($this->_forkHandlerList as $forkHandler) { posix_kill($forkHandler->getPid(), $signal); } usleep(1000000 * 0.05); foreach ($this->_forkHandlerList as $forkHandler) { $pid = pcntl_waitpid($forkHandler->getPid(), $status, WNOHANG); if ($pid > 0 || !$this->isRunning($pid)) { $forkHandler = $this->_getForkHandlerByPid($forkHandler->getPid()); unset($this->_forkHandlerList[$forkHandler->getIdentifier()]); $forkHandler->closeIpcStream(); if (!$this->_hasForks()) { $this->unbind('exit', [$this, 'killChildren']); } } } } }
public function testHandleException() { $mockLogHandler = $this->mockInterface('CM_Log_Handler_HandlerInterface')->newInstance(); $mockHandleRecord = $mockLogHandler->mockMethod('handleRecord'); $logger = $this->_getLoggerMock(new CM_Log_Context(), new CM_Log_Handler_Layered([new CM_Log_Handler_Layered_Layer([$mockLogHandler])])); $exception = new Exception('foo'); $mockHandleRecord->set(function (CM_Log_Record $record) use($exception) { $this->assertTrue(!!$record->getContext()->getException()); $recordException = $record->getContext()->getException(); $this->assertSame('foo', $recordException->getMessage()); $this->assertSame($exception->getLine(), $recordException->getLine()); $this->assertSame($exception->getFile(), $recordException->getFile()); $this->assertSame('Error happened', $record->getMessage()); $this->assertSame(CM_Log_Logger::ERROR, $record->getLevel()); }); $context = new CM_Log_Context(); $context->setException($exception); $logger->error('Error happened', $context); $this->assertSame(1, $mockHandleRecord->getCallCount()); $exception = new CM_Exception('bar'); $mockHandleRecord->set(function (CM_Log_Record $record) use($exception) { $recordException = $record->getContext()->getException(); $this->assertSame('bar', $recordException->getMessage()); $this->assertSame($exception->getLine(), $recordException->getLine()); $this->assertSame($exception->getFile(), $recordException->getFile()); $this->assertSame('Warning alert', $record->getMessage()); $this->assertSame(CM_Log_Logger::WARNING, $record->getLevel()); }); $context = new CM_Log_Context(); $context->setException($exception); $logger->warning('Warning alert', $context); $this->assertSame(2, $mockHandleRecord->getCallCount()); }
/** * @param CM_Log_Context $context */ public function merge(CM_Log_Context $context) { if ($computerInfo = $context->getComputerInfo()) { $this->setComputerInfo($computerInfo); } if ($httpRequest = $context->getHttpRequest()) { $this->setHttpRequest($httpRequest); } if ($getUserClosure = $context->_getUserClosure) { $this->setUserWithClosure($getUserClosure); } if ($exception = $context->getException()) { $this->setException($exception); } $extra = array_merge($this->getExtra(), $context->getExtra()); $this->setExtra($extra); }
/** * @param Closure $regularCode * @param Closure $errorCode * @return mixed * @throws CM_Exception */ protected function _runWithCatching(Closure $regularCode, Closure $errorCode) { try { return $regularCode(); } catch (CM_Exception $ex) { $config = self::_getConfig(); $exceptionsToCatch = $config->exceptionsToCatch; $catchPublicExceptions = !empty($config->catchPublicExceptions); $errorOptions = \Functional\first($exceptionsToCatch, function ($options, $exceptionClass) use($ex) { return is_a($ex, $exceptionClass); }); $catchException = null !== $errorOptions; if ($catchException && isset($errorOptions['log']) && true === $errorOptions['log']) { $logLevel = isset($errorOptions['level']) ? $errorOptions['level'] : null; if (null === $logLevel) { $logLevel = CM_Log_Logger::exceptionToLevel($ex); } $context = new CM_Log_Context(); $context->setUser($this->getViewer()); $context->setException($ex); $this->getServiceManager()->getLogger()->addMessage('Response processing error', $logLevel, $context); } if (!$catchException && ($catchPublicExceptions && $ex->isPublic())) { $errorOptions = []; $catchException = true; } if ($catchException) { return $errorCode($ex, $errorOptions); } throw $ex; } }
/** * @param Exception $exception */ protected function _logException(Exception $exception) { $logLevel = CM_Log_Logger::exceptionToLevel($exception); $context = new CM_Log_Context(); $context->setException($exception); CM_Service_Manager::getInstance()->getLogger()->addMessage('KickBox client error', $logLevel, $context); }