Class: PrometheusConfigBuilder::ScrapeConfigECS

Inherits:
Object
  • Object
show all
Extended by:
PrometheusConfigBuilderLogger
Defined in:
lib/prometheus-config-builder/scrape_ecs.rb

Class Method Summary collapse

Methods included from PrometheusConfigBuilderLogger

logger, logger, logger=

Class Method Details

.get_task_endpoints(cluster, tasks, common_labels, metrics_port) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/prometheus-config-builder/scrape_ecs.rb', line 83

def self.get_task_endpoints(cluster, tasks, common_labels, metrics_port)
  endpoints = []
  if tasks.length == 0
    return []
  end

  task_chunk = tasks.pop(100)
  loop do
    begin
      options = {
        cluster: cluster,
        tasks: task_chunk,
      }
      result = @@ecs.describe_tasks(options)
      if result && result.tasks
        result.tasks.each do |task|
          # FIXME: This assumes somewhat on the ip structure.
          if task.containers[0].network_interfaces && task.containers[0].network_interfaces.length > 0
            ip = task.containers[0].network_interfaces[0].private_ipv_4_address
          else
            logger.warn("WARNING: Unable to obtain ipv4 address from task #{task}")
            return
          end

          if metrics_port
            ip = ip + ":" + metrics_port.to_s
          end
          labels = common_labels.clone
          labels["ecs_arn"] = task.task_arn
          endpoints << {
            "targets" => [ip],
            "labels" => labels
          }
        end
      end
    rescue Aws::ECS::Errors::ServiceError => e
      logger.warn("Error listing ecs tasks for cluster #{cluster}: #{e}\n")
      sleep(1)
      next
    end
    break if tasks.length == 0
    task_chunk = tasks.pop(100)
  end
  return endpoints
end

.get_tasks(cluster, service_name) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/prometheus-config-builder/scrape_ecs.rb', line 57

def self.get_tasks(cluster, service_name)
  tasks = []
  last_result = Aws::ECS::Types::ListTasksResponse.new
  last_result.next_token = nil
  loop do
    begin
      options = {
        cluster: cluster,
        service_name: service_name,
        next_token: last_result.next_token
      }
      last_result = @@ecs.list_tasks(options)
      if last_result && last_result.task_arns
        tasks.push(*last_result.task_arns)
      end
    rescue Aws::ECS::Errors::ServiceError => e
      logger.warn("Error listing ecs tasks for service #{service_name} in cluster #{cluster}: #{e}")
      sleep(1)
      next
    end
    break if !last_result.next_token
  end

  return tasks
end

.handle(basename, config, dst_prefix) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/prometheus-config-builder/scrape_ecs.rb', line 9

def self.handle(basename, config, dst_prefix)

  x = $VERBOSE
  $VERBOSE = nil
  require 'aws-sdk'

  if !config["region"]
    logger.warn("File #{basename}: the scrape_configs of type:ecs-tasks doesn't have \"region\" field set. Ignoring!")
    return nil

  end

  @@ecs = Aws::ECS::Client.new({
    region:config["region"]
  })
  $VERBOSE = x
  tasks = get_tasks(config["cluster"], config["service"])
  endpoints = get_task_endpoints(config["cluster"], tasks, config["labels"], config["metrics_port"])

  if !config["job_name"]
    logger.warn("File #{basename}: the scrape_configs of type:ecs-tasks doesn't have \"job_name\" field set. Ignoring!")
    return nil
  end

  file = File.expand_path(dst_prefix + "_" + config["job_name"] + ".json")
  File.open(file, "w") do |file|
    file.write(endpoints.to_json)
  end

  # Make copy of the settings and remove our custom properties from it.
  # The rest user can set just as he wants according to the Prometheus schema.
  # See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config
  settings = config.clone
  settings.delete("type")
  settings.delete("cluster")
  settings.delete("service")
  settings.delete("metrics_port")
  settings.delete("labels")
  settings.delete("region")
  settings["file_sd_configs"] = [
    "files" => [
      file
    ]
  ]

  return settings
end