- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用 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...
防止机器人访问您站点的快速方法是将这两行放入服务器上的 /robots.txt
文件中。在 'web' 目录中创建一个 robots.txt
文件并粘贴以下内容:
User-agent: *
Disallow: /
当您需要完全避免访问时,这是推荐的选项,这意味着您的网站将不再被搜索引擎和其他机器人编入索引。您无需在应用程序中配置/实现任何内容即可实现。
现在,如果您需要机器人进入,但又不想在日志中注册它。不是在某处写入日志文件,一些 处理程序用于在将日志条目发送到其他 处理程序之前过滤或修改日志条目。默认情况下,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
您尝试执行的操作是不可取的,因为处理程序 将依赖于 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
属性必须等于service
,id
必须是定义前的服务名和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.yml
或 services.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 - 使用 MonologBundle 自定义 HandlerWrapper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39291248/
我是一名优秀的程序员,十分优秀!