我在 slim 4 应用程序中配置了
monolog
,并在 logErrors
中将 logErrorDetails
和 ErrorMIddleware
设置为 true,但是当我收到错误时,它不会写入日志。为了模拟错误,我打开应用程序上的缓存,然后收到如下错误 Call to undefined function apcu_fetch()
b-z doctrine
默认情况下使用 apcu 来缓存所有元数据,并且 apcu 未安装在我的开发环境中。
这是记录器的
PHP-DI
配置:
LoggerInterface::class => static function (Container $container) {
$config = $container->get(Config::class);
$logger = new Logger((string)$config->get('logger.name'));
$fileNameSuffix = PHP_SAPI === 'cli' ? 'php-cli-' : 'php-fpm';
$logger->pushHandler(
new StreamHandler(
$config->get('logger.log_dir') . '/' . $fileNameSuffix . '-' . $config->get('logger.name') . '.log',
$config->get('logger.log_level'))
);
if ((bool)$config->get('main.debug')) {
$logger->pushHandler(new FirePHPHandler());
}
return $logger;
}
这是
ErrorMiddleware
配置:
$definitions[ErrorMiddleware::class] = static function(ContainerInterface $container): ErrorMiddleware {
$middleware = new ErrorMiddleware(
$container->get(CallableResolverInterface::class),
$container->get(ResponseFactoryInterface::class),
(bool)$container->get(Config::class)->get('main.debug'), //false or true
$container->has(LoggerInterface::class) ? true : false,
$container->has(LoggerInterface::class) ? true : false
);
$middleware->setErrorHandler(HttpNotFoundException::class, $container->get(NotFoundHandler::class));
return $middleware;
};
是的,我将该中间件添加到
App
,就像这样$app->add($container->get(ErrorMiddleware::class));
我检查了不同的 slim 4 骨架 Github 存储库,没有找到任何额外的配置,所以我不知道为什么它没有将日志写入文件。也许我需要设置一个自定义的默认错误处理程序? slim 4 默认使用 php
error_log
函数来写入日志?
这就是它在我的
LoggerInterface
中配置 dependencies.php
的方式。我使用 bzikarsky/gelf-php 包发送正确的 GELF 格式。
对于本地环境,使用
StreamHandler
,对于任何其他环境,使用 GelfHandler
。
使用 Graylog 时,请留意确切的端口和协议。在我的示例中,我使用
UdpTransport
。请随意使用其他交通工具,例如 TcpTransport
。
依赖关系.php
<?php
use Monolog\Logger;
// ...
LoggerInterface::class => function (ContainerInterface $c) {
$config = $c->get(Configuration::class)->getArray('logger');
$logger = new Logger($config['name']);
if ($c->get(Configuration::class)->getString('settings.environment') === 'local') {
$processor = new UidProcessor();
$logger->pushProcessor($processor);
$handler = new StreamHandler($config['path'], $config['level']);
} else {
$transport = new UdpTransport(
$config['graylog']['host'],
$config['graylog']['port'],
UdpTransport::CHUNK_SIZE_LAN
);
$publisher = new Publisher();
$publisher->addTransport($transport);
$handler = new GelfHandler($publisher);
}
$logger->pushHandler($handler);
return $logger;
},
// ...
也许这可以是一个解决方案。我在创建对象错误处理时添加 Log 对象。这是我的index.php。 $logger = $app->getContainer()->get(LoggerInterface::class);
<?php
declare(strict_types=1);
use DI\ContainerBuilder;
use Psr\Log\LoggerInterface;
use Slim\Factory\AppFactory;
use App\Application\Handlers\ShutdownHandler;
use Slim\Factory\ServerRequestCreatorFactory;
use App\Application\Handlers\HttpErrorHandler;
use App\Application\Settings\SettingsInterface;
use App\Application\ResponseEmitter\ResponseEmitter;
require __DIR__ . '/../vendor/autoload.php';
// Instantiate PHP-DI ContainerBuilder
$containerBuilder = new ContainerBuilder();
if (false) { // Should be set to true in production
$containerBuilder->enableCompilation(__DIR__ . '/../var/cache');
}
// Set up settings
$settings = require __DIR__ . '/../app/settings.php';
$settings($containerBuilder);
// Set up dependencies
$dependencies = require __DIR__ . '/../app/dependencies.php';
$dependencies($containerBuilder);
// Set up repositories
$repositories = require __DIR__ . '/../app/repositories.php';
$repositories($containerBuilder);
// Build PHP-DI Container instance
$container = $containerBuilder->build();
// Instantiate the app
AppFactory::setContainer($container);
$app = AppFactory::create();
$callableResolver = $app->getCallableResolver();
// Register middleware
$middleware = require __DIR__ . '/../app/middleware.php';
$middleware($app);
// Register routes
include __DIR__ . '/index_api.php';
// $app->setBasePath('/public');
$routes = require __DIR__ . '/../app/routes.php';
$routes($app);
/** @var SettingsInterface $settings */
$settings = $container->get(SettingsInterface::class);
$displayErrorDetails = $settings->get('displayErrorDetails');
$logError = $settings->get('logError');
$logErrorDetails = $settings->get('logErrorDetails');
// Create Request object from globals
$serverRequestCreator = ServerRequestCreatorFactory::create();
$request = $serverRequestCreator->createServerRequestFromGlobals();
// Create Error Handler
$logger = $app->getContainer()->get(LoggerInterface::class);
$responseFactory = $app->getResponseFactory();
$errorHandler = new HttpErrorHandler($callableResolver, $responseFactory, $logger);
// Create Shutdown Handler
$shutdownHandler = new ShutdownHandler($request, $errorHandler, $displayErrorDetails);
register_shutdown_function($shutdownHandler);
// Add Routing Middleware
$app->addRoutingMiddleware();
// Add Body Parsing Middleware
$app->addBodyParsingMiddleware();
// Add Error Middleware
$errorMiddleware = $app->addErrorMiddleware($displayErrorDetails, $logError, $logErrorDetails);
$errorMiddleware->setDefaultErrorHandler($errorHandler);
// Run App & Emit Response
$response = $app->handle($request);
$responseEmitter = new ResponseEmitter();
$responseEmitter->emit($response);