首页 > 编程语言 >【prometheus】【Node_export】【原理介绍】【源码阅读】node_export的newHandler函数详解

【prometheus】【Node_export】【原理介绍】【源码阅读】node_export的newHandler函数详解

时间:2024-12-31 17:29:16浏览次数:3  
标签:Node includeExporterMetrics promhttp err handler export exporterMetricsRegistry 

在这里插入图片描述

这两个函数是 Go 语言 node_exporter 的核心部分,主要与 Prometheus 指标的收集、注册、处理以及 HTTP 处理器的创建相关。我们将逐步解析每个函数的逻辑。

目录

1. newHandler函数

func newHandler(includeExporterMetrics bool, maxRequests int, logger *slog.Logger) *handler {
	h := &handler{
		exporterMetricsRegistry: prometheus.NewRegistry(),
		includeExporterMetrics:  includeExporterMetrics,
		maxRequests:             maxRequests,
		logger:                  logger,
	}
	if h.includeExporterMetrics {
		h.exporterMetricsRegistry.MustRegister(
			promcollectors.NewProcessCollector(promcollectors.ProcessCollectorOpts{}),
			promcollectors.NewGoCollector(),
		)
	}
	if innerHandler, err := h.innerHandler(); err != nil {
		panic(fmt.Sprintf("Couldn't create metrics handler: %s", err))
	} else {
		h.unfilteredHandler = innerHandler
	}
	return h
}
解析:
  1. 创建 handler 对象

    h := &handler{
        exporterMetricsRegistry: prometheus.NewRegistry(),
        includeExporterMetrics:  includeExporterMetrics,
        maxRequests:             maxRequests,
        logger:                  logger,
    }
    
    • 这段代码初始化了一个 handler 实例,并设置其属性:
      • exporterMetricsRegistry: 创建一个新的 Prometheus Registry,用来注册指标。
      • includeExporterMetrics: 是否包括 node_exporter 自身的指标(如进程、Go runtime 等)。
      • maxRequests: 配置最大并发请求数。
      • logger: 用于记录日志的 logger 对象。
  2. 如果 includeExporterMetricstrue,注册与 exporter 自身相关的指标

    if h.includeExporterMetrics {
        h.exporterMetricsRegistry.MustRegister(
            promcollectors.NewProcessCollector(promcollectors.ProcessCollectorOpts{}),
            promcollectors.NewGoCollector(),
        )
    }
    
    • 如果 includeExporterMetricstrue,则将 ProcessCollectorGoCollector 注册到 exporterMetricsRegistry 中。
      • ProcessCollector 采集与进程相关的指标(如进程的 CPU、内存使用等)。
      • GoCollector 采集 Go runtime 的指标(如 goroutine 数、GC 状态等)。
  3. 调用 innerHandler 函数创建内部处理器

    if innerHandler, err := h.innerHandler(); err != nil {
        panic(fmt.Sprintf("Couldn't create metrics handler: %s", err))
    } else {
        h.unfilteredHandler = innerHandler
    }
    
    • 调用 innerHandler 方法来创建一个指标处理器。如果出错,则程序会 panic 并打印错误信息。否则,将生成的处理器赋值给 h.unfilteredHandler
  4. 返回创建的 handler 对象

    return h
    
    • 返回构建好的 handler 实例。

2. innerHandler函数

