swoft 事件监听和触发 打印sql日志
需求 打印出swoft的所有sql日志到控制台或者文件
只要打开listener 下面 Dbranlisten.php 里面最后一行注释即可,swoft已经帮我们实现好了
____ _____ ___ ___
/ __/ _____ / _/ /_ |_ | / _ \
_\ \| |/|/ / _ \/ _/ __/ / __/_/ // /
/___/|__,__/\___/_/ \__/ /____(_)___/ SERVER INFORMATION(v2.0.9)
********************************************************************************
* HTTP | Listen: 0.0.0.0:18306, Mode: Process, Worker: 6, Task worker: 12
******************************************************************************** HTTP Server Start Success!
2020/07/17-20:55:29 [INFO] Swoft\Server\Server:startSwoole(491) Swoole\Runtime::enableCoroutine
2020/07/17-20:55:29 [INFO] Swoft\Listener\BeforeStartListener:handle(27) Server extra info: pidFile @runtime/swoft.pid
2020/07/17-20:55:29 [INFO] Swoft\Listener\BeforeStartListener:handle(28) Registered swoole events:
start, shutdown, managerStart, managerStop, workerStart, workerStop, workerError, request, task, finish
Server start success (Master PID: 17681, Manager PID: 17686)
[INFO] insert into `tb_users` (`name`, `age`, `created_at`) values ('test', 10, '2020-07-17 20:55:50')
为什么会监听到日志 事件什么时候触发的
/**
* Class RanListener
*
* @since 2.0
*
* @Listener(DbEvent::SQL_RAN)
*/
/**
* Sql ran after
*/
public const SQL_RAN = 'swoft.db.ran';
全项目搜索 DbEvent::SQL_RAN 发现除了调用的地方 还有写入的地方
Connection.php
/**
* Run a SQL statement and log its execution context.
*
* @param string $query
* @param array $bindings
* @param Closure $callback
*
* @return mixed
*
* @throws DbException
*/
protected function run(string $query, array $bindings, Closure $callback)
{
$this->reconnectIfMissingConnection();
$start = microtime(true);
// Here we will run this query. If an exception occurs we'll determine if it was
// caused by a connection that has been lost. If that is the cause, we'll try
$result = $this->runQueryCallback($query, $bindings, $callback);
$time = $this->getElapsedTime($start);
$this->fireEvent(DbEvent::SQL_RAN, $query, $bindings, $time); // Once we have run the query we will calculate the time that it took to run and
// then log the query, bindings, and execution time so we will report them on
// the event that the developer needs them. We'll log time in milliseconds.
return $result;
} 这个方法 $this->fireEvent(DbEvent::SQL_RAN, $query, $bindings, $time);
往下
HasEvent.php /**
* Fire the given event for the model.
*
* @param string $event
* @param mixed ...$args
*
* @return bool
*/
protected function fireEvent(string $event, ...$args): bool
{
// Trigger method public event
$eventPublicResult = Swoft::trigger($event, $this, ...$args);
if ($eventPublicResult->isPropagationStopped() === true) {
return false;
} // Not model no trigger
if ($this->getContextName() !== 'model') {
return true;
}
// Trigger model method event
$modelEventResult = Swoft::trigger($this->getModelEventName($event), $this, ...$args);
if ($modelEventResult->isPropagationStopped() === true) {
return false;
} return true;
} 发现 Swoft::trigger($event, $this, ...$args); 往下 Swoft.php
/**
* Trigger an swoft application event
*
* @param string|EventInterface $event eg: 'app.start' 'app.stop'
* @param null|mixed $target
* @param array $params
*
* @return EventInterface
*/
public static function trigger($event, $target = null, ...$params): EventInterface
{ /** @see EventManager::trigger() */
return BeanFactory::getSingleton('eventManager')->trigger($event, $target, $params);
} EventManage.php
/**
* Trigger an event. Can accept an EventInterface or will create one if not passed
*
* @param string|EventInterface $event 'app.start' 'app.stop'
* @param mixed|string $target It is object or string.
* @param array|mixed $args
*
* @return EventInterface
* @throws InvalidArgumentException
*/
public function trigger($event, $target = null, array $args = []): EventInterface
{
if ($isString = is_string($event)) {
$name = trim($event);
} elseif ($event instanceof EventInterface) {
$name = trim($event->getName());
} else {
throw new InvalidArgumentException('Invalid event params for trigger event handler');
} $shouldCall = []; // Have matched listener
if (isset($this->listenedEvents[$name])) {
$shouldCall[$name] = '';
} // Like 'app.db.query' => prefix: 'app.db'
if ($pos = strrpos($name, '.')) {
$prefix = substr($name, 0, $pos); // Have a wildcards listener. eg 'app.db.*'
$wildcardEvent = $prefix . '.*';
if (isset($this->listenedEvents[$wildcardEvent])) {
$shouldCall[$wildcardEvent] = substr($name, $pos + 1);
}
} // Not found listeners
if (!$shouldCall) {
return $isString ? $this->basicEvent : $event;
} /** @var EventInterface $event */
if ($isString) {
$event = $this->events[$name] ?? $this->basicEvent;
} // Initial value
$event->setName($name);
$event->setParams($args);
$event->setTarget($target);
$event->stopPropagation(false); // Notify event listeners
foreach ($shouldCall as $name => $method) {
$this->triggerListeners($this->listeners[$name], $event, $method); if ($event->isPropagationStopped()) {
return $this->destroyAfterFire ? $event->destroy() : $event;
}
} // Have global wildcards '*' listener.
if (isset($this->listenedEvents['*'])) {
$this->triggerListeners($this->listeners['*'], $event);
} return $this->destroyAfterFire ? $event->destroy() : $event;
} 调用 triggerListeners
/**
* @param array|ListenerQueue $listeners
* @param EventInterface $event
* @param string $method
*/
protected function triggerListeners($listeners, EventInterface $event, string $method = ''): void
{
// $handled = false;
$name = $event->getName();
$callable = false === strpos($name, '.'); // 循环调用监听器,处理事件
foreach ($listeners as $listener) {
if ($event->isPropagationStopped()) {
break;
} if (is_object($listener)) {
if ($listener instanceof EventHandlerInterface) {
$listener->handle($event);
} elseif ($method && method_exists($listener, $method)) {
$listener->$method($event);
} elseif ($callable && method_exists($listener, $name)) {
$listener->$name($event);
} elseif (method_exists($listener, '__invoke')) {
$listener($event);
}
} elseif (is_callable($listener)) {
$listener($event);
}
}
} 最终调用监听的 hadle方法
所以是 调动trigger 就会触发匹配到的监听,执行监听的hanle方法
模仿 自己触发event 自己listen
控制器 HomeController 里面新建方法
/**
* @RequestMapping("/add")
*/
public function add()
{
// $user = new Users();
// $user->fill(['name'=>'test','age'=>10])->save();
// return $user; Swoft::trigger("swoft.wang","this is message",'hello','world');
}
app\Listener\Test\WangListener.php
<?php declare(strict_types=1);
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://swoft.org/docs
* @contact group@swoft.org
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/ namespace App\Listener\Test; use Swoft\Event\Annotation\Mapping\Listener;
use Swoft\Event\EventHandlerInterface;
use Swoft\Event\EventInterface;
use Swoft\Exception\SwoftException;
use Swoft\Log\Helper\CLog;
use Swoft\Server\SwooleEvent; /**
* Class ShutDownListener
*
* @since 2.0
*
* @Listener("swoft.wang")
*/
class WangListener implements EventHandlerInterface
{
/**
* @param EventInterface $event
*
* @throws SwoftException
*/
public function handle(EventInterface $event): void
{ $message = $event->getTarget();
$hello = $event->getParam(0);
$world = $event->getParam(1); var_dump($message,$hello,$world); CLog::debug('this is a test trigger');
}
}
访问页面 http://192.168.33.50:18306/add 发现结果为 如下 自己触发的事件被自己监听到了,打印出了参数
____ _____ ___ ___
/ __/ _____ / _/ /_ |_ | / _ \
_\ \| |/|/ / _ \/ _/ __/ / __/_/ // /
/___/|__,__/\___/_/ \__/ /____(_)___/ SERVER INFORMATION(v2.0.9)
********************************************************************************
* HTTP | Listen: 0.0.0.0:18306, Mode: Process, Worker: 6, Task worker: 12
******************************************************************************** HTTP Server Start Success!
2020/07/17-21:06:09 [INFO] Swoft\Server\Server:startSwoole(491) Swoole\Runtime::enableCoroutine
2020/07/17-21:06:09 [INFO] Swoft\Listener\BeforeStartListener:handle(27) Server extra info: pidFile @runtime/swoft.pid
2020/07/17-21:06:09 [INFO] Swoft\Listener\BeforeStartListener:handle(28) Registered swoole events:
start, shutdown, managerStart, managerStop, workerStart, workerStop, workerError, request, task, finish
Server start success (Master PID: 17738, Manager PID: 17743)
string(15) "this is message"
string(5) "hello"
string(5) "world"
swoft 事件监听和触发 打印sql日志的更多相关文章
- DOM事件监听和触发
EventTargetAPI定义了DOM事件(mouse事件等)的监听和触发方法,所有的DOM节点都部署了这个接口. 这个接口有三个方法:addEventListener, removeEventLi ...
- MVC框架入门准备(三)事件类 - 事件的监听和触发
在mvc框架中可以看到事件类,实现事件的监听和触发. 举例: <?php /** * 事件类 */ class Event { // 事件绑定记录 private static $events; ...
- Node.js 教程 05 - EventEmitter(事件监听/发射器 )
目录: 前言 Node.js事件驱动介绍 Node.js事件 注册并发射自定义Node.js事件 EventEmitter介绍 EventEmitter常用的API error事件 继承EventEm ...
- Spring Boot实践——事件监听
借鉴:https://blog.csdn.net/Harry_ZH_Wang/article/details/79691994 https://blog.csdn.net/ignorewho/arti ...
- 十一、Spring之事件监听
Spring之事件监听 ApplicationListener ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成Applica ...
- Spring的事件监听ApplicationListener
ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制. 如果容器中存在Applica ...
- Zookeeper开源客户端Curator之事件监听详解
Curator对Zookeeper典型场景之事件监听进行封装,提供了使用参考.这篇博文笔者带领大家了解一下Curator的实现方式. 引入依赖 对于Curator封装Zookeeper的典型场景使用都 ...
- thinkphp6事件监听event-listene
事件系统可以看成是行为系统的升级版,相比行为系统强大的地方在于事件本身可以是一个类,并且可以更好的支持事件订阅者. 事件相比较中间件的优势是事件比中间件更加精准定位(或者说粒度更细),并且更适合一些业 ...
- Java中用得比较顺手的事件监听
第一次听说监听是三年前,做一个webGIS的项目,当时对Listener的印象就是个"监视器",监视着界面的一举一动,一有动静就触发对应的响应. 一.概述 通过对界面的某一或某些操 ...
随机推荐
- 第一次编程作业(My Own Score)
博客班级 https://edu.cnblogs.com/campus/fzzcxy/2018SE2 作业要求 https://edu.cnblogs.com/campus/fzzcxy/2018SE ...
- 记一次函数异常(getopt_long)
前言 以下参考博客以及man手册. getopt_long函数,getopt_long函数包含了getopt函数的功能,并且还可以指定"长参数"(或者说长选项),与getopt函数 ...
- C#开发PACS医学影像处理系统(十五):Dicom影像交叉定位线算法
1.定位线概念:某个方位的影像在另一个方向的影像上的投影相交线,例如横断面(从头到脚的方向)在矢状面(从左手到右手)上的影像投影面交线. 举个例子:右边的是MR(核磁共振)的某一帧切片,这是从头开始扫 ...
- Linux实战(19):Shell交互式read 用法
read 用法有好几种,我在实战过程中用到了 -p,记一笔以防不用忘记了. 实例 #!/bin/bash echo "检测IP是否被占用" while read -p " ...
- Java审计之文件操作漏洞
Java审计之文件操作漏洞篇 0x00 前言 本篇内容打算把Java审计中会遇到的一些文件操作的漏洞,都给叙述一遍.比如一些任意文件上传,文件下载,文件读取,文件删除,这些操作文件的漏洞. 0x01 ...
- 测试工具-XPath使用
XML有两种MIME类型,即application/xml和text/xml,在HTTP中,MIME Type类型被定义在Content-Type header中.我们经常也会看到接口返回数据类型为X ...
- 基于NPOI的Excel导入导出类库
概述 支持多sheet导入导出.导出字段过滤.特性配置导入验证,非空验证,唯一验证,错误标注等 用于基础配置和普通报表的导入导出,对于复杂需求,比如合并列,公式,导出图片等暂不支持 GitHub地址: ...
- git如何上传文件夹
git是不支持上传空文件夹的,文件夹里面必须有文件才可以 1.本地仓库上传文件夹到远程 在本地仓库新建一个文件夹,如果里面没有文件,那么$ git push origin master 不能将文件夹p ...
- 模型集成model ensemble
A prediction model that is composed of a set of models is called a model ensemble. Baggging 和Boostin ...
- 【Java】socket编程,输入输出中的问题
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWri ...