- 为什么要用Elasticsearch存储Laravel日志而不是直接使用默认的文件存储?
- 当PHP部署在多台服务器时,如果需要查找日志则要在每台服务器上面进行查找。
- 通常日志是按天分割的,如果不确定是哪一天还需要在好几个文件里面进行查找,然后需要查找的文件数就变成了不确定的天数*负载均衡的服务器数量。
- 在服务器上面直接通过命令行查询查找日志内容真的不方便。
- 开始折腾
- 首先得有Elasticsearch服务器,自己在服务器上面安装或者使用第三方提供的服务,我这里直接使用AWS的服务。
- 因为Elasticsearch就是通过标准的RESTful接口进行操作,所以PHP也就不用安装什么扩展了,但是为了方便使用还是要安装一个Packagist:
https://packagist.org/packages/elasticsearch/elasticsearch
composer require elasticsearch/elasticsearch
如果没使用过可以看中文文档:
https://www.elastic.co/guide/cn/elasticsearch/php/current/index.html
- 这里我就不安装Laravel的package,毕竟只是把日志写到Elasticsearch就行了,所以自己动手写个简单的
ElasticsearchClient
类,里面就只有一个getClient
方法:
<?php
/**
*===================================================
* Filename:ElasticsearchClient.php
* Author:f4ck_langzi@foxmail.com
* Date:2018-06-15 18:31
*===================================================
**/
namespace App\Libs;
use Elasticsearch\ClientBuilder;
class ElasticsearchClient
{
private $client;
public function __construct()
{
$hosts = config('elasticsearch.hosts');
$this->client = ClientBuilder::create()->setHosts($hosts)->build();
}
public function getClient()
{
return $this->client;
}
}
为了能够配置Elasticsearch相关信息,我创建了配置文件elasticsearch.php
,只有hosts
和log_name(Index)
:
<?php
/**
*===================================================
* Filename:elasticsearch.php
* Author:f4ck_langzi@foxmail.com
* Date:2018-06-15 18:32
*===================================================
**/
return [
'hosts'=>[
env('ELASTIC_HOST')
],
'log_name'=>env('ELASTIC_LOG_NAME')
];
现在就可以在Laravel中通过(new ElasticsearchClient())->getClient()
来获取到Elasticsearch的Client
对象了。
4. 在页面的每一次请求中肯定会打印多次日志,如果每次打印日志都要创建Elasticsearch的Client
对象就会会消耗一定的时间和性能,为了能够更加优雅的使用Client
对象,我创建了一个ElasticsearchClientProvider
:
<?php
namespace App\Providers;
use App\Libs\ElasticsearchClient;
use Illuminate\Support\ServiceProvider;
class ElasticsearchClientProvider extends ServiceProvider
{
protected $defer = true;
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->singleton('elasticsearch', function () {
return new ElasticsearchClient();
});
}
public function provides()
{
return ['elasticsearch'];
}
}
有了这个就不用每次都来new一次,使用的时候通过app('elasticsearch')->getClient();
直接从容器中拿出来就即可;其实还可以写个Facade
门脸类来进一步简化代码,这里就不去麻烦了。
5. 以上步骤只是把Elasticsearch集成到了Laravel中,要想把日志直接放到Elasticsearch还需要一些工作。
6. 接下来修改Laravel默认的Log存储方式为Elasticsearch,通过网上查询资料发现有两种方式可以修改:
http://www.muyesanren.com/2017/09/15/laravel-how-to-store-logging-with-mongodb/
第一种是在bootstrap/app.php
的return $app<