【测试平台系列】第一章 手撸压力机(六)- 日志服务及使用yaml配置文件

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 上一章节我们封装TO(测试对象),方便我们以后扩展其他被测的接口或协议。本章我们主要实现以下,我们的日志输出。

上一章节我们封装TO(测试对象),方便我们以后扩展其他被测的接口或协议。本章我们主要实现以下,我们的日志输出。在以前的章节中,我们都是使用go的fmt包进行日志输出(打印到控制台),在工作中我们都知道,我们的服务都是由日志文件,以及日志级别的。下面我们就实现以下,将指定的级别的日志,输出到日志文件中。
我们在项目中新建global目录并在global目录下新建log目录,结构如下:
kitchen-engine/global/log/logger.go

package log

import (
        "github.com/natefinch/lumberjack"
        "go.uber.org/zap"
        "go.uber.org/zap/zapcore"
        "os"
)

// 声明一个zap包的SugaredLogger指针
var Logger *zap.SugaredLogger

var Logger *zap.SugaredLogger

// 获取一个异步io.Write
func getWriteSyncer(path string, maxSize, maxBackups, maxAge int, compress bool) zapcore.WriteSyncer {
        lumberJackLogger := &lumberjack.Logger{}
        // 日志文件的位置
        if path == "" {
                path = "./runner"
        }
        lumberJackLogger.Filename = path

        // 在进行切割之前,日志文件的最大大小,MB
        if maxSize != 0 {
                lumberJackLogger.MaxSize = maxSize
        }

        // 保留旧文件的最大个数
        if maxBackups != 0 {
                lumberJackLogger.MaxBackups = maxBackups
        }

        // 旧文件保留的时间天数
        if maxAge != 0 {
                lumberJackLogger.MaxAge = maxAge
        }

        // 是否压缩/归档旧文件
        if compress {
                lumberJackLogger.Compress = true
        }

        return zapcore.AddSync(lumberJackLogger)
}

// InitLogger 初始化日志模块
func InitLogger() {

        // 设置日志的基本格式,使用开发模式
        encoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())

    // 大于等于warn的日志级别
        errLogger := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
                return level >= zapcore.WarnLevel
        })

    // 小于等于warn的日志级别
        infoLogger := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
                return level <= zapcore.WarnLevel
        })

        // 配置输出到控制台
        consoleSyncer := zapcore.AddSync(os.Stdout)
        // 详细日志输出到info日志文件
        info := getWriteSyncer("./runner-go-info.log", 100, 5, 10, false)
        // 错误日志输出到错误日志文件
        errSync := getWriteSyncer("./runner-go-err.log", 100, 5, 10, false)
        core := zapcore.NewTee(
                zapcore.NewCore(encoder, info, infoLogger),
                zapcore.NewCore(encoder, consoleSyncer, zap.DebugLevel),
                zapcore.NewCore(encoder, errSync, errLogger))

        Logger = zap.New(core, zap.AddCaller()).Sugar()
}

这样,我们就把日志的模块,配置完了。
我们可以使用单元测试,自测以下。在go中使用单元测试,我们直接新建一个
kitchen-engine/global/log/logger_test.go

package log

import (
        "testing"
)

// 使用go单元测试,直接Test+方法名
func TestInitLogger(t *testing.T) {
        // 初始化日志配置
        InitLogger()
        // 打印debug级别的日志
        Logger.Debug("你好我好,大家好")
        // 打印错误级别的日志
        Logger.Error("错误哦错误")
}

然后,我们直接运行该方法即可,不用在main函数中去使用。这样,我们在控制台,可以看到如下日志:

=== RUN   TestInitLogger
2023-06-15T14:05:49.896+0800        DEBUG        log/logger_test.go:15        你好  我好,大家好
2023-06-15T14:05:49.910+0800        ERROR        log/logger_test.go:16        错误  哦错误
--- PASS: TestInitLogger (0.02s)
PASS
Process finished with the exit code 0

同时在我们的log文件夹下,分别多了runner-go-info.log和runner-go-err.log
​编辑
刚才我们使用单元测试对日志模块进行了自测,可以正常使用。
下面我们为了,更灵活的配置日志,我们采用配置文件的方式来进行配置。
在global目录下新建global/config/config.go


