Symfony 4:在非生产环境中隐藏调试堆栈跟踪

时间:2019-01-18 10:38:54

标签: symfony4 production-environment

我有2个生产环境,分别是 prod1 prod2 ,它们的配置不同,例如数据库和业务逻辑。这基本上是主从关系。

我想像在正常生产环境中一样向用户隐藏调试堆栈跟踪。应该可以通过在 .env 文件中设置 APP_DEBUG = 0来实现。

APP_DEBUG=0

但是我得到了调试屏幕:

enter image description here

但是奇怪的是,只有当我将 APP_ENV 设置为 prod 时,这才行不通。没有显示调试堆栈跟踪。

我的.env文件如下:

APP_ENV=prod1
APP_DEBUG=0
APP_SECRET=xxxxxxxaxaxaxa

我检查了 public / index.php 中的参数,并已正确传输:

$env = 'prod1';
$debug = false;
$kernel = new Kernel($env, $debug);

我正在将Symfony 4.2.2与symfony / env一起使用。

有人可以复制这种行为吗?可能是Symfony或symfony / env错误吗?

3 个答案:

答案 0 :(得分:1)

我有几个用Symfony 4编写的项目。为了重现您的错误,我将我的一个项目更新为Symfony 4.2.2。所有Symfony依赖项:

symfony/browser-kit                              v4.2.2             Symfony BrowserKit Component
symfony/cache                                    v4.2.2             Symfony Cache component with PSR-6, PSR-16, and tags
symfony/class-loader                             v3.4.21            Symfony ClassLoader Component
symfony/config                                   v4.2.2             Symfony Config Component
symfony/console                                  v4.2.2             Symfony Console Component
symfony/contracts                                v1.0.2             A set of abstractions extracted out of the Symfony components
symfony/css-selector                             v4.2.2             Symfony CssSelector Component
symfony/debug                                    v4.2.2             Symfony Debug Component
symfony/dependency-injection                     v4.2.2             Symfony DependencyInjection Component
symfony/doctrine-bridge                          v4.2.2             Symfony Doctrine Bridge
symfony/dom-crawler                              v4.2.2             Symfony DomCrawler Component
symfony/dotenv                                   v4.2.2             Registers environment variables from a .env file
symfony/event-dispatcher                         v4.2.2             Symfony EventDispatcher Component
symfony/filesystem                               v4.2.2             Symfony Filesystem Component
symfony/finder                                   v4.2.2             Symfony Finder Component
symfony/flex                                     v1.1.8             Composer plugin for Symfony
symfony/form                                     v4.2.2             Symfony Form Component
symfony/framework-bundle                         v4.2.2             Symfony FrameworkBundle
symfony/http-foundation                          v4.2.2             Symfony HttpFoundation Component
symfony/http-kernel                              v4.2.2             Symfony HttpKernel Component
symfony/inflector                                v4.2.2             Symfony Inflector Component
symfony/intl                                     v4.2.2             A PHP replacement layer for the C intl extension that includes additional data from the ICU library.
symfony/maker-bundle                             v1.11.3            Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.
symfony/monolog-bridge                           v4.2.2             Symfony Monolog Bridge
symfony/monolog-bundle                           v3.3.1             Symfony MonologBundle
symfony/options-resolver                         v4.2.2             Symfony OptionsResolver Component
symfony/orm-pack                                 v1.0.6             A pack for the Doctrine ORM
symfony/polyfill-intl-icu                        v1.10.0            Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring                        v1.10.0            Symfony polyfill for the Mbstring extension
symfony/polyfill-php72                           v1.10.0            Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions
symfony/process                                  v4.2.2             Symfony Process Component
symfony/profiler-pack                            v1.0.4             A pack for the Symfony web profiler
symfony/property-access                          v4.2.2             Symfony PropertyAccess Component
symfony/routing                                  v4.2.2             Symfony Routing Component
symfony/security-bundle                          v4.2.2             Symfony SecurityBundle
symfony/security-core                            v4.2.2             Symfony Security Component - Core Library
symfony/security-csrf                            v4.2.2             Symfony Security Component - CSRF Library
symfony/security-guard                           v4.2.2             Symfony Security Component - Guard
symfony/security-http                            v4.2.2             Symfony Security Component - HTTP Integration
symfony/stopwatch                                v4.2.2             Symfony Stopwatch Component
symfony/swiftmailer-bundle                       v3.2.5             Symfony SwiftmailerBundle
symfony/templating                               v4.2.2             Symfony Templating Component
symfony/translation                              v4.2.2             Symfony Translation Component
symfony/twig-bridge                              v4.2.2             Symfony Twig Bridge
symfony/twig-bundle                              v4.2.2             Symfony TwigBundle
symfony/validator                                v4.2.2             Symfony Validator Component
symfony/var-dumper                               v4.2.2             Symfony mechanism for exploring and dumping PHP variables
symfony/var-exporter                             v4.2.2             A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code
symfony/web-profiler-bundle                      v4.2.2             Symfony WebProfilerBundle
symfony/web-server-bundle                        v4.2.2             Symfony WebServerBundle
symfony/yaml                                     v4.2.2             Symfony Yaml Component

