• grafana agent 动态配置内部机制简单说明


    grafana agent 动态配置目前属于一个体验特性,但是设计上利用了gomplate 一个强大的模版引擎工具

    参考配置

    • 运行配置参考
    agentv2:
      image: grafana/agent:main
      ports:
        - 12345:12345
        - 12347:12347
      entrypoint:
        - /bin/agent
        - -config.file.type=dynamic
        - -server.http.address=0.0.0.0:12345
        - -config.file=file:///etc/agent-config/agent.yaml # 动态配置默认加载地址
        - -metrics.wal-directory=/tmp/agent/wal
        - -enable-features=dynamic-config,integrations-next # 需要开启的特性
        - -config.enable-read-api
      volumes:
        - ./agentv2.yaml:/etc/agent-config/agent.yaml
        - ./agent-data:/etc/agent/data
        - ./confs:/opt/confs # 挂载的配置文件
        - ./logs:/var/log
    • 配置参考
      比如metrics ,需要移除metrics
     
    global:
        scrape_interval: 10s
        remote_write:
        - url: http://victoriametrics:8428/api/v1/write
    configs:
      - name: default
        scrape_configs:
        - job_name: avalanche
          static_configs:
          - targets: ['${AVALANCHE_HOST:-localhost:9001}']

    log 配置

    configs:
      - name: default
        positions:
          filename: /tmp/positions.yaml
        scrape_configs:
          - job_name: varlogs
            static_configs:
              - targets: [localhost]
                labels:
                  job: varlogs
                  __path__: /var/log/*log
        clients:
          - url: http://loki:3100/loki/api/v1/push

    filter 配置 (agentv2.yaml)

    template_paths:
      - file:///opt/confs # 基于文件格式
    # Filters allow you to override the default naming convention
     
    agent_filter:            "agent-*.yml" # defaults to agent-*.yml
    server_filter:           "server-*.yml" # defaults to server-*.yml
    metrics_filter:          "metrics-*.yml" # defaults to metrics-*.yml
    #metrics_instance_filter: string # defaults to metrics_instances-*.yml
    integrations_filter:     "integrations-*.yml" # defaults to integrations-*.yml
    logs_filter:             "logs-*.yml" # defaults to logs-*.yml
    traces_filter:           "traces-*.yml" # defaults to traces-*.yml

    内部机制

    grafana agent 动态配置实际上上利用了gomplate,但是目前来说似乎只能是第一次加载的时候,并不能实时reload
    处理机制上核心是开发的一些filter,如果需要加载其他数据源推荐配置datasource,默认可以通过本地文件
    filter 处理部分

     
    // ProcessConfigs loads the configurations in a predetermined order to handle functioning correctly.
    func (c *DynamicLoader) ProcessConfigs(cfg *Config) error {
      if c.cfg == nil {
        return fmt.Errorf("LoadConfig or LoadConfigByPath must be called")
      }
      var returnErr error
     
      err := c.processAgent(cfg)
      returnErr = errorAppend(returnErr, err)
     
      serverConfig, err := c.processServer()
      returnErr = errorAppend(returnErr, err)
      if serverConfig != nil {
        cfg.Server = *serverConfig
      }
     
      metricConfig, err := c.processMetrics()
      returnErr = errorAppend(returnErr, err)
      if metricConfig != nil {
        cfg.Metrics = *metricConfig
      }
     
      instancesConfigs, err := c.processMetricInstances()
      returnErr = errorAppend(returnErr, err)
      cfg.Metrics.Configs = append(cfg.Metrics.Configs, instancesConfigs...)
     
      logsCfg, err := c.processLogs()
      returnErr = errorAppend(returnErr, err)
      if logsCfg != nil {
        cfg.Logs = logsCfg
      }
     
      traceConfigs, err := c.processTraces()
      returnErr = errorAppend(returnErr, err)
      if traceConfigs != nil {
        cfg.Traces = *traceConfigs
      }
     
      integrations, err := c.processIntegrations()
      returnErr = errorAppend(returnErr, err)
     
      cfg.Integrations.ExtraIntegrations = append(cfg.Integrations.ExtraIntegrations, integrations...)
     
      return returnErr
    }

    不同filter 处理(log 参考)

    func (c *DynamicLoader) processLogs() (*logs.Config, error) {
      var returnError error
      found := 0
      var cfg *logs.Config
      // 基于配置的模版进行模版数据的处理
      for _, path := range c.cfg.TemplatePaths {
        filesContents, err := c.retrieveMatchingFileContents(path, c.cfg.LogsFilter, "logs")
        returnError = errorAppend(returnError, err)
        found = len(filesContents) + found
        if len(filesContents) == 1 {
          cfg = &logs.Config{}
          err = yaml.Unmarshal([]byte(filesContents[0]), cfg)
          returnError = errorAppend(returnError, err)
        }
      }
      // 只支持一个文件,实际上官方文档也说明了log 只支持一个
      if found > 1 {
        returnError = errorAppend(returnError, fmt.Errorf("found %d logs templates; expected 0 or 1", found))
      }
      return cfg, returnError
    }

    datasource 的加载(基于了gomplate的能力)

    // DynamicLoader is used to load configs from a variety of sources and squash them together.
    // This is used by the dynamic configuration feature to load configurations from a set of templates and then run them through
    // gomplate producing an end result.
    type DynamicLoader struct {
      loader *loader.ConfigLoader
      mux    fsimpl.FSMux
      cfg    *LoaderConfig
    }
     
    // NewDynamicLoader instantiates a new DynamicLoader.
    func NewDynamicLoader() (*DynamicLoader, error) {
      // 此处基于了hairyhenderson 提供的vfs 能力,目前只支持本地以及对象存储文件,实际上hairyhenderson/go-fsimpl 还提供其他费事(git,http。。。。)
      return &DynamicLoader{
        mux: newFSProvider(),
      }, nil
    }
     
    // LoadConfig loads an already created LoaderConfig into the DynamicLoader.
    func (c *DynamicLoader) LoadConfig(cfg LoaderConfig) error {
      sources := make(map[string]*data.Source)
      for _, v := range cfg.Sources {
        sourceURL, err := url.Parse(v.URL)
        if err != nil {
          return err
        }
        sources[v.Name] = &data.Source{
          URL:   sourceURL,
          Alias: v.Name,
        }
      }
      // Set Defaults
      if cfg.IntegrationsFilter == "" {
        cfg.IntegrationsFilter = "integrations-*.yml"
      }
      if cfg.AgentFilter == "" {
        cfg.AgentFilter = "agent-*.yml"
      }
      if cfg.ServerFilter == "" {
        cfg.ServerFilter = "server-*.yml"
      }
      if cfg.MetricsFilter == "" {
        cfg.MetricsFilter = "metrics-*.yml"
      }
      if cfg.MetricsInstanceFilter == "" {
        cfg.MetricsInstanceFilter = "metrics_instances-*.yml"
      }
      if cfg.LogsFilter == "" {
        cfg.LogsFilter = "logs-*.yml"
      }
      if cfg.TracesFilter == "" {
        cfg.TracesFilter = "traces-*.yml"
      }
      cl := loader.NewConfigLoader(context.Background(), sources)
      c.loader = cl
      c.cfg = &cfg
      return nil
    }

    说明

    以上是一个简单的说明,详细的可以多看看源码

    参考资料

    https://github.com/grafana/agent/blob/987c214431af8abae7e13468468b99d21d2df3e3/pkg/config
    https://github.com/hairyhenderson/gomplate
    https://grafana.com/docs/agent/latest/configuration/dynamic-config/

  • 相关阅读:
    div中嵌套div中使用margin-top失效问题
    thinkphp点击导航变色
    thinkphp I() 方法
    判断是手机端还是电脑端 isMobile()
    手机端H5 header定义样式
    AR.Drone 2.0四轴飞机体验:最好的玩具航拍器
    这是一个专注于电脑技术、软件应用、互联网、嵌入式,电子技术行业等的原创IT博客
    ul li列子
    [HTML]去除li前面的小黑点,和ul、LI部分属性
    Bad update sites
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/16871359.html
Copyright © 2020-2023  润新知