使用graylog来收集你的Docker日志

Docker日志


Docker会默认收集应用程序的标准输出存储到一个json.log文件中,文件的格式类似下面这种:

{"log":"root@c835298de6dd:/# ls\r\n","stream":"stdout","time":"2014-03-14T22:15:15.155863426Z"}
{"log":"bin  boot  dev\u0009etc  home  lib\u0009lib64  media  mnt  opt\u0009proc  root  run  sbin  selinux\u0009srv  sys  tmp  usr  var\r\n","stream":"stdout","time":"2014-03-14T22:15:15.194869963Z"}

以一行一个作为一条JSON数据存储。Docker的这种日志存储方式是可以配置的,具体参数可以在执行run启动容器的时候通过log-driver进行配置,具体配置请参考log-driver。下面是官方的log-driver的配置可选项:

Supported logging drivers

The following logging drivers are supported. See each driver’s section below for its configurable options, if applicable.

Driver Description

none No logs will be available for the container and docker logs will not return any output.
json-file The logs are formatted as JSON. The default logging driver for Docker.
syslog Writes logging messages to the syslog facility. The syslog daemon must be running on the host >machine.
journald Writes log messages to journald. The journald daemon must be running on the host machine.
gelf Writes log messages to a Graylog Extended Log Format (GELF) endpoint such as Graylog or Logstash.
**fluentd ** Writes log messages to fluentd (forward input). The fluentd daemon must be running on the host machine.
awslogs Writes log messages to Amazon CloudWatch Logs.
splunk Writes log messages to splunk using the HTTP Event Collector.
etwlogs Writes log messages as Event Tracing for Windows (ETW) events. Only available on Windows platforms.
gcplogs Writes log messages to Google Cloud Platform (GCP) Logging.

Docker默认使用了json-file driver作为log driver,因此日志是存储在一个json.log的本地文件中的。而gelf则是本文需要使用的log driver。

当容器多了,或者是采用类似swarm集群部署Docker的时候,各种日志分散存在各个json.log文件中,当查找问题或者进行相关统计的时候,分散的日志对我们来说是非常不友好的。我们需要一个能够集中管理Docker日志的工具,这也是本文介绍的重点。

Graylog

相信大部分的人都用过或者听说过ELK这个强大的日志栈架构,我们要用的graylog和ELK非常的相似,但是算是后起之秀,具体对比请参考:

Graylog——日志聚合工具的后起之秀