package config

import (
        "flag"
        "fmt"
)
import "github.com/spf13/viper"

var YC YamlConfig

type YamlConfig struct {
        Log Log yaml:"log"
}

type Log struct {
        Env          string yaml:"env"            // 环境
        InfoLogPath  string yaml:"info_log_path"  // 详细日志的文件地址
        ErrLogPath   string yaml:"err_log_path"   // 错误日志的文件地址
        IsConsoleLog bool   yaml:"is_console_log" // 是否将日志输出到控制台
}

// InitConfig 初始化YamlConfig结构体,将配置文件读取到内存中
func InitConfig() {

        var file string
        // go语言命令行工具
        flag.StringVar(&file, "f", "../../open.yaml", "配置文件,默认为根目录下的open.yaml")
        if !flag.Parsed() {
                flag.Parse()
        }

        viper.SetConfigFile(file)
        // 读取的配置文件为yaml文件类型
        viper.SetConfigType("yaml")

        if err := viper.ReadInConfig(); err != nil {
                panic(fmt.Sprintf("读取配置文件: %s 失败!", file))
        }

        if err := viper.Unmarshal(&YC); err != nil {
                panic(fmt.Sprintf("配置文件: %s, 匹配: %v类型失败!", file, YC))
        }
        fmt.Println(fmt.Sprintf("配置文件:%s初始化成功", file))
}

在项目的根目录,我们新建open.yaml(配置文件)。

log:
  env: "test"            # 环境
  Info_log_path: "./runner-go-info.log"  # 详细日志的文件地址
  err_log_path: "./runner-go-err.log"   # 错误日志的文件地址
  is_console_log: true # 是否将日志输出到控制台

我们去main.go中对配置文件和日志配置,进行测试。
main.go

package main

import (
        "kitchen-engine/global/config"
        "kitchen-engine/global/log"
)

// 初始化函数,在main函数之前运行
func init() {
        // 初始化配置信息
        config.InitConfig()
        // 初始化日志配置
        log.InitLogger()
}

func main() {

        log.Logger.Debug("yc:   ", config.YC)
        //// 一个类型中的字段,可以重置,也可以使用默认值,在go中,所有的类型的初始值,都是字段类型的0值,比如string的初始值是""空字符串,int类型的初始值是0等等
        //httpClientSettings := model.HttpClientSettings{
        //        Name:                     "测试厨房",
        //        NoDefaultUserAgentHeader: true,
        //        MaxConnDuration:          1000,
        //        AdvancedOptions: model.AdvancedOptions{
        //                Tls: model.Tls{
        //                        IsVerify:   true,
        //                        VerifyType: 1,
        //                },
        //        },
        //}
        //
        //headers := []model.Header{
        //        model.Header{
        //                Field: "name",
        //                Value: "你好",
        //        },
        //}
        //
        //httpRequest := model.HttpRequest{
        //        Url:                "https://www.baidu.com",
        //        Method:             "GET",
        //        HttpClientSettings: httpClientSettings,
        //        Headers:            headers,
        //}
        //
        //client.RequestHttp(httpRequest)
        log.Logger.Info("欢迎使用zap日志")
}

这样,我们就可以修改我们的日志初始化的配置。
logger.go

// InitLogger 初始化日志模块
func InitLogger(yc config.YamlConfig) {

   // 设置日志的基本格式,使用开发模式
   encoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())

   // 大于等于warn的日志级别
   errLogger := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
      return level >= zapcore.WarnLevel
   })

   // 小于等于warn的日志级别
   infoLogger := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
      return level <= zapcore.WarnLevel
   })

   // 配置输出到控制台
   consoleSyncer := zapcore.AddSync(os.Stdout)
   // 详细日志输出到info日志文件
   info := getWriteSyncer(yc.Log.InfoLogPath, 100, 5, 10, false)
   // 错误日志输出到错误日志文件
   errSync := getWriteSyncer(yc.Log.ErrLogPath, 100, 5, 10, false)
   core := zapcore.NewTee(
      zapcore.NewCore(encoder, info, infoLogger),
      zapcore.NewCore(encoder, consoleSyncer, zap.DebugLevel),
      zapcore.NewCore(encoder, errSync, errLogger))

   Logger = zap.New(core, zap.AddCaller()).Sugar()
}

