ELK + Logspout 收集容器中日志

ELK + Logspout 收集容器中日志

通过 docker-compose 部署 ELK 服务加 logspout 收集存储服务器上 docker 容器日志

起因

在部署 hyperledger-fabric 区块链时,发现部署完成后日志全是在相应容器的 stdout 中,暂时没找到 fabric 中有地方可以配置日志写入到文件,无奈只能寻找收集容器日志的方法。

回忆起在 fabric 的示例 demo fabric-samples 中有看到有脚本写过使用 logspout 收集日志。此工具可以实时收集服务器上全部容器的日志,挺符合要求的。就是可惜的是不能存储到文件,又不想写入到 syslog,那么就只能写入到 ELK 中了。

ELK

使用 docker-compose 编排启动 ELK

启动之前先按照 ES 官方文档 修改宿主机内核运行参数

shell
1
2
grep vm.max_map_count /etc/sysctl.conf || echo >> vm.max_map_count=262144 /etc/sysctl.conf
sysctl -p
  1. 编辑 compose-elk.yml 文件,内容如下:

    compose-elk.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    version: "3"

    networks:
    elk:
    driver: bridge

    volumes:
    es_data:
    driver: local

    services:
    elasticsearch:
    image: elasticsearch:6.8.3
    container_name: elasticsearch
    restart: always
    environment:
    - TZ=Asia/Shanghai
    - LOGSPOUT=ignore
    - cluster.name=elk-cluster
    # - bootstrap.memory_lock=true
    - "ES_JAVA_OPTS=-Xms2048m -Xmx2048m"
    networks:
    - elk
    expose:
    - 9200
    - 9300
    # ports:
    # - "9200:9200"
    # - "9300:9300"
    volumes:
    - es_data:/usr/share/elasticsearch/data

    logstash:
    image: logstash:6.8.3
    container_name: logstash
    restart: always
    command: logstash -f /etc/logstash/conf.d/logstash.conf
    environment:
    - TZ=Asia/Shanghai
    - LOGSPOUT=ignore
    networks:
    - elk
    ports:
    - "5001:5000"
    volumes:
    - $PWD/logstash.conf:/etc/logstash/conf.d/logstash.conf
    depends_on:
    - elasticsearch

    kibana:
    image: kibana:6.8.3
    container_name: kibana
    restart: always
    environment:
    - TZ=Asia/Shanghai
    - LOGSPOUT=ignore
    - ELASTICSEARCH_URL=http://elasticsearch:9200
    networks:
    - elk
    ports:
    - "5601:5601"
    depends_on:
    - elasticsearch
  2. 添加 logstash 配置文件

    logstash.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    input {
    tcp {
    port => 5000
    type => syslog
    codec => json
    }
    udp {
    port => 5000
    type => syslog
    }
    }

    filter {
    grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
    }
    }

    output {
    elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "blockchian-%{+YYYY.MM.dd}"
    }
    stdout { codec => rubydebug }
    }
  3. 启动 ELK

    shell
    1
    docker-compose -p elk -f compose-elk.yml up -d

    使用命令:docker-compose -p elk -f compose-elk.yml logs -f --tail 50 查看日志,等待启动完毕

logspout

同样的,使用 docker-compose 编排启动 logspout

在需要被收集日志的容器所在服务器上添加 logspout 的编排文件 compose-logspout.yml,内容如下:

compose-logspout.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3"

networks:
logging:
driver: bridge

services:
logspout:
image: gliderlabs/logspout:latest
container_name: logspout
restart: always
environment:
- TZ=Asia/Shanghai
- LOGSPOUT=ignore
networks:
- logging
volumes:
- /etc/hostname:/etc/host_hostname:ro
- /var/run/docker.sock:/var/run/docker.sock
command:
# logstash的宿主机ip
syslog+tcp://172.16.123.160:5001

保存后,启动 logspout 容器

shell
1
docker-compose -p logging -f compose-logspout.yml up -d

日志收集规则

logspout 默认收集所在主机上的所有 docker 容器日志。但有时我们只希望收集部分容器的日志,根据官方文档,我们可以在其他的容器中设置环境变量 LOGSPOUT=ignore 忽略

官方示例:

shell
1
docker run -d -e 'LOGSPOUT=ignore' image

或者使用 filter 过滤,仅收集满足指定条件的容器日志

shell >folded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 指定容器名
docker run \
--volume=/var/run/docker.sock:/var/run/docker.sock \
gliderlabs/logspout \
raw://192.168.10.10:5000?filter.name=*_db
# 指定容器 ID
docker run \
--volume=/var/run/docker.sock:/var/run/docker.sock \
gliderlabs/logspout \
raw://192.168.10.10:5000?filter.id=3b6ba57db54a
# 指定文件
docker run \
--volume=/var/run/docker.sock:/var/run/docker.sock \
gliderlabs/logspout \
raw://192.168.10.10:5000?filter.sources=stdout%2Cstderr
# 指定容器标签
docker run \
--volume=/var/run/docker.sock:/var/run/docker.sock \
gliderlabs/logspout \
raw://192.168.10.10:5000?filter.labels=a:x*%2Cb:*y

例如:

compose-logspout.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3"

networks:
logging:
driver: bridge

services:
logspout:
image: gliderlabs/logspout:latest
container_name: logspout
restart: always
environment:
- TZ=Asia/Shanghai
- LOGSPOUT=ignore
networks:
- logging
volumes:
- /etc/hostname:/etc/host_hostname:ro
- /var/run/docker.sock:/var/run/docker.sock
command:
# logstash的宿主机ip,且仅收集已 peer_ 开头的容器
syslog+tcp://172.16.123.160:5001?filter.name=peer_*

需要收集日志的容器,在启动时需要设置容器名前缀为 peer_,即可监控该容器的日志

日志查看

通过部署 ELK 的服务器 IP+5601 端口访问 kibana 页面

http://server-ip:5601

首次登陆需要手动创建索引

  1. 通过 Management => Elasticsearch => Index Management 中可以看到,当前 Elasticsearch 中没有可用索引。需要我们先通过启动待收集日志的容器后,通过 logstash 同步日志到 Elasticsearch 才能使用。

通过 logstash 创建的索引

  1. kibana 中创建索引,如下图所示

  1. 选择 Time Filter field name@timestamp,然后创建索引

  1. 索引建立完成后,通过 Discover 即可查看日志

参考文章:

评论

:D 一言句子获取中...

加载中,最新评论有1分钟缓存...