为什么要选择graylog来作为Docker的日志收集平台呢?

  • Docker原生支持graylog协议,直接将日志发送到graylog(通过gelf协议

  • graylog官方提供了将本身部署在Docker的支持

部署

graylog官方提供了Dockerfile供我们快速的在Docker上部署日志系统,Dockerfile地址,在这个Docker Hub的地址中,也提供了docker-compose.yml来快速部署整个graylog栈,包含了mongodb、ElasticSearch,而不需要分别单独进行部署,我将完整的部署过程总结如下:

  1. 创建一个目录用来部署graylog,本文假设目录为/data/graylog,以下所有操作都是在/data/graylog中进行的。
  2. 初始化目录和配置文件
#创建数据目录
mkdir -p ./graylog/data
#创建配置文件目录
mkdir -p ./graylog/config
cd ./graylog/config
#直接下载官方推荐配置文件
wget https://raw.githubusercontent.com/Graylog2/graylog2-images/2.1/docker/config/graylog.conf
#日志配置文件
wget https://raw.githubusercontent.com/Graylog2/graylog2-images/2.1/docker/config/log4j2.xml

修改下载完的graylog.conf中的root_timezone为:

root_timezone = +08:00

改为GMT+0800中国时区。

  1. 新建docker-compose.yml来供docker-compose快速启动完整服务,文件内容如下:
version: '2'
services:
  some-mongo:
    image: "mongo:3"
    volumes:
      - /etc/localtime:/etc/localtime
      - /etc/timezone:/etc/timezone
      - ./graylog/data/mongo:/data/db
  some-elasticsearch:
    image: "elasticsearch:2"
    command: "elasticsearch -Des.cluster.name='graylog'"
    volumes:
      - /etc/localtime:/etc/localtime
      - /etc/timezone:/etc/timezone
      - ./graylog/data/elasticsearch:/usr/share/elasticsearch/data
  graylog:
    image: graylog2/server:2.1.1-1
    volumes:
      - /etc/localtime:/etc/localtime
      - /etc/timezone:/etc/timezone
      - ./graylog/data/journal:/usr/share/graylog/data/journal
      - ./graylog/config:/usr/share/graylog/data/config
    environment:
      GRAYLOG_PASSWORD_SECRET: somepasswordpepper
      GRAYLOG_ROOT_PASSWORD_SHA2: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      #这个地址需要配置成你要访问的地址,比如你的容器部署在192.168.1.2,你需要通过192.168.1.2来访问服务的话,你需要配置成http://192.168.1.2:9000/api,否则访问会报错
      GRAYLOG_WEB_ENDPOINT_URI: http://127.0.0.1:9000/api
    links:
      - some-mongo:mongo
      - some-elasticsearch:elasticsearch
    ports:
      #web界面端口
      - "9000:9000"
      #gelf收集日志的端口,如果需要添加graylog收集器,可以新增暴露出来的端口
      - "12201/udp:12201/udp"
      - "1514/udp:1514/udp"

文件保存后通过

docker-compoes up

启动整个服务,如果没有问题的话,会看到graylog webserver started的终端输出消息。
访问 http://{server}:9090/
会看到graylog的web界面,使用用户名admin,密码:admin 来登录后台,至此部署完成。

系统配置

  • input配置
    graylog的日志收集通过定义input对象来完成,在graylogweb管理界面按照如下图片进入input对象配置:
进入Input配置界面

选择GELF UDP协议来新建一个输入器(input)

选择正确的Input类型

填好相关属性,新建:

Input详细配置

至此graylog就可以开始收集日志了

  • Docker配置
    如果docker通过命令行启动,可以在run命令中加上如下参数:
docker run --log-driver=gelf --log-opt gelf-address=udp://{graylog服务器地址}:12201  --log-opt tag=<当前容器服务标签,用来供graylog查询的时候进行分类>  <IMAGE> <运行命令>

如果通过docker-compose命令,则可以在docker-compose.yml中加入相关配置,以下用tomcat容器举例:

version: '2'
services:
  tomcat:
    image: tomcat:7
    volumes:
         - /etc/localtime:/etc/localtime
         - /etc/timezone:/etc/timezone
         - /data/tomcat-adtp/logs:/usr/local/tomcat/logs
         - /data/tomcat-adtp/webroot:/usr/local/tomcat/webapps/ROOT
    environment:
         - JAVA_OPTS=-Xmx1g
         - JAVA_OPTS=-Xms3g
    ports:
        - "80:8080"
    logging:
      driver: "gelf"
      options:
        gelf-address: "udp://graylogserver:12201"
        tag: front-tomcat

容器启动的时候可能会有下面这个提示:

tomcat_1  | WARNING: no logs are available with the 'gelf' log driver

可以无视这个警告,日志还是会继续发送过去的。到这里为止我们可以在graylog的web后台中看到tomcat所产生日志了。

后续

虽然日志已经可以集中收集了,但是有些日志还是不会以我们理想的方式收集的,比如Java程序的异常堆栈、Hibernate的格式化sql等等,因为这种日志并不是一行一个的,而是多行一个整体,但是Docker不会知道这个,而是一行一个把日志发送到了graylog,导致一个完整的堆栈分散的存储到了graylog中,这样显然不是我们想要看到的结果,在这里我们可以使用一种比较折衷的方法,让Java程序自己将这种多行日志发送到graylog,剩下的日志继续由Docker处理,具体做法如下:
由于本人在目前系统中使用的logback,可以使用特定的appender把日志发送到graylog,我相信log4j或者是其他相关的日志框架也都有类似的配置。修改logback的配置文件,添加指定的log appender:

<appender name="gelf" class="me.moocar.logbackgelf.GelfUDPAppender">
        <remoteHost>192.168.31.8</remoteHost>
        <port>12201</port>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="me.moocar.logbackgelf.GelfLayout">
                <!--An example of overwriting the short message pattern-->
                <shortMessageLayout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%ex{short}%.100m</pattern>
                </shortMessageLayout>
                <!-- Use HTML output of the full message. Yes, any layout can be used (please don't actually do this)-->
                <fullMessageLayout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level \(%F:%L\) - %msg %n</pattern>
                </fullMessageLayout>
                <useLoggerName>true</useLoggerName>
                <useThreadName>true</useThreadName>
                <useMarker>true</useMarker>
                <includeFullMDC>true</includeFullMDC>
                <fieldType>requestId:long</fieldType>
                <!--Facility is not officially supported in GELF anymore, but you can use staticFields to do the same thing-->
                <staticField class="me.moocar.logbackgelf.Field">
                    <key>tag</key>
                    <value>business-server</value>
                </staticField>
            </layout>
        </encoder>
    </appender>
    <root>
        <level value="info"/>
        <appender-ref ref="gelf"/>
    </root>

这样logback会自动把日志发送到graylog,异常堆栈信息也不会分散了,这个功能需要一个第三方的logback扩展支持,github地址在这里

结束

至此,搭建一个graylog并且收集Docker日志集中管理的方案就完成了,希望能够帮到看这篇文章的你。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270

推荐阅读更多精彩内容