我想在Docker中使用Fluentd来模拟灵活的PHP应用程序日志管理。(3)
大家好。
上一次我们成功地将 PHP 日志从 Fluentd 发送到用于日志聚合的 Fluentd 服务器。
这一次,我们要通过将日志存储到聚合服务器的 MongoDB 服务器上,来实现标题中的 “灵活日志”。
查看以下存储库可以了解这次的结果:https://github.com/niisan-tokyo/log_experioment/tree/IndMongo
另外,正如上次一样,所有使用Docker命令的部分都是在虚拟机的atomic host上进行的。
引入MongoDB
为什么选择MongoDB?
虽然这可能已经成为常识,但我还是会解释一下为什么要引入MongoDB。
MongoDB的特点在于它是一个无模式的数据库,也就是说,“不需要或不存在表定义”。
在MongoDB中,与MySQL的“表”相对应的概念是“集合”。在MySQL中,必须预先确定表的列有哪些,而在集合中,每个存储的数据都可以具有自由的字段(列)。而且,即使没有预先定义集合,只要指定一个新的集合名称并插入数据,就可以创建一个新的集合。而且,数据库也会自动创建。
总之,它具有极高的灵活性。
我们稍后将解释这些特点如何发挥作用。
安装MongoDB
既然本次与上次一样需要创建Dockerfile,感觉有些麻烦,但实际上官方已经提供了Docker镜像的分发,我们可以使用它。
docker pull mongo:latest
既然已经创建好了包含MongoDB的Docker镜像,让我们立即启动吧。
docker run --name logmongo -d -p 27017:27017 mongo
这样就完成了
现在已经可以从外部连接MongoDB了。我能够通过192.168.33.40:27017连接到MongoDB。这太简单了,令人惊讶。
重新创建Fluentd的映像
由于以前创建的Fluentd镜像是将聚合日志输出到文件中,所以必须更改配置。由于追求不变性,只要配置文件发生变化,就必须重新创建镜像。
尽管如此,在重新制作图像时,对于与上次相比没有任何变化的部分,只需使用缓存,处理将立即结束。
配置文件
設定文件的更改位置如下所示。
<match app.**>
- type file
- path /var/log/td-agent/app
+# type file
+# path /var/log/td-agent/app
+type mongo
+host logmongo
+port 27017
+database applog
+tag_mapped
+remove_tag_prefix app
</match>
在这个设置中,特别重要的选项是tag_mapped。
这个设置文件的意思是,当以”app.”作为前缀的标签的日志到达时,将日志发送到名为logmongo的主机上的端口27017,按照MongoDB接口的方式处理。
在这个过程中,选择的数据库是applog,但是这次没有指定特定的集合。使用tag_mapped选项,可以根据标签名称自动设置集合。
由于设置了remove_tab_prefix为”app”,所以选择的日志存储目的地是去掉标签中”app”部分的名称的集合。
因为设置文件已经修改完成,让我们重新构建Fluentd。
docker build -t niisan-tokyo/fluentd dockers/fluentd/
习惯了之后非常容易。
确认柔软的日志
查看日志
我们开始启动容器并确认日志是否正确存储到MongoDB中。由于之前已经启动了MongoDB服务器,所以无需改变。
# docker run -d --name fluentlogger --link logmongo:logmongo niisan-tokyo/fluentd
# docker run -d --name web -p 8080:8080 --link fluentlogger:logger niisan-tokyo/php56
使用这个链接http://192.168.33.40:8080/访问,并且提交一些值。然后,查看日志,但因为没有MongoDB的客户端,所以暂时准备一个随意的工具。我使用了MongoHub。
那么,我们立刻来看一下它的内容吧。

由于输入的值已经被存储,日志的存储已成功。
如果没有任何显示,则可能是由于从WEB服务器发送日志的延迟,所以请耐心等待。
尝试添加一个字段
让我们来确认一下,当表单中添加了字段后的操作。我们将在以下的模板文件中,在docker容器上进行修改试试:
https://github.com/niisan-tokyo/log_experioment/blob/master/niisan-tokyo/Logexp/src/Resource/Page/Index.html.twig
# docker exec -it web /bin/bash
# vi src/Resource/Page/Index.html.twig
在此示例中,docker exec是一条命令,用于在正在运行的容器上执行外部处理,本次是启动了bash。以下是通过vi进行的编辑内容。
<form method="POST" action=".">
スコア1<input type="text" name="score1" /><br>
スコア2<input type="text" name="score2" /><br>
スコア3<input type="text" name="score3" /><br>
+ スコア4<input type="text" name="score4" /><br>
<input type="submit" value="送信" />
</form>
现在,分数字段已经变为了4个。
同样地,我也会对处理进行修正。
- public function onPost($score1, $score2, $score3)
+ public function onPost($score1, $score2, $score3, $score4)
{
- for($num = 1; $num < 4; $num++) {
+ for($num = 1; $num < 5; $num++) {
$str = 'score'.$num;
$res[$str] = intval($$str);
}
$this->logger->post('app.scores', $res);
}

请注意,在这个集合中,有一些数据有score4这个字段,而其他数据没有。这是使用MongoDB的模式特性得出的结果,就像我之前提到的一样。
换句话说,只需在PHP代码中随意添加字段,日志存储的数据库会灵活适应这些添加。而且,MongoDB作为一个名为数据库的数据存储系统,也具有数据库的功能,可以创建索引和进行聚合操作,但这次我们不涉及这些。
试试添加新的日志
此外,让我们突然尝试添加以下类似的代码:
+ $sum = 0;
for($num = 1; $num < 5; $num++) {
$str = 'score'.$num;
$res[$str] = intval($$str);
+ $sum += $res[$str];
}
$this->logger->post('app.scores', $res);
+ $this->logger->post('app.sum', ['sum' => $sum]);
经此操作,一个新的集合将被创建,并且额外保存了各自和分数的数据将被添加进去。
总结
现在,成功地通过使用Fluentd和MongoDB,在Docker上实现了对PHP日志进行灵活管理的模拟。本次文章涵盖的内容可能已经在许多地方被广泛应用,并且成为常识。但是,正是在将Docker、Fluentd和MongoDB整合到一个地方的过程中,才赋予了本文的意义。
请用中文提供以下内容的释义,只需要一种选项:
参考:
The above statement is asking for a paraphrase in Chinese.
以下是原文的中文同义句:
https://docs.mongodb.org/ecosystem/tools/administration-interfaces/
http://docs.fluentd.org/articles/out_mongo