func (h *handler) innerHandler(filters ...string) (http.Handler, error) {
    nc, err := collector.NewNodeCollector(h.logger, filters...)
    if err != nil {
       return nil, fmt.Errorf("couldn't create collector: %s", err)
    }

    // Only log the creation of an unfiltered handler, which should happen
    // only once upon startup.
    if len(filters) == 0 {
       h.logger.Info("Enabled collectors")
       for n := range nc.Collectors {
          h.enabledCollectors = append(h.enabledCollectors, n)
       }
       sort.Strings(h.enabledCollectors)
       for _, c := range h.enabledCollectors {
          h.logger.Info(c)
       }
    }

    r := prometheus.NewRegistry()
    r.MustRegister(versioncollector.NewCollector("node_exporter"))
    if err := r.Register(nc); err != nil {
       return nil, fmt.Errorf("couldn't register node collector: %s", err)
    }

    var handler http.Handler
    if h.includeExporterMetrics {
       handler = promhttp.HandlerFor(
          prometheus.Gatherers{h.exporterMetricsRegistry, r},
          promhttp.HandlerOpts{
             ErrorLog:            slog.NewLogLogger(h.logger.Handler(), slog.LevelError),
             ErrorHandling:       promhttp.ContinueOnError,
             MaxRequestsInFlight: h.maxRequests,
             Registry:            h.exporterMetricsRegistry,
          },
       )
       // Note that we have to use h.exporterMetricsRegistry here to
       // use the same promhttp metrics for all expositions.
       handler = promhttp.InstrumentMetricHandler(
          h.exporterMetricsRegistry, handler,
       )
    } else {
       handler = promhttp.HandlerFor(
          r,
          promhttp.HandlerOpts{
             ErrorLog:            slog.NewLogLogger(h.logger.Handler(), slog.LevelError),
             ErrorHandling:       promhttp.ContinueOnError,
             MaxRequestsInFlight: h.maxRequests,
          },
       )
    }

    return handler, nil
}
解析:
  1. 创建 NodeCollector

    nc, err := collector.NewNodeCollector(h.logger, filters...)
    if err != nil {
       return nil, fmt.Errorf("couldn't create collector: %s", err)
    }
    
    • 创建一个 NodeCollector 实例来收集系统的节点级指标。如果发生错误,则返回错误信息。
  2. 记录启用的采集器

    if len(filters) == 0 {
        h.logger.Info("Enabled collectors")
        for n := range nc.Collectors {
            h.enabledCollectors = append(h.enabledCollectors, n)
        }
        sort.Strings(h.enabledCollectors)
        for _, c := range h.enabledCollectors {
            h.logger.Info(c)
        }
    }
    
    • 如果没有传入过滤器(即默认启用所有采集器),则记录启用的采集器。
    • 将启用的采集器按名称排序,并逐个输出日志。
  3. 创建一个新的 prometheus.Registry

    r := prometheus.NewRegistry()
    r.MustRegister(versioncollector.NewCollector("node_exporter"))
    
    • 创建一个新的 Registry 实例并注册 versioncollector(记录 node_exporter 版本信息)。
  4. 注册 NodeCollector

    if err := r.Register(nc); err != nil {
       return nil, fmt.Errorf("couldn't register node collector: %s", err)
    }
    
    • NodeCollector 注册到 Prometheus 的 Registry 中。如果注册失败,则返回错误。
  5. 根据 includeExporterMetrics 决定使用哪个处理器

    var handler http.Handler
    if h.includeExporterMetrics {
        handler = promhttp.HandlerFor(
           prometheus.Gatherers{h.exporterMetricsRegistry, r},
           promhttp.HandlerOpts{
              ErrorLog:            slog.NewLogLogger(h.logger.Handler(), slog.LevelError),
              ErrorHandling:       promhttp.ContinueOnError,
              MaxRequestsInFlight: h.maxRequests,
              Registry:            h.exporterMetricsRegistry,
           },
        )
        handler = promhttp.InstrumentMetricHandler(
           h.exporterMetricsRegistry, handler,
        )
    } else {
        handler = promhttp.HandlerFor(
           r,
           promhttp.HandlerOpts{
              ErrorLog:            slog.NewLogLogger(h.logger.Handler(), slog.LevelError),
              ErrorHandling:       promhttp.ContinueOnError,
              MaxRequestsInFlight: h.maxRequests,
           },
        )
    }
    
    • 如果 includeExporterMetricstrue,则创建一个 promhttp.Handler,用于处理包括 node_exporter 自身的指标在内的所有指标。使用 prometheus.Gatherers{h.exporterMetricsRegistry, r} 来聚合来自 exporterMetricsRegistryr 的指标。
    • 如果 includeExporterMetricsfalse,则只创建一个包含 r 的处理器。
  6. 返回 HTTP 处理器

    return handler, nil
    
    • 返回构建好的 HTTP 处理器。

