hypef 九、日志

教程:Hyperf

hyperf结合monolog是属于低耦合,通过配置文件和调用工厂类设置参数设置实例。

monolog详见Monolog 修改_lsswear的博客-CSDN博客,理解monolog原理之后若有对应的报错比较好改。

一、使用LoggerFactory

#/config/autoload/logger.php
return ['default' => ['handler' => ['class' => Monolog\Handler\StreamHandler::class,'constructor' => ['stream' => BASE_PATH . '/runtime/logs/hyperf.log','level' => Monolog\Logger::DEBUG,],],'formatter' => ['class' => Monolog\Formatter\LineFormatter::class,'constructor' => ['format' => null,'dateFormat' => 'Y-m-d H:i:s','allowInlineLineBreaks' => true,],],],'test1' => ['handler' => ['class' => Monolog\Handler\RotatingFileHandler::class,'constructor' => ['stream' => BASE_PATH . '/runtime/logs/test1.log','level' => Monolog\Logger::DEBUG,'filename' => BASE_PATH . '/runtime/logs/test1.log',],],'formatter' => ['class' => Monolog\Formatter\JsonFormatter::class,'constructor' => ['format' => null,'dateFormat' => 'Y-m-d H:i:s','allowInlineLineBreaks' => true,],],],
];
#/config/autoload/dependencies.php
return [Psr\Log\LoggerInterface::class => Hyperf\Logger\LoggerFactory::class,
];#App\Service\LogService
class LogService
{/*** @Inject* @var LoggerInterface*/protected $logger;public function __construct(LoggerFactory $loggerFactory){// 第一个参数对应日志的 name, 第二个参数对应 config/autoload/logger.php 内的 key//$this->logger = $loggerFactory->get('log', 'default');$this->logger = $loggerFactory->get('log1', 'test1');}public function info($info, $content = []){$this->logger->info($info, $content);}
}#App\Controller\TestController
/*** @AutoController()*/
class TestController extends AbstractController
{/*** @Inject* @var LogService*/private $logserver;
public function testlog1(){$this->logserver->info('test1', ['qwe' => '123', 'asd' => '6778']);}
}#日志输出 /runtime/logs/test1-2023-07-19.log
{"message":"test1","context":{"qwe":"123","asd":"6778"},"level":200,"level_name":"INFO","channel":"log1","datetime":"2023-07-19T09:57:04.018739+00:00","extra":{}}

若dependencies.php没设置,就是官网的写法,不能用Inject注入。

