knowledge/docs/php/monolog-mongo.md

166 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PHP实现把日志保存到mongodb中
`monolog`可以说是PHP中应用最为广泛的日志组件使用它可以方便的实现多种日志记录需求本文主要利用`monolog`的`MongoDBHandler`类,将日志保存至`mongodb`中。
## 环境
本文使用`webman`框架,用法基本与`laravel`大同小异。
## 准备工作
### 需要为php安装mongodb扩展
```sh
pecl install mongodb
```
> 也可以使用已经做好环境的docker镜像`docker pull wandoubaba517/workerman:8.1`
### monolog版本要在3.0以上
先创建一个全新的`webman`项目:
```sh
composer create-project workerman/webman
cd webman
```
`webman`中默认已经内置了`monolog`,不过我们要确保`monolog`的版本要在3.0以上:
```sh
compose require monolog/monolog:^3.0
```
### 用docker快速启动一下mongodb服务
```sh
mkdir -p log/db
touch mongod.conf
```
`mongod.conf`文件中的内容类似下面的样子:
```yml
storage:
dbPath: /data/db
net:
port: 27017
bindIp: 0.0.0.0
```
`docker-compose.yml`文件中添加`log`服务类似下面的样子把root和password换成你自己想要设置的
```yml
version: "3.1"
services:
log:
image: mongo:7.0
container_name: mongodb-log
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: log
volumes:
- ./log/db:/data/db
- ./log/mongod.conf:/etc/mongod.conf
network_mode: host
command: ['mongod', '--config', '/etc/mongod.conf']
```
执行`docker compose up -d`就可以启动mongodb服务了。
### 引入`mongodb/laravel-mongodb`组件
```sh
composer require mongodb/laravel-mongodb
```
## 实现代码
### `config/database.php`文件中配置mongodb连接
```php
return [
'default' => 'pgsql',
'connections' => [
'pgsql' => [
/// ...
],
'mongo' => [
'driver' => 'mongodb',
'host' => '127.0.0.1',
'port' => 27017,
'database' => 'log',
'username' => 'root',
'password' => 'password',
'options' => [
'appname' => 'homestead'
],
],
/// ...
]
];
```
### `config/log.php`文件中配置日志通道
```php
return [
'mongo' => [
'handlers' => [
[
'class' => Monolog\Handler\MongoDBHandler::class,
'constructor' => [
new Mongodb\Client('mongodb://root:password@localhost:27017'),
'log', // 数据库名
'default', // 集合名(相当于表名)
Monolog\Level::Debug, // 最低日志等级默认就是Debug
],
],
],
],
/// ...
];
```
### 业务代码中应用
以`app/controller/IndexController.php`中的`log`方法为例:
```php
<?php
namespace app\controller;
use support\Request;
use support\Db;
use support\Log;
class IndexController
{
public function log(Request $request)
{
// 随便记录点什么日志
Log::channel('mongo')->info(__CLASS__ . DIRECTORY_SEPARATOR . __FUNCTION__, $request->all());
$logs = Db::connection('mongo')->collection('default')->get();
return json($logs);
}
}
```
### 运行测试
启动服务,然后用浏览器或者接口调试工具访问`http://IP:port/index/log`,控制器方法会先记录一条日志,然后再把整所有已经保存的日志全部都输出回来。
## 与文本日志对比
主要优势方便查询文本日志文件的最小粒度是一天一个文件当日志量具大时在几百M或者几个G甚至更大的一个文本文件中定位某行记录简直就是灾难
主要劣势:需要自行处理过期记录(文本日志可以自动删除过期的文件)。
## 推荐
本文作者建好了一个开箱即用的webman+mongodb代码仓库<https://git.wandoubaba.com/wandoubaba/docker-webman-mongolog>