gpt4 book ai didi

php - 使用 MonologBu​​ndle 自定义 HandlerWrapper

转载 作者:可可西里 更新时间:2023-11-01 12:36:04 25 4
gpt4 key购买 nike

我正在使用 Symfony 3.1,我尝试以这样一种方式配置 Monolog,即不记录来自 Googlebot 的请求。为此,我编写了一个 UserAgentProcessor,它已经按预期工作了。在下一步中,我尝试编写如下所示的 BotFilter:

<?php

namespace AppBundle\Handler;

use Monolog\Handler\HandlerWrapper;

class FilterBotsHandler extends HandlerWrapper
{

/**
* {@inheritdoc}
*/
public function isHandling(array $record)
{
if (stripos($record['extra']['userAgent'], 'bot') !== false){
return false;
} else {
return $this->handler->isHandling($record);
}
}
}

这受到 HandlerWrapper 抽象类中的注释的启发(看看 here )。

现在我想将该过滤器添加到我的独白 yml 配置中。我尝试将它添加到我的服务中,但这是不可能的,因为 HandlerWrapper 的构造函数需要一个 Handler 实例。我研究了如何在没有服务的情况下使用过滤器,但据我所知,独白包只接受内置类型和通用服务类型。

现在的问题是:如何在我的配置中使用过滤器?

最佳答案

I am using Symfony 3.1 and I try to configure Monolog in such a way, that requests from the GoogleBot are not logged...


  1. 防止机器人访问您站点的快速方法是将这两行放入服务器上的 /robots.txt 文件中。在 'web' 目录中创建一个 robots.txt 文件并粘贴以下内容:

    User-agent: *
    Disallow: /

    https://support.google.com/webmasters/answer/6062608?hl=en&visit_id=1-636097099675465769-3677253464&rd=1

    当您需要完全避免访问时,这是推荐的选项,这意味着您的网站将不再被搜索引擎和其他机器人编入索引。您无需在应用程序中配置/实现任何内容即可实现。


  1. 现在,如果您需要机器人进入,但又不想在日志中注册它。不是在某处写入日志文件,一些 处理程序用于在将日志条目发送到其他 处理程序之前过滤或修改日志条目。默认情况下,prod 环境中使用一个名为 fingers_crossed 的强大内置处理程序。它在请求期间存储所有日志消息,但仅在其中一条消息达到 action_level 时才将它们传递给第二个处理程序:

    # app/config/config.yml
    monolog:
    handlers:
    filter_for_errors:
    type: fingers_crossed
    # if *one* log is error or higher, pass *all* to file_log
    action_level: error
    handler: file_log

    # now passed *all* logs, but only if one log is error or higher
    file_log:
    type: stream
    path: "%kernel.logs_dir%/%kernel.environment%.log"

    因此,在您的 prod.log 文件中只会记录包含一些错误的消息/请求,因此 bots 在此级别无效。

    有关此的更多详细信息 http://symfony.com/doc/current/logging.html


  1. 您尝试执行的操作是不可取的,因为处理程序 将依赖于 http 请求而不是日志记录,这将脱离上下文,但是您可以注册自己的 handler 在 Symfony 中很容易:

    让我们创建自定义处理程序类:

    namespace AppBundle\Monolog\Handler;

    use Monolog\Handler\AbstractHandler;

    class StopBotLogHandler extends AbstractHandler
    {
    public function isBotRequestDetected()
    {
    // here your code to detect Bot requests, return true or false
    // something like this:
    // return isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/bot|crawl|slurp|spider/i', $_SERVER['HTTP_USER_AGENT']);
    }

    /**
    * Checks whether the given record will be handled by this handler.
    *
    * This is mostly done for performance reasons, to avoid calling processors for nothing.
    *
    * Handlers should still check the record levels within handle(), returning false in isHandling()
    * is no guarantee that handle() will not be called, and isHandling() might not be called
    * for a given record.
    *
    * @param array $record Partial log record containing only a level key (e.g: array('level' => 100) for DEBUG level)
    *
    * @return bool
    */
    public function isHandling(array $record)
    {
    return $this->isBotRequestDetected();
    }

    /**
    * Handles a record.
    *
    * All records may be passed to this method, and the handler should discard
    * those that it does not want to handle.
    *
    * The return value of this function controls the bubbling process of the handler stack.
    * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
    * calling further handlers in the stack with a given log record.
    *
    * @param array $record The record to handle
    *
    * @return bool true means that this handler handled the record, and that bubbling is not permitted.
    * false means the record was either not processed or that this handler allows bubbling.
    */
    public function handle(array $record)
    {
    // do nothing, just returns true whether the request is detected as "bot", this will break the handlers loop.
    // else returns false and other handler will handle the record.

    return $this->isBotRequestDetected();
    }
    }

    无论何时向记录器添加记录,它都会遍历处理程序堆栈。每个处理程序决定它是否完全处理了记录,如果是,则记录的传播到此结束。

    重要:阅读 isHandling()handle() 方法的 phpdoc 以获取更多详细信息。

    接下来,让我们将类注册为“没有标签”的服务:

    # app/config/services.yml
    services:
    monolog.handler.stop_bot_log:
    class: AppBundle\Monolog\Handler\StopBotLogHandler
    public: false

    然后,将它的handler 添加到handlers 列表中:

    # app/config/config_prod.yml
    monolog:
    handlers:
    # ...

    stopbotlog:
    type: service
    id: monolog.handler.stop_bot_log
    priority: 1

    注意type属性必须等于serviceid必须是定义前的服务名和priority 必须大于 0 以确保其处理程序 将在任何其他处理程序之前执行。

    GoogleBot 向网站应用程序执行请求时,stopbotlog handler 停止在他之后的所有 handlers 并停止'注册任何日志消息。

    请记住,这不是推荐的方法!根据您的需要,实现选项 1 或 2 应该就足够了。


如果您想忽略机器人对处理程序组的请求,您可以覆盖 monolog.handler.group.class 容器参数并覆盖组 handler 行为:

namespace AppBundle\Handler;

use Monolog\Handler\GroupHandler;

class NoBotGroupHandler extends GroupHandler
{
public function isBotRequestDetected()
{
// here your code to detect Bot requests, return true or false
}

public function handle(array $record)
{
if ($this->isBotRequestDetected()) {
// ignore bot request for handlers list
return false === $this->bubble;
}

return parent::handle($record);
}
}

在您的 config_prod.ymlservices.yml 中:

parameters:
monolog.handler.group.class: AppBundle\Handler\NoBotGroupHandler

就是这样!现在,您可以停止自定义句柄列表的机器人日志:

# config_prod.yml
monolog:
handlers:
grouped:
type: group
members: [main, console, chromephp]

最后,如果您难以分析日志文件,我建议您使用这个神奇的工具:https://github.com/EasyCorp/easy-log-handler

关于php - 使用 MonologBu​​ndle 自定义 HandlerWrapper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39291248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com