总结:

  • newHandler:该函数主要负责创建 handler 对象,初始化 Prometheus 指标的注册表,并根据是否需要包括 node_exporter 自身的指标来注册相应的指标。如果需要,还会调用 innerHandler 来创建一个指标处理器。

  • innerHandler:该函数负责创建 NodeCollector,注册节点采集器,创建并配置 Prometheus 的 Registry,然后根据是否包含 node_exporter 自身的指标来创建并返回一个 HTTP 处理器。

这两个函数共同作用,负责创建 node_exporter 的 HTTP 处理器并提供 Prometheus 格式的指标。

标签:Node,includeExporterMetrics,promhttp,err,handler,export,exporterMetricsRegistry,
From: https://blog.csdn.net/zhangshenglu1/article/details/144772267

相关文章

  • Springboot流浪动物管理系统p2326(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,宠物分类,宠物信息,领养信息,宠物救助,宠物助养,助养捐款,助养明细,关于我们,成员申请开题报告内容一、开题依据1.研究目的及意义随着城市化进程的推进,......
  • Springboot流浪宠物救助网站设计与实现92soy(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,宠物信息,宠物分类,申请信息开题报告内容一、研究背景与意义随着社会的进步,人们对流浪宠物的关注日益增加。然而,由于缺乏有效的管理,流浪宠物的救助工作面......
  • Springboot零件管理系统48580(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,零件信息,零件领用,零件入库,公告信息开题报告内容一、研究背景随着工业化进程的加速和智能制造的兴起,企业对于生产设备及其零件的管理需求日益增强。传统......
  • Java基于spring boot的小型超市商品管理系统python+nodejs+php-计算机毕业设计
    目录功能和技术介绍具体实现截图开发核心技术:开发环境开发步骤编译运行核心代码部分展示系统设计详细视频演示可行性论证软件测试源码获取功能和技术介绍该系统基于浏览器的方式进行访问,采用springboot集成快速开发框架,前端使用vue方式,基于es5的语法,开发工具Intelli......
  • java基于springboot+vue的视频点播系统数据与分析python+nodejs+php-计算机毕业设计
    目录功能和技术介绍具体实现截图开发核心技术:开发环境开发步骤编译运行核心代码部分展示系统设计详细视频演示可行性论证软件测试源码获取功能和技术介绍该系统基于浏览器的方式进行访问,采用springboot集成快速开发框架,前端使用vue方式,基于es5的语法,开发工具Intelli......
  • python+vue基于django/flask的智慧博物馆预约平台java+nodejs+php-计算机毕业设计
    目录技术栈和环境说明具体实现截图系统设计详细视频演示技术路线解决的思路性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示研究方法感恩大学老师和同学源码获取技术栈和环境说明本系统以Python开发语言开发,MySQL为后......
  • node.js毕设 大规模学术会议智能签到与统计系统 论文+程序
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于大规模学术会议签到与统计问题的研究,现有研究多聚焦于会议管理的部分环节,如单纯的人员信息收集或者传统签到方式的局部优化等。专门针对大规模学术......
  • node.js基于多终端的校园失物招领平台管理端程序+论文 可用于毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于校园失物招领平台的研究,现有研究主要集中在单终端或者通用性失物招领平台方面,专门针对多终端的校园失物招领平台的研究较少。在国内外的校园管理中,......
  • node.js基于协同过滤算法的美食推荐系统 后端程序+论文 可用于毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于美食推荐系统的研究,现有研究主要以基于内容推荐或热门推荐为主。在协同过滤算法应用于美食推荐方面,专门针对美食领域多维度因素(如用户、美食类型、......
  • 【Java项目】基于SpringBoot+Vue的嗨玩旅游网站的设计与实现(源码+LW+包运行)
    源码获取:https://download.csdn.net/download/u011832806/89756183基于SpringBoot+Vue的嗨玩旅游网站开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven嗨玩旅游网站是一个专为旅行爱好者打造的在线平台。我们提供丰富多样的旅游......