Go微服务 - 第十部分 - 集中化日志

第十部分: Go微服务 - 集中化日志

本文介绍咱们的Go微服务基于Logrus、Docker Gelf日志驱动以及Loggly服务(Logging as a Service)的日志策略。html

  • Logrus: Go语言中的结构化、可插拔日志功能。
  • Docker Gelf日志驱动器: 是一种方便的格式,能够被不少工具理解,例如Graylog, Logstash, Fluentd等等。
  • Loggly: 这是一个日志数据管理的SaaS解决方案。使用它能够将日志从整个基础设施的深处带到一个能够跟踪活动和分析趋势的地方。最重要的是,Loggly是一种托管服务,你不须要任何额外的硬件或软件就可使用Loggly,而且能够动态根据操做进行扩展。

简介

日志。你根本不知道你会失去多少, 直到你这样作。为你的团队制定关于记录什么,何时记录以及如何记录,多是产生可维护应用程序的关键因素之一。而后,微服务就发生了。linux

虽然对于单体应用来讲处理一些日志文件一般都是可管理的(虽然存在例外...), 但考虑到对于基于微服务的应用程序来讲,一样可能使用数百个甚至数千个服务容器来产生日志。若是没有一个搜集和汇总日志的解决方案,基本上考虑不了变得更大的时候的问题了。git

谢天谢地,不少聪明人已经想到这一点 - 叫作ELK的著名栈可能就是开源社区中最著名的一个。它是ElasticSearch, LogStash和Kibana构成的Elastic Stack(ELK), 推荐能够在驻机和云主机上使用。然而ELK的文章遍地都是,因此本文咱们基于四个部分来探索集中日志记录解决方案LaaS:github

  • Logrus: Go语言的日志框架。
  • Docker Gelf驱动器: Greylog Extended Log格式的日志驱动器。
  • Gelftail: 本文中将要构建的轻量级日志聚合器。
  • Loggly: 一个LaaS提供商。 提供相似的管理和做用日志数据做为相似服务的能力。

解决方案概览

clipboard.png

源代码

https://github.com/walkerqiao...golang

一般咱们的Go微服务直到如今都是使用的fmt或log包打的日志,通常都输出到stdout或stderr。咱们但愿能更好的控制日志级别和格式。在Java世界,咱们不少(大部分)都使用log4j、logback、slf4j之类的框架来处理日志。本文咱们选择使用Logrus做为日志API, 它大致上提供了我刚提到的关于日志级别、格式化仍是钩子API一样类型的功能。docker

使用logrus

使用logrus很好的特性就是它实现了目前咱们用于日志的fmt, log相同的接口。这就意味着咱们或多或少的可使用logrus做为无需太多改变的替换。首先确保你的GOPATH设置正确,而后使用下面的命令获取logrus:json

go get github.com/sirupsen/logrus

更新代码

咱们使用老派方式来操做。对于common, accountservice, vipservice分别使用IDE或文本编辑器作全局搜索替换。 fmt.和log.替换为logrus.。那么如今就会出现不少logrus.Println和logrus.Pringf调用。 即使经过这样的方式不错,可是我仍是建议使用logrus更通常化的严格支持,例如INFO, WARN, DEBUG之类的。例如:框架

fmt                                 log                             logrus
Println                             Println                         Infoln
printf                              Printf                          Infof
Error                                                               Errorln

有一个例外,fmt.Error用于产生错误实例。不要替换fmt.Error。elasticsearch

使用goimports更新imports

鉴于咱们已经使用logrus替换了大量的log.Println和fmt.Println(和其余日志函数),咱们就有大量无用的import,这样会产生编译错误。与其一个文件一个文件的修改,不如咱们使用一个小工具来帮咱们作到这些。 这个工具就是goimports, 能够经过下面的方式安装:编辑器

go get golang.org/x/tools/cmd/goimports

安装完后,这个命令工具在$GOPATH/bin目录。 接下来能够进入accountservice, vipservice, 执行下面的命令:

cd $GOPATH/src/github.com/callistaenterprise/goblog/accountservice
$GOPATH/bin/goimports -w **/*.go

执行goimports会自动为全部的文件添加未import的语句,同时会去掉无用的import语句。

而后能够对咱们全部的微服务代码进行这样的操做,包括common目录。

而后运行go build确保每一个服务都能正常编译。

配置logrus

若是咱们不配置logrus, 它将直接以纯文本的形式输出日志内容。例如:

logrus.Infof("Starting our service...")

// 输出内容
INFO[0000] Starting our service...

这里0000是服务启动的时间。不是咱们所想要的,我想要一个datetime类型的。 所以咱们须要提供一个格式。

func init() {
    logrus.SetFormatter(&logrus.TextFormatter{
        TimestampFormat: "2006-01-02T15:04:05.000",
        FullTimestamp: true,
    })
}

init函数最适合干这种事情了。设置以后,咱们的日志输出就以下所示:

INFO[2017-07-17T13:22:49.164] Starting our service...

要比刚才好些。 然而,在咱们微服务用例中,咱们但愿日志日志语句更容易解析,这样咱们能够将它们发送到咱们的选择的LaaS上, 让日志索引、排序、聚合等等。所以当咱们不在单例模式(-profile=dev)下运行微服务时,咱们将但愿使用JSON格式。

咱们再次修改init函数, 这样它将使用json格式替代除非有-profile=dev标志传入。

func init() {
    profile := flag.String("profile", "test", "Environment profile")
    if *profile == "dev" {
        logrus.SetFormatter(&logrus.TextFormatter{
            TimestampFormat: "2006-01-02T15:04:05.000",
            FullTimestamp: true,
        })
    } else {
        logrus.SetFormatter(&logrus.JSONFormatter{})
    }
}

输出内容以下:

{"level":"info","msg":"Starting our service...","time":"2017-07-17T16:03:35+02:00"}

就是这样,你能够阅读logrus的文档得到更全面的例子。

应该清楚的是,标准的logrus日志不支持来你在其余平台使用的细粒度的控制,例如经过配置修改某些给定包以调试模式进行日志。然而,能够建立范围话的日志实例,使得更细粒度的配置成为可能,例如:

var LOGGER = logrus.Logger{}   // <-- Create logger instance

func init() {
    // Some other init code...
    
    // Example 1 - using global logrus API
    logrus.Infof("Successfully initialized")
    
    // Example 2 - using logger instance
    LOGGER.Infof("Successfully initialized")
}

这里只是示例代码,仓库中是不存在的。

经过使用LOGGER实例,就能够配置更细粒度的应用级别的日志。然而,我已经选择使用全局日志,使用logrus.X做为本文中代码使用的日志记录。

2. Docker Gelf驱动器

Gelf是什么? 它是Greylog Extended Log Format的首字母缩写,是logstash的标准格式。
基本上来讲,他的日志数据以JSON格式的数据。在Docker上下文,咱们能够配置Docker Swarm模式服务使用各类不一样驱动器来进行日志, 实际上意味着在某个容器中写到stdout, stderr的东西会被Docker引擎捡起,交给日志驱动器来处理。 这些处理包括添加大量容器、Swarm节点、服务等相关的元数据。这些都是针对docker的。大概样子以下:

{
    "version":"1.1",
    "host":"swarm-manager-0",
    "short_message":"Starting HTTP service at 6868",
    "timestamp":1.487625824614e+09,
    "level":6,
    "_command":"./vipservice-linux-amd64 -profile=test",
    "_container_id":"894edfe2faed131d417eebf77306a0386b43027e0bdf75269e7f9dcca0ac5608",
    "_container_name":"vipservice.1.jgaludcy21iriskcu1fx9nx2p",
    "_created":"2017-02-20T21:23:38.877748337Z",
    "_image_id":"sha256:1df84e91e0931ec14c6fb4e559b5aca5afff7abd63f0dc8445a4e1dc9e31cfe1",
    "_image_name":"someprefix/vipservice:latest",
    "_tag":"894edfe2faed"
}

让咱们看看如何修改copyall.sh脚本中的docker service create让它支持Gelf驱动的:

docker service create \
--log-driver=gelf \
--log-opt gelf-address=udp://192.168.99.100:12202 \
--log-opt gelf-compression-type=none \
--name=accountservice --replicas=1 --network=my_network -p=6767:6767 someprefix/accountservice
  • --log-driver=gelf: 告诉Docker使用gelf驱动器。
  • --log-opt gelf-address=udp://192.168.99.100:12202: 告诉Docker朝哪里发送全部日志语句。在gelf的状况中,咱们使用UDP协议,并告诉Docker将日志语句发送定义的IP:port的服务。这个服务通常就是相似logstash的东西,可是咱们这个例子中,咱们使用了下一节构建的轻量日志聚合服务。
  • --log-op gelf-compression-type: 告诉Docker在发送日志语句以前是否须要压缩。 为了简单起见,本文不对日志语句进行压缩。

3. 日志集合和使用Gelftail进行日志聚合

4. Loggly

总结

本文咱们看了集中化日志方面的东西 - 为何它很重要,如何对Go微服务进行格式化日志,如何使用容器编排里边的日志驱动器在日志状态上传到LaaS提供商以前对日志进行预处理。

下一节,是时候使用Netflix Hystrix为咱们微服务添加断路器和弹性(resilience)。

中英文对照

  • 日志即服务: Logging as a Service(LaaS).
  • ELK: Electic Search、LogStash、Kibana三个首字母组合。一般三个配合使用,构成ELK协议栈。

参考连接

  • Logrus: Go语言中的结构化、可插拔日志功能。
  • Elastic Stack: 集中化、转换和储存你的数据。是一个开源的、服务端数据处理流水线,它同时从多个源中采集数据,转换它,而后将它发送到你最喜欢的Stash中(对于咱们来讲天然是Elastic Search)。
  • Kibana: Kibana可让你可视化你的Elastic Search(弹性搜索)数据,并浏览Elastic Stack,这样你就能够了解为何在凌晨两点的时候被分页来理解雨季对你季度数字的影响。
  • ElasticSearch: Elastic Stack的核心。具备解决不断壮大用例的分布式、RESTful搜索和分析引擎能力。做为Elastic Stack的核心,它集中化存储数据,所以你能够发现预期和发现意外状况。
  • Docker Gelf日志驱动器: 是一种方便的格式,能够被不少工具理解,例如Graylog, Logstash, Fluentd等等。
  • Loggly: 这是一个日志数据管理的SaaS解决方案。使用它能够将日志从整个基础设施的深处带到一个能够跟踪活动和分析趋势的地方。最重要的是,Loggly是一种托管服务,你不须要任何额外的硬件或软件就可使用Loggly,而且能够动态根据操做进行扩展。
  • 英文第10部分
  • 系列文章首页
  • 下一节
相关文章
相关标签/搜索