 /*** @var \Psr\Log\LoggerInterface*/protected $logger;public function __construct(LoggerFactory $loggerFactory){// 第一个参数对应日志的 name, 第二个参数对应 config/autoload/logger.php 内的 key$this->logger = $loggerFactory->get('log', 'default');}

二、静态调用

因为是静态调用,会不走构造,所以日志实例对象不能放到构造。

#App\Service\LogService2
use Hyperf\Utils\ApplicationContext;
use \Hyperf\Logger\LoggerFactory;class LogService2
{static $obj;static $logger;public static function get($name = "app"){self::$logger = self::$obj->get($name, 'test1');return self::$logger;}public static function __callStatic($funcname, $arguments){$container = ApplicationContext::getContainer();self::$obj = $container->get(LoggerFactory::class);$name = isset($arguments[2]) ? $arguments[2] : 'test1';$msg = $arguments[0];$data = isset($arguments[1]) ? $arguments[1] : [];self::get($name);self::$logger->$funcname($msg, $data);}
}#App\Controller\TestController
public function testlog1(){//$this->logserver->info('test1', ['qwe' => '123', 'asd' => '6778']);LogService2::info('test2', ['qqq' => '555']);}#日志输出
{"message":"test2","context":{"qqq":"555"},"level":200,"level_name":"INFO","channel":"test1","datetime":"2023-07-20T09:49:11.443349+00:00","extra":{}}

三、改造

#App\Service\MlogService
class MlogService extends RotatingFileHandler
{protected function streamWrite($stream, array $record): void{$str = (string) $record['formatted'] . PHP_EOL . var_export($record['context'], true) . PHP_EOL;fwrite($stream, $str);}
}#/config/autoload/logger.php
'test2' => ['handler' => ['class' => App\Service\MlogService::class,'constructor' => ['stream' => BASE_PATH . '/runtime/logs/test2.log','level' => Monolog\Logger::DEBUG,'filename' => BASE_PATH . '/runtime/logs/test2.log',],],'formatter' => ['class' => Monolog\Formatter\LineFormatter::class,'constructor' => ['format' => "[%datetime%] %channel%.%level_name%: %message%\n%extra%\n",'dateFormat' => 'Y-m-d H:i:s','allowInlineLineBreaks' => true,],],],#App\Service\LogService2
public static function get($name = "app"){//self::$logger = self::$obj->get($name, 'test1');self::$logger = self::$obj->get($name, 'test2');return self::$logger;}#App\Controller\TestController
public function testlog2(){LogService2::info('test3', ['qqq1' => '555-0']);}#日志输出
[2023-07-21 09:30:38] test1.INFO: test3
[]array ('qqq1' => '555-0',
)

可以看到数组是有格式输出,这样再看起来就非常舒服。

四、stdout日志

根据文档,大概意思就是框架默认是使用Hyperf\Framework\Logger\StdoutLogger类输入日志到命令行,通过设置dependencies.php改变处理类。

使用举例

#Hyperf\DbConnection\Connection
public function __construct(ContainerInterface $container, DbPool $pool, array $config){parent::__construct($container, $pool);$this->factory = $container->get(ConnectionFactory::class);$this->config = $config;$this->logger = $container->get(StdoutLoggerInterface::class);$this->reconnect();}public function reconnect(): bool{……$this->connection->setReconnector(function ($connection) {$this->logger->warning('Database connection refreshing.');if ($connection instanceof \Hyperf\Database\Connection) {$this->refresh($connection);}});……}
#Hyperf\Framework\Logger\StdoutLogger
public function warning($message, array $context = []): void{$this->log(LogLevel::WARNING, $message, $context);}
/*** {@inheritdoc}*/public function log($level, $message, array $context = []): void{$config = $this->config->get(StdoutLoggerInterface::class, ['log_level' => []]);if (! in_array($level, $config['log_level'], true)) {return;}$keys = array_keys($context);$tags = [];foreach ($keys as $k => $key) {if (in_array($key, $this->tags, true)) {$tags[$key] = $context[$key];unset($keys[$k]);}}$search = array_map(function ($key) {return sprintf('{%s}', $key);}, $keys);$message = str_replace($search, $context, $this->getMessage((string) $message, $level, $tags));$this->output->writeln($message);}#Hyperf\Framework\ConfigProvider
use Hyperf\Contract\ApplicationInterface;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Framework\Logger\StdoutLogger;public function __invoke(): array{return ['dependencies' => [ApplicationInterface::class => ApplicationFactory::class,StdoutLoggerInterface::class => StdoutLogger::class,],'annotations' => ['scan' => ['paths' => [__DIR__,],],],];}

使用之前设置的可静态调用Service类做处理,调用monolog直接将输出屏幕的内容输出到日志中。

#App\Service\StdoutLoggerService
class StdoutLoggerService
{public function __invoke(ContainerInterface $container){return LogService2::get('sys');}
}
#App\Service\LogService2public static function get($name = "app"){//self::$logger = self::$obj->get($name, 'test1');if (empty(self::$obj)) {$container = ApplicationContext::getContainer();self::$obj = $container->get(LoggerFactory::class);}self::$logger = self::$obj->get($name, 'test2');return self::$logger;}#

根据两段代码,调用都是info、warning这种只不过实现的具体方法不一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/8557.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git相关

gerrit用户指南: 资料:Gerrit 用户指南 gerrit-user-guide 上述有介绍如何review,review并非修改代码之后如何重新提交等操作 jenkins介绍 Jenkins详细教程 - 知乎 一、jenkins是什么? Jenkins是一个开源的、提供友好操作界…

使用Ensp配置DHCP协议

如何使用Ensp配置DHCP协议,为PC自动分配IP地址 什么是DHCP? Dynamic Host Configuration Protocol,动态主机配置协议,简单理解为自动分配IP地址,有了这个协议就不用手动配置IP地址了,如图 思路 给路由…

iptable的备份和还原

1、写在命令行当中的都是临时配置 2、把我们的规则配置在服务的文件当中,形成永久生效, iptables -save > /opt/test(自设) #进行备份 /etc/sysconfig/iptables #默认配置文件 写在配置文件中才会永久生效 iptables-r…

Docker如何使用

一、Docker安装 命令:curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 1.1 Docker技术的三大核心概念 镜像:类似一个root系统文件 容器:镜像运行的实体,可以被创建、启动、停止、删除、暂停等 仓库:保存镜像 二、镜…

Ubuntu 上编译protobuf 指

欢迎大家关注我的B站主页MYVision_MY视界的个人空间-MYVision_MY视界个人主页-哔哩哔哩视频 下载protobuf GitHub - protocolbuffers/protobuf: Protocol Buffers - Googles data interchange format 根据需要从release 中下载指定的版本 下载完之后,根据提供的C…

Godot 4 着色器 - Shader调试

我之前用OpenCV进行图像相关处理,觉得已经很不错,结合GDI可以实现流畅的动画效果 直到近来用Shader后才发现,着色器更上一层楼,原来这是入了GPU的坑 Shader编程限制很多,各种不支持,看在它性能不错功能炫…

让vue项目支持glsl语法

如果你想让Vue项目支持GLSL(OpenGL着色语言)语法,你需要使用特殊的加载器使Webpack能够加载和解析GLSL文件。这一般可以通过下面的步骤实现: Install webpack-glsl-loader: npm install webpack-glsl-loader--save-dev如果你使用…

发布npm包流程

发布npm包的步骤如下: 在终端中通过 npm init 命令创建一个新的npm包,按照提示填写包的信息,如包名称、版本、描述、作者、许可证等。 在包的根目录下创建一个 index.js 文件,编写你的代码。 确认你已经注册了npm账号&#xff0…

深入浅出Pytorch函数——torch.max

分类目录:《深入浅出Pytorch函数》总目录 相关文章: 深入浅出Pytorch函数——torch.max 深入浅出Pytorch函数——torch.maximum torch.max有三种输入形式,根据其输入形式及参数的不同有下列三种返回形式: torch.max(input)&…

mysql进阶2——prosysql实现mysql读写分离

文章目录 一、读写分离方案类型1.1 最简单的读写分离1.2 多个读组或写组的分离模式 二、案例2.1 初始化操作2.2 mysql主添加proxysql连接用户2.3 Proxysql添加连接mysql集群参数2.4 添加健康检测用户2.5 添加读写分离的路由规则2.6 验证 一、读写分离方案类型 基本了解&#xf…

pytorch工具——pytorch中的autograd

目录 关于torch.tensor关于tensor的操作关于梯度gradients 关于torch.tensor 关于tensor的操作 x1torch.ones(3,3) xtorch.ones(2,2,requires_gradTrue) print(x1,\n,x)yx2 print(y) print(x.grad_fn) print(y.grad_fn)zy*y*3 outz.mean() print(z,out)注意 atorch.randn(2,…

音视频——压缩原理

H264视频压缩算法现在无疑是所有视频压缩技术中使用最广泛, 最流行的。随着 x264/openh264以及ffmpeg等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大降低了人们使用H264的成本。 但为了用好H264,我们还是要对…

spring学习笔记七

一、自动装配 1.1、BookDao接口和实现类 public interface BookDao {void save(); } public class BookDaoImpl implements BookDao {public void save(){System.out.println("book dao save......");} } 1.2、BookService接口和实现类 public interface BookSer…

又一家车企陷「软件门」僵局,全栈自研成「疑难杂症」

过去几年,因为汽车智能化软件开发不及预期而造成的新车发布推迟,已经不是什么新鲜事。典型的代表,就是大众集团。 上周,因为PPE平台及软件开发问题,大众集团旗下豪华品牌奥迪宣布与上汽集团达成战略合作,联…

JVM分享

JVM分享 官网:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html Java代码的执行流程 我们编写完之后的java文件如果要运行,java文件会编译成class文件,在jvm中运行时ClassLoader会加载class文件,加载进来之后&a…

mac电脑强大的解压缩软件BetterZip 5.3.4 for Mac中文版及betterzip怎么压缩

BetterZip 5.3.4 for Mac 是Mac系统平台上一款功能强大的文件解压缩软件,不必解压就能快速地检查压缩文档。它能执行文件之间的合并并提供密码。使用它,用户可以更快捷的向压缩文件中添加和删除文件。它支持包括zip、gz、bz、bz2、tar、tgz、tbz、rar、7…

Langchain 的 Validate template

Langchain 的 Validate template 默认情况下, PromptTemplate 将通过检查 input_variables 是否与 template 中定义的变量匹配来验证 template 字符串。您可以通过将 validate_template 设置为 False 来禁用此行为。 template "I am learning langchain beca…

nfs服务器的描述,搭建和使用

前言 这是我在这个网站整理的笔记,关注我,接下来还会持续更新。 作者:RodmaChen nfs服务器的描述,搭建和使用 NFS概述工作原理优缺点 nfs服务器搭建服务端客户端 NFS概述 NFS(Network File System)是一种基…

Webpack5 对bundle分析

文章目录 为什么要对bundle分析使用BundleAnalyzerPlugin 为什么要对bundle分析 bundle是Webpack打包的产物,通过分析bundle包的大小和模块关系等信息,我们可以更好地理解代码打包结果,并且继续优化 bundle 大小和性能。 使用BundleAnalyze…

Go 语言入门指南

Go 语言入门指南 学一门语言先看看helloworld吧,感觉go结合了好多语言的方式,写起来一会像python一会像c,java差不多。反正语法挺奇特 package mainimport "fmt"func main() {fmt.Println("HelloWorld") }go语言特点&a…