为清楚起见-我正在生产环境中运行该项目,并且我使用 Apache2 来完成这项工作。

在我的项目中,我只有一个.env文件,而没有任何带有环境变量的*.local文件。该文件如下所示:

APP_ENV=prod
APP_SECRET=928374923784mysecretkey92837498273

使用这些设置,我看不到调试页面-正确的行为

APP_ENV=prod
APP_DEBUG=1
APP_SECRET=928374923784mysecretkey92837498273

如果我添加变量APP_DEBUG的值为 1 -显示调试页面-正确的行为

我添加了一个名为prod1的自定义环境:

APP_ENV=prod1
APP_SECRET=928374923784mysecretkey92837498273

默认情况下,现在可见调试页面-正确的行为

我添加了APP_DEBUG = 0:

APP_ENV=prod1
APP_DEBUG=0
APP_SECRET=928374923784mysecretkey92837498273

并且调试页面没有出现-正确的行为


因此,如您所见,我无法重现此错误。在Symfony 4.2.2中,一切似乎都能正常工作。在项目或Web服务器配置中搜索错误,因为这是问题的原因。我认为您在某处覆盖了APP_DEBUG变量。也许在Apache / Nginx虚拟主机配置中:

More informations here

enter image description here

Siavas 所述,它也可以是缓存。尝试手动删除var/log目录并运行composer install


不幸的是,我没有更多的想法,如果该项目不是严格保密的,您可以在github上共享它,也许我将能够为您提供更多帮助

答案 1 :(得分:1)

问题是,我在项目中未正确配置ExceptionController

  1. FOSRestBundle具有其自己的ExceptionController,用于显示json / xml异常

您可以在config / fos_rest.yaml中对其进行配置:

fos_rest
    exception:
        enabled: true
        exception_controller: 'App\Controller\ExceptionController::handleExceptionAction'
  1. Twig是symfony的默认ExceptionController

您可以在config / twig.yaml中对其进行配置:

twig:
    debug: '%kernel.debug%'
    exception_controller: App\Controller\ExceptionController::showException

使用的Exception Handler是fos_rest,我在services.yaml中我配置不正确

App\Controller\ExceptionController:
  - '@fos_rest.view_handler.default'
  - '@fos_rest.exception.messages_map'
  -  true   <------ this should be '%kernel.debug%'
  - '@templating.engine.twig'
  - '@logger'

问题是,第三个参数应该是%kernel.debug%

最后,我最终有2个ExceptionControllers ,一个用于json格式Response的API,另一个用于标准的Twig Exception Controller奏鸣曲后端。唯一的解决方案是将请求从一个控制器转发到另一个:

 <?php

namespace App\Controller;

use Psr\Log\LoggerInterface;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Bundle\TwigBundle\Controller\ExceptionController as TwigExceptionController;

class ExceptionController
{
    protected $debug;

    /**
     * @var TwigExceptionController
     */
    protected $twigExceptionController;

    /**
     * @param bool $debug
     * @param TwigExceptionController $twigExceptionController
     */
    public function __construct(
        bool $debug,
        TwigExceptionController $twigExceptionController
    )
    {
        $this->debug = $debug;
        $this->twigExceptionController = $twigExceptionController;
    }

    /**
     * Converts an Exception to a Response.
     *
     * @param Request                   $request
     * @param FlattenException     $exception
     * @param LoggerInterface $logger
     *
     * @return Response
     */
    public function handleExceptionAction(Request $request, FlattenException $exception, LoggerInterface $logger): Response
    {    
        if (!stristr( strtolower($request->getUri()), '/api/')) {
            return $this->twigExceptionController->showAction($request, $exception, $logger);
        }

        $currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1));
        if ($currentContent) {
            $logger->error('current content: '.$currentContent);
        }

        $code = $this->getStatusCode($exception);
        $response = new JsonResponse();
        $response->setStatusCode($code);
        $response->setData([
            'message' => $exception->getMessage(),
            'code' => $code
        ]);
        return $response;
    }


    /**
     * Determines the status code to use for the response.
     *
     * @param \Exception $exception
     *
     * @return int
     */
    protected function getStatusCode($exception): int
    {
        if (method_exists($exception, 'getCode') && $exception->getCode() > 0) {
            return $exception->getCode();
        }
        if (method_exists($exception, 'getStatusCode') && $exception->getStatusCode() > 0) {
            return $exception->getStatusCode();
        }

        return 500;
    }

    /**
     * Gets and cleans any content that was already outputted.
     *
     * This code comes from Symfony and should be synchronized on a regular basis
     * see src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php
     *
     * @return string
     */
    private function getAndCleanOutputBuffering($startObLevel)
    {
        if (ob_get_level() <= $startObLevel) {
            return '';
        }
        Response::closeOutputBuffers($startObLevel + 1, true);
        return ob_get_clean();
    }
}

答案 2 :(得分:0)

您的配置正确。

这很可能是一个缓存问题:尝试运行php bin/console cache:clear

相关问题