news 2026/5/23 1:34:30

DeepSeekubernetes-1.35.3/kubernetes-1.35.3/test/utils/ktesting/examples/logging/example_test.go 源码分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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("context""testing""k8s.io/klog/v2""k8s.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)// 创建带字段的日志器logger=logger.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:// 所有日志都会包含 component=example 和 testID=12345 字段}// 示例:展示子测试中的日志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)// 这些日志会被记录(级别 <= 2)logger.V(1).Info("Verbosity 1 message")logger.V(2).Info("Verbosity 2 message")// 这个日志不会被记录(级别 > 2)logger.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;i<b.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")// -v=1 时可见logger.V(2).Info("debug level 2")// -v=2 时可见

实际应用场景

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 测试框架的核心设计理念:

  1. 结构化日志:使用键值对而非字符串拼接,便于日志分析和过滤
  2. 上下文传递:通过 context 传递日志器,实现测试隔离
  3. 灵活的配置:通过选项模式支持不同测试需求
  4. 性能考虑:支持日志级别过滤,避免生产环境性能损耗

这种设计使得 Kubernetes 的测试更加可维护、可调试,同时也为开发者提供了良好的测试编写体验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/23 1:34:43

PyQt6开发可视化界面中遇到问题及解决方案集合

PyQt6开发可视化界面中遇到问题及解决方案集合 安装与配置&#xff1a; 1.配环境の拷打 因为博主这个项目本来是在pycharm中的本地python3.12.7环境下开发的&#xff0c;涉及mineru解析&#xff0c;vectordatabase、fuseki、neo4j入库等核心模块&#xff0c;开发桌面软件时遇…

作者头像 李华
网站建设 2026/5/23 1:34:34

【EtD】Exposing the Deception: Uncovering More Forgery Clues for Deepfake Detection

文章目录 Exposing the Deception: Uncovering More Forgery Clues for Deepfake Detection points 摘要 介绍 相关工作 方法 局部解耦模块 全局聚合模块 评估 实验设置 与现有方法的比较 消融实验 可视化 局限性 理论证明(补充) 评估(补充) Exposing the Deception: Uncov…

作者头像 李华
网站建设 2026/5/23 1:34:30

双臂机器人piper_ros

1.piper gazebo仿真启动gazebo终端1&#xff1a;cd piper_ros source devel/setup.bash roslaunch piper_gazebo piper_gazebo.launch #有夹爪roslaunch piper_gazebo piper_no_gripper_gazebo.launch #无夹爪启动rviz终端2&#xff1a;cd ~/piper_ros source devel/setup.bash…

作者头像 李华
网站建设 2026/5/23 1:35:09

FLAC3D流固耦合,降雨强度对边坡稳定性影响,案例

FLAC3D流固耦合&#xff0c;降雨强度对边坡稳定性影响&#xff0c;案例FLAC3D 是一个功能强大的数值模拟软件&#xff0c;广泛应用于岩土工程、采矿工程等领域。它通过离散元法&#xff08;Distinct Element Method&#xff0c;简称 DEM&#xff09;模拟岩石和土壤的力学行为&a…

作者头像 李华
网站建设 2026/5/23 1:34:38

高可用外卖返利 CPS 平台:Java 后端异步回调处理机制深度解析

高可用外卖返利 CPS 平台&#xff1a;Java 后端异步回调处理机制深度解析 在构建外卖返利&#xff08;CPS&#xff09;系统时&#xff0c;异步回调&#xff08;Callback&#xff09;机制是连接用户授权、订单同步与佣金结算的神经中枢。美团、饿了么等平台的用户授权与订单状态…

作者头像 李华