main.go


package main

import (
   "kitchen-engine/global/config"
   "kitchen-engine/global/log"
)

// 初始化函数,在main函数之前运行
func init() {
   // 初始化配置信息
   config.InitConfig()
   // 初始化日志配置
   log.InitLogger(config.YC)
}

今天的内容就到这里,其他配置项如果也想修改的,可以自行配置及变更。这样可以更方便、更灵活的使用。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
存储 运维 监控
超越传统模型:从零开始构建高效的日志分析平台——基于Elasticsearch的实战指南
【10月更文挑战第8天】随着互联网应用和微服务架构的普及,系统产生的日志数据量日益增长。有效地收集、存储、检索和分析这些日志对于监控系统健康状态、快速定位问题以及优化性能至关重要。Elasticsearch 作为一种分布式的搜索和分析引擎,以其强大的全文检索能力和实时数据分析能力成为日志处理的理想选择。
159 6
|
2月前
|
Java Shell
「sh脚步模版自取」测试线排查的三个脚本:启动、停止、重启、日志保存
「sh脚步模版自取」测试线排查的三个脚本:启动、停止、重启、日志保存
43 1
|
29天前
|
人工智能 供应链 安全
AI辅助安全测试案例某电商-供应链平台平台安全漏洞
【11月更文挑战第13天】该案例介绍了一家电商供应链平台如何利用AI技术进行全面的安全测试,包括网络、应用和数据安全层面,发现了多个潜在漏洞,并采取了有效的修复措施,提升了平台的整体安全性。
|
1月前
|
监控 安全 测试技术
构建高效的精准测试平台:设计与实现指南
在软件开发过程中,精准测试是确保产品质量和性能的关键环节。一个精准的测试平台能够自动化测试流程,提高测试效率,缩短测试周期,并提供准确的测试结果。本文将分享如何设计和实现一个精准测试平台,从需求分析到技术选型,再到具体的实现步骤。
132 1
|
2月前
|
Java 程序员 应用服务中间件
「测试线排查的一些经验-中篇」&& 调试日志实战
「测试线排查的一些经验-中篇」&& 调试日志实战
26 1
「测试线排查的一些经验-中篇」&& 调试日志实战
|
1月前
|
Web App开发 定位技术 iOS开发
Playwright 是一个强大的工具,用于在各种浏览器上测试应用,并模拟真实设备如手机和平板。通过配置 `playwright.devices`,可以轻松模拟不同设备的用户代理、屏幕尺寸、视口等特性。此外,Playwright 还支持模拟地理位置、区域设置、时区、权限(如通知)和配色方案,使测试更加全面和真实。例如,可以在配置文件中设置全局的区域设置和时区,然后在特定测试中进行覆盖。同时,还可以动态更改地理位置和媒体类型,以适应不同的测试需求。
Playwright 是一个强大的工具,用于在各种浏览器上测试应用,并模拟真实设备如手机和平板。通过配置 `playwright.devices`,可以轻松模拟不同设备的用户代理、屏幕尺寸、视口等特性。此外,Playwright 还支持模拟地理位置、区域设置、时区、权限(如通知)和配色方案,使测试更加全面和真实。例如,可以在配置文件中设置全局的区域设置和时区,然后在特定测试中进行覆盖。同时,还可以动态更改地理位置和媒体类型,以适应不同的测试需求。
64 1
|
2月前
|
人工智能 监控 测试技术
云应用开发平台测试
云应用开发平台测试
77 2
|
1月前
|
监控 安全 测试技术
构建高效精准测试平台:设计与实现全攻略
在软件开发过程中,精准测试是确保产品质量的关键环节。一个高效、精准的测试平台能够自动化测试流程,提高测试覆盖率,缩短测试周期。本文将分享如何设计和实现一个精准测试平台,从需求分析到技术选型,再到具体的实现步骤。
63 0
|
2月前
|
存储 Prometheus NoSQL
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
33 3
|
2月前
|
存储 数据采集 分布式计算
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
56 1