【测试平台系列】第一章 手撸压力机(六)- 日志服务及使用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日志并进行多维度分析。
相关文章
|
1月前
|
存储 运维 监控
超越传统模型:从零开始构建高效的日志分析平台——基于Elasticsearch的实战指南
【10月更文挑战第8天】随着互联网应用和微服务架构的普及,系统产生的日志数据量日益增长。有效地收集、存储、检索和分析这些日志对于监控系统健康状态、快速定位问题以及优化性能至关重要。Elasticsearch 作为一种分布式的搜索和分析引擎,以其强大的全文检索能力和实时数据分析能力成为日志处理的理想选择。
100 6
|
1月前
|
Java Shell
「sh脚步模版自取」测试线排查的三个脚本:启动、停止、重启、日志保存
「sh脚步模版自取」测试线排查的三个脚本:启动、停止、重启、日志保存
36 1
|
2月前
|
存储 消息中间件 网络协议
日志平台-ELK实操系列(一)
日志平台-ELK实操系列(一)
|
1月前
|
Java 程序员 应用服务中间件
「测试线排查的一些经验-中篇」&& 调试日志实战
「测试线排查的一些经验-中篇」&& 调试日志实战
20 1
「测试线排查的一些经验-中篇」&& 调试日志实战
|
13天前
|
Web App开发 定位技术 iOS开发
Playwright 是一个强大的工具,用于在各种浏览器上测试应用,并模拟真实设备如手机和平板。通过配置 `playwright.devices`,可以轻松模拟不同设备的用户代理、屏幕尺寸、视口等特性。此外,Playwright 还支持模拟地理位置、区域设置、时区、权限(如通知)和配色方案,使测试更加全面和真实。例如,可以在配置文件中设置全局的区域设置和时区,然后在特定测试中进行覆盖。同时,还可以动态更改地理位置和媒体类型,以适应不同的测试需求。
Playwright 是一个强大的工具,用于在各种浏览器上测试应用,并模拟真实设备如手机和平板。通过配置 `playwright.devices`,可以轻松模拟不同设备的用户代理、屏幕尺寸、视口等特性。此外,Playwright 还支持模拟地理位置、区域设置、时区、权限(如通知)和配色方案,使测试更加全面和真实。例如,可以在配置文件中设置全局的区域设置和时区,然后在特定测试中进行覆盖。同时,还可以动态更改地理位置和媒体类型,以适应不同的测试需求。
17 1
|
1月前
|
存储 Prometheus NoSQL
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
22 3
|
1月前
|
存储 数据采集 分布式计算
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
42 1
|
2月前
|
关系型数据库 MySQL Go
go抽取mysql配置到yaml配置文件
go抽取mysql配置到yaml配置文件
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
44 2
|
2月前
|
Python
Python 解析 yaml 配置文件
Python 解析 yaml 配置文件
37 0