Elasticsearch:运用 Python 实时通过 Logstash 写入日志到 Elasticsearch

2,611 阅读4分钟

在我之前的文章,我详细地介绍了如何通过 Filebeat 来收集日志并写入到 Elasticsearch。你可以阅读我之前的文章:

在今天的文章中,我将分享如何使用 Logstash 把日志文件发送到 Elasticsearch。使用 Logstash 的好处是它可以很方便地使用它丰富的过滤器对数据进行清洗以便更好地对数据进行分析。我们使用如下的架构:

 在今天的展示中,我将使用最新的 Elastic Stack 8.4.3 来进行展示。

安装

如果你还没有安装好自己的 Elasticsearch,Kibana 及 Logstash,你可以按照如下的文章来进行安装:

首先,我们参考文章 “Logstash:如何连接到带有 HTTPS 访问的集群” 来生成 truststore.p12 证书文件:



1.  $ pwd
2.  /Users/liuxg/test/elasticsearch-8.4.3/config/certs
3.  $ ls 
4.  http.p12      http_ca.crt   transport.p12
5.  $ keytool -import -file http_ca.crt -keystore truststore.p12 -storepass password -noprompt -storetype pkcs12
6.  Certificate was added to keystore
7.  $ ls
8.  http.p12       http_ca.crt    transport.p12  truststore.p12


在上面,我们生产的 truststore.p12 的密码为 password。

我们针对 Logstash 配置如下的配置文件:

logstash.conf

`

1.  input {
2.    udp {
3.      port => 5959
4.      codec => json {
5.            target => "[document]"
6.      }
7.    }
8.  }
9.  output {
10.    stdout {
11.      codec => rubydebug
12.    }

14.    elasticsearch {
15.        index => "logdb"
16.        hosts => ["https://192.168.0.3:9200"]
17.        user => "elastic"
18.        password => "6bTlJp388KkgJKWi+hQr"
19.        ssl_certificate_verification => true
20.        truststore => "/Users/liuxg/test/elasticsearch-8.4.3/config/certs/truststore.p12"
21.        truststore_password => "password"
22.    }
23.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

在上面,我们需要根据自己的 Elasticsearch 账号及密码进行修改。另外你也需要根据自己的证书位置进行相应的调整。 上面的 hosts 是我的本地 Elasticsearch 集群的访问地址。你需要根据自己的进行配置。在上面,我们使用 udp input 来收集日志,并传入到 Elasticsearch。在本示例中,我们忽略了 filter 部分,以简化问题的描述。我们可以把这个 logstash.conf 置于 Logstash 的安装根目录中。

我们可以使用如下的命令来运行:

Python 日志应用

我们首先来安装一个叫做 python-logstash 的包:

 pip install python-logstash

我们设计如下的 Python 应用来通过 Logstash 写入日志:

app.py

`

1.  import logging
2.  import logstash
3.  import sys

6.  class Logging(object):
7.      def __init__(self, logger_name='python-logger',
8.                   log_stash_host='localhost',
9.                   log_stash_upd_port=5959

11.                   ):
12.          self.logger_name = logger_name
13.          self.log_stash_host = log_stash_host
14.          self.log_stash_upd_port = log_stash_upd_port

17.      def get(self):
18.          logging.basicConfig(
19.              file,
20.              filemode="a",
21.              format="%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s",
22.              datefmt="%H:%M:%S",
23.              level=logging.INFO,
24.          )

26.          self.stderrLogger = logging.StreamHandler()
27.          logging.getLogger().addHandler(self.stderrLogger)
28.          self.logger = logging.getLogger(self.logger_name)
29.          self.logger.addHandler(logstash.LogstashHandler(self.log_stash_host,
30.                                                          self.log_stash_upd_port,
31.                                                          version=1))
32.          return self.logger

36.  instance = Logging(log_stash_upd_port=5959, log_stash_host='localhost', logger_name='soumil')
37.  logger = instance.get()

39.  count = 0
40.  from time import sleep
41.  while True:

43.      count = count + 1

45.      if count % 2 == 0:
46.          logger.error('Error Message Code Faield :{} '.format(count))
47.      else:
48.          logger.info('python-logstash: test logstash info message:{} '.format(count))

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

我们在和 Logstash 运行的同一个机器上运行上面的应用。我们使用如下的方法来运行:

python app.py

我们在 Logstash 的 terminal 中可以看到:

它表明 Logstash 运作正常。

我们再到 Kibana 中打入如下的命令:

GET _cat/indices

从上面的输出中,我们可以看到新生成的 logdb 索引。

我们可以对这个索引进行搜索:

我们可以看到日志被正常地解析并可以被搜索。

采用异步方式写入日志

在很多的时候如果我们的日志是大量的,那么我们可以采取使用异步的方式来写如日志。这样的好处是应用不用等待数据完全写入后才继续向下执行。我们创建如下的 Logstash 的配置文件:

logstash_async.conf

`

1.  input {
2.      tcp {
3.          port => 6000
4.      }
5.  }

8.  output {
9.    stdout {
10.      codec => rubydebug
11.    }

13.    elasticsearch {
14.        index => "logstash_async"
15.        hosts => ["https://192.168.0.3:9200"]
16.        user => "elastic"
17.        password => "6bTlJp388KkgJKWi+hQr"
18.        ssl_certificate_verification => true
19.        truststore => "/Users/liuxg/test/elasticsearch-8.4.3/config/certs/truststore.p12"
20.        truststore_password => "password"
21.    }
22.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

我们把这个文件拷贝到 Logstash 的安装根目录下,并进行如下的运行:

 

我们接下来创建如下的 Python 应用:

python-logstash-logging.py

`1.  import logging
2.  import time
3.  from logstash_async.handler import AsynchronousLogstashHandler

5.  host = 'localhost'
6.  port = 6000

8.  test_logger = logging.getLogger('python-logging-test')
9.  test_logger.setLevel(logging.DEBUG)
10.  async_handler = AsynchronousLogstashHandler(host, port, database_path = None)
11.  test_logger.addHandler(async_handler)

13.  while True:
14.      test_logger.info("this is an info message at %s", time.time())
15.      time.sleep(0.5)` ![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

在上面,我们每隔 0.5 秒的时间写入一条日志到 TCP 端口 6000,进而通过 Logstash 写入到 Elasticsearch。我们可以通过如下的命令来运行这个 Python 应用:

python python-logstash-logging.py 

在 Logstash 运行的 terminal 中,我们可以看到如下的输出:

在 Kibana 中,我们可以查看索引 logstash_async: