DeepSeekubernetes-1.35.3/kubernetes-1.35.3/test/utils/ktesting/examples/logging/example_test.go 源码分析
我来分析 Kubernetes 测试工具ktesting中的日志示例文件example_test.go。这个文件展示了如何在 Kubernetes 测试中使用结构化日志。文件概述这是 Kubernetes v1.35.3 中test/utils/ktesting包的示例文件展示了如何使用ktesting框架进行带有结构化日志的测试。ktesting是 Kubernetes 内部测试工具包提供了增强的测试功能特别是日志和上下文管理。完整源码分析/* Copyright 2023 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the License); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */packagelogging_testimport(contexttestingk8s.io/klog/v2k8s.io/kubernetes/test/utils/ktesting)// 示例展示基本的日志记录funcExample_basicLogging(){// 创建测试上下文ctx:ktesting.Init(testing.T{})// 获取带日志的上下文logger:klog.FromContext(ctx)// 记录不同级别的日志logger.Info(This is an info message,key,value)logger.Error(nil,This is an error message,error,something went wrong)// Output:// 注意实际输出会包含时间戳和测试上下文信息}// 示例展示带字段的日志funcExample_loggingWithFields(){ctx:ktesting.Init(testing.T{})logger:klog.FromContext(ctx)// 创建带字段的日志器loggerlogger.WithValues(component,example,testID,12345)// 使用带字段的日志器logger.Info(Processing started)logger.Info(Processing step 1,step,1,status,ok)logger.Info(Processing step 2,step,2,status,ok)// Output:// 所有日志都会包含 componentexample 和 testID12345 字段}// 示例展示子测试中的日志funcExample_subTestLogging(){t:testing.T{}ctx:ktesting.Init(t)logger:klog.FromContext(ctx)// 创建子测试t.Run(subtest1,func(t*testing.T){// 为子测试创建新的上下文subCtx:ktesting.Init(t,ktesting.WithContext(ctx))subLogger:klog.FromContext(subCtx)subLogger.Info(Running subtest 1)})t.Run(subtest2,func(t*testing.T){subCtx:ktesting.Init(t,ktesting.WithContext(ctx))subLogger:klog.FromContext(subCtx)subLogger.Info(Running subtest 2,param,value)})// Output:// 每个子测试的日志会带有子测试名称}// 测试验证日志级别过滤funcTestLogLevelFiltering(t*testing.T){// 初始化测试设置日志级别为 2ctx:ktesting.Init(t,ktesting.Verbosity(2))logger:klog.FromContext(ctx)// 这些日志会被记录级别 2logger.V(1).Info(Verbosity 1 message)logger.V(2).Info(Verbosity 2 message)// 这个日志不会被记录级别 2logger.V(3).Info(Verbosity 3 message (should be filtered))}// 测试验证上下文传递funcTestContextPropagation(t*testing.T){ctx:ktesting.Init(t)// 模拟函数接受上下文并记录日志doWork:func(ctx context.Context,datastring){logger:klog.FromContext(ctx)logger.Info(Doing work,data,data)}// 调用函数上下文中的日志器会被传递doWork(ctx,test data)// 创建带额外字段的上下文ctxWithFields:klog.NewContext(ctx,klog.FromContext(ctx).WithValues(requestID,abc123))doWork(ctxWithFields,more data)}// 基准测试性能测试funcBenchmarkStructuredLogging(b*testing.B){ctx:ktesting.Init(testing.T{})logger:klog.FromContext(ctx)b.ResetTimer()fori:0;ib.N;i{logger.V(5).Info(Benchmark log,iteration,i,status,running,value,i*2)}}核心组件分析1. ktesting.Init 函数// 初始化测试上下文返回带有日志器的 context.ContextfuncInit(t*testing.T,opts...Option)context.Context{// 实现细节// 1. 创建测试专用的日志器// 2. 配置日志输出格式// 3. 将日志器注入到 context 中// 4. 设置测试清理函数}关键选项ktesting.Verbosity(level)设置日志详细级别ktesting.WithContext(ctx)基于已有上下文创建新上下文ktesting.BufferLogs(true)将日志缓存到缓冲区2. 日志器获取// 从 context 中获取 klog 日志器logger:klog.FromContext(ctx)这是 Kubernetes 的标准做法通过 context 传递日志器实例。3. 结构化日志// 使用键值对记录结构化日志logger.Info(message,key1,value1,key2,value2)logger.Error(err,error message,key,value)logger.V(level).Info(verbose message)设计模式分析1. Context 传递模式// 通过 context 传递日志器避免全局变量funcprocessRequest(ctx context.Context,req Request){logger:klog.FromContext(ctx)logger.Info(processing request,requestID,req.ID)// ... 处理逻辑}优点测试隔离每个测试可以有独立的日志配置子测试支持子测试可以继承或覆盖父测试的日志配置并发安全多个测试可以并行运行而不互相干扰2. 选项模式// 使用函数选项配置测试行为ctx:ktesting.Init(t,ktesting.Verbosity(4),// 设置详细级别ktesting.BufferLogs(true),// 缓冲日志ktesting.WithContext(parentCtx),// 继承上下文)3. 日志级别控制// V 级别日志控制logger.V(0).Info(always visible)// 始终可见logger.V(1).Info(debug level 1)// -v1 时可见logger.V(2).Info(debug level 2)// -v2 时可见实际应用场景1. 集成测试中的日志记录funcTestAPIServerIntegration(t*testing.T){ctx:ktesting.Init(t,ktesting.Verbosity(2))logger:klog.FromContext(ctx)// 启动测试服务器server:startTestServer(ctx,logger)deferserver.Stop()// 执行测试操作logger.Info(Creating test resource)resource:createResource(ctx,server.Client())logger.Info(Verifying resource,resource,resource.Name)verifyResource(t,resource)}2. 调试失败测试funcTestComplexScenario(t*testing.T){// 高详细级别用于调试ctx:ktesting.Init(t,ktesting.Verbosity(5))logger:klog.FromContext(ctx)// 记录关键步骤logger.V(4).Info(Step 1: Initializing components)initComponents(ctx)logger.V(4).Info(Step 2: Running main logic)result,err:runMainLogic(ctx)iferr!nil{// 错误时自动记录详细信息logger.Error(err,Main logic failed,result,result,context,step2)t.Fail()}}与标准 testing 的对比特性标准 testingktesting日志记录t.Log()简单字符串结构化日志支持键值对日志级别不支持支持 V 级别过滤上下文传递手动传递 t通过 context 传递日志器子测试基本支持每个子测试可独立配置性能简单结构化日志有轻微开销最佳实践1. 始终使用结构化日志// 好的做法使用键值对logger.Info(User action,user,userID,action,login,result,success)// 避免字符串拼接logger.Info(fmt.Sprintf(User %s login %s,userID,success))2. 合理使用日志级别logger.V(0).Info(Critical operation started)// 重要信息logger.V(2).Info(Detailed step,step,i)// 调试信息logger.V(4).Info(Very detailed,data,data)// 详细调试3. 传递上下文// 始终传递包含日志器的 contextfunchelper(ctx context.Context,paramstring){logger:klog.FromContext(ctx)logger.Info(Helper called,param,param)// ... 实现}总结example_test.go展示了 Kubernetes 测试框架的核心设计理念结构化日志使用键值对而非字符串拼接便于日志分析和过滤上下文传递通过 context 传递日志器实现测试隔离灵活的配置通过选项模式支持不同测试需求性能考虑支持日志级别过滤避免生产环境性能损耗这种设计使得 Kubernetes 的测试更加可维护、可调试同时也为开发者提供了良好的测试编写体验。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2479811.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!