funcmain(){ // 使用 kingpin 定义了众多标志 var ( listenAddress = kingpin.Flag( "web.listen-address", "Address on which to expose metrics and web interface.", ).Default(":9100").String() metricsPath = kingpin.Flag( "web.telemetry-path", "Path under which to expose metrics.", ).Default("/metrics").String() disableExporterMetrics = kingpin.Flag( "web.disable-exporter-metrics", "Exclude metrics about the exporter itself (promhttp_*, process_*, go_*).", ).Bool() maxRequests = kingpin.Flag( "web.max-requests", "Maximum number of parallel scrape requests. Use 0 to disable.", ).Default("40").Int() disableDefaultCollectors = kingpin.Flag( "collector.disable-defaults", "Set all collectors to disabled by default.", ).Default("false").Bool() configFile = kingpin.Flag( "web.config", "[EXPERIMENTAL] Path to config yaml file that can enable TLS or authentication.", ).Default("").String() ) promlogConfig := &promlog.Config{} flag.AddFlags(kingpin.CommandLine, promlogConfig)
// 定义 Version 的输出信息,HelpFlag 的短字段 kingpin.Version(version.Print("node_exporter")) kingpin.HelpFlag.Short('h') kingpin.Parse()
iflen(filters) == 0 { // No filters, use the prepared unfiltered handler. h.unfilteredHandler.ServeHTTP(w, r) return } // To serve filtered metrics, we create a filtering handler on the fly. // 动态创建 filteredHandler filteredHandler, err := h.innerHandler(filters...) if err != nil { level.Warn(h.logger).Log("msg", "Couldn't create filtered metrics handler:", "err", err) w.WriteHeader(http.StatusBadRequest) w.Write([]byte(fmt.Sprintf("Couldn't create filtered metrics handler: %s", err))) return } filteredHandler.ServeHTTP(w, r) }
// innerHandler is used to create both the one unfiltered http.Handler to be // wrapped by the outer handler and also the filtered handlers created on the // fly. The former is accomplished by calling innerHandler without any arguments // (in which case it will log all the collectors enabled via command-line // flags). func(h *handler)innerHandler(filters ...string)(http.Handler, error) { // 根据 filters 指定字符串 Collector,用于创建 `collector.NodeCollector` nc, err := collector.NewNodeCollector(h.logger, filters...) if err != nil { returnnil, fmt.Errorf("couldn't create collector: %s", err) }
// Only log the creation of an unfiltered handler, which should happen // only once upon startup. // 这里将在 node_exporter 启动时打印启用的 Collector 相关日志 iflen(filters) == 0 { level.Info(h.logger).Log("msg", "Enabled collectors") collectors := []string{} for n := range nc.Collectors { collectors = append(collectors, n) } sort.Strings(collectors) for _, c := range collectors { level.Info(h.logger).Log("collector", c) } }
r := prometheus.NewRegistry() r.MustRegister(version.NewCollector("node_exporter")) if err := r.Register(nc); err != nil { returnnil, fmt.Errorf("couldn't register node collector: %s", err) } // 这里应该是收集指标数据的过程 handler := promhttp.HandlerFor( // 传入的 Gatherers 内部保存了实现 Gatherer 接口的 Registry,将来 Registry 会在 Gather() 方法中通过其中保存的 Collector 对象调用 Collect() 方法收集数据指标. // 同时 Collector 对象的 Collect() 方法内部会调用 Collector.Update() 方法获取数据指标相关信息 prometheus.Gatherers{h.exporterMetricsRegistry, r}, promhttp.HandlerOpts{ ErrorHandling: promhttp.ContinueOnError, MaxRequestsInFlight: h.maxRequests, Registry: h.exporterMetricsRegistry, }, ) // 如果没有指定 --web.disable-exporter-metrics` 选项,则 `h.includeExporterMetrics = true` if h.includeExporterMetrics { // Note that we have to use h.exporterMetricsRegistry here to // use the same promhttp metrics for all expositions. // 调用 InstrumentMetricHandler 方法,对 promhttp_metric_handler_requests_total,promhttp_metric_handler_requests_in_flight 值进行设置 handler = promhttp.InstrumentMetricHandler( h.exporterMetricsRegistry, handler, ) } return handler, nil }