Go中的结构化日志

2020-06-14 06:10:34

弹性堆栈(也称为ELK)可以为您的生产服务带来很多价值。但是,如果您的服务中不使用结构化日志,那么它就没有太大的价值。

在我最近的一篇帖子中,我写到了麋鹿是什么,以及为什么你应该关心它。我还写了一篇关于如何将elk与你的Go应用程序集成的教程。

在本文中,我将带您了解如何将结构化日志记录集成到Go服务中。我们将使用一个具有几个基本端点的示例HTTP服务,并将使用zap库发出错误/成功日志,其中还将包括一些特定于域的信息。

目前,repo有一个main.go文件,该文件具有三个不同端点的http处理程序:

处理程序本身并不执行任何特殊操作,它们只是在被调用时返回状态OK。

目前,它所做的是将标准http.ResponseWriter包装到statusWriter中,后者记录返回的http状态代码。

除了GO应用程序之外,在分支的根目录中还有一个GO-elk-Exercise-reqs.json文件。它是一组导出的请求,您可以将其导入您选择的REST客户端。

我用的,并推荐的,是失眠症。如果您想使用该文件,只需将该文件导入到您的失眠工作区,如下所示:

如果一切都成功了,您将获得所有必要的HTTP请求导入到您的工作区中,并且所有必要的数据(例如标头)都已经设置好了。

或者,如果导入不适用于您的REST客户端,下面是请求的内容,以便您可以手动添加它们:

在本教程中,我们将通过在成功(状态码小于400)或错误(状态码大于或等于400)时发出结构化日志来完成loggingMiddleware功能。

如果成功,我们将通过logger.Info写“入站请求成功”。

如果出现错误的状态码,我们会在默认的错误键中写入“入站请求失败,状态为[返回的状态码]”,默认的错误键中会写下“Inbound Request Failed with Status[Returned Status code]”。

以下是我们将在教程结束时发出的示例日志行:

在下一节中,我将一步一步地向您介绍如何实现这一点。

在本节中,我们将逐步介绍应用程序&&实现结构化日志记录。

值得注意的是,我们是如何将日志作为中间件插入的。

这使得编写域特定逻辑的开发人员不知道如何记录他们的HTTP调用的实现细节。

此外,它还允许我们在每个要检测的端点上重用日志中间件,而不是将代码复制粘贴到每个处理程序中。

最后,这个应用程序故意保持简单。在实际的应用程序中,您可能希望将此中间件作为FX模块包含在内,作为每个微服务的基准FX模块的一部分。

我们将从简单地对每个成功或失败的http调用发出日志消息开始。

在后面的步骤中,我们将使用这个数组用我们想要在日志中发出的特定键填充它。

接下来,在适当的位置使用logger.Info和logger.Error,并显示各自的成功/错误消息。还包括当前为空但将在下一步中填充的所有日志记录字段。

我们还将错误消息封装在zap.Error字段中。这将在单独的错误字段中传播错误消息,并且还将包括堆栈跟踪。

通过使用go run main.go运行应用程序并从REST客户机发送http请求来测试一切是否正常工作。

如果一切正常,下面是您应该在屏幕上看到的示例日志行:

让我们继续添加我们需要的其余密钥。

要将调用的端点和HTTP方法包括在结构化日志中,您必须从*http.Request对象中获取它们。

执行与上一节类似的测试,并看到您的日志现在包括端点和http方法:

这里,我们从http请求中提取头部,并将它们添加到日志中:

添加此内容后,我们应该可以在本练习开始时看到预期的日志:

现在,您应该已经很好地掌握了什么是结构化日志,以及如何在Go服务中使用它们。

如果你想了解更多关于如何利用它的信息,请查看我在这篇文章开头链接的其他一些文章。