# 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 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代码仓库: