Files
ubicloud/rhizome/common/bin/metrics-collector
shikharbhardwaj 27eb155fcb Move metrics-collector to rhizome/common/bin
Allow for re-use in other places.
2025-05-23 12:42:17 +05:30

63 lines
2.1 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# frozen_string_literal: true
require "fileutils"
require "json"
require "net/http"
require "openssl"
require "time"
require "uri"
if ARGV.count != 1
fail "Wrong number of arguments. Expected 1, Given #{ARGV.count}"
end
metrics_dir = ARGV[0]
fail "Metrics directory does not exist: #{metrics_dir}" unless Dir.exist?(metrics_dir)
fail "Metrics config file does not exist: #{metrics_dir}/config.json" unless File.exist?("#{metrics_dir}/config.json")
# Create directories
FileUtils.mkdir_p("#{metrics_dir}/pending")
FileUtils.mkdir_p("#{metrics_dir}/done")
# Clear the pending directory on startup (anything there is from a crash)
Dir.children("#{metrics_dir}/pending").each { File.delete("#{metrics_dir}/pending/#{_1}") }
# Parse config
metrics_config_hash = JSON.parse(File.read("#{metrics_dir}/config.json"))
endpoints = metrics_config_hash["endpoints"]
max_file_retention = metrics_config_hash["max_file_retention"] || 100
filename = Time.now.utc.strftime("%Y-%m-%dT%H-%M-%S-%6N")
pending_file_path = "#{metrics_dir}/pending/#{filename}.txt"
# Download content directly to the pending directory
File.open(pending_file_path, "w") do |file|
endpoints.each do |endpoint|
uri = URI(endpoint)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # Equivalent to --insecure
response = http.get(uri.request_uri)
fail "HTTP request failed with status: #{response.code}" unless response.is_a?(Net::HTTPSuccess)
file.write(response.body)
end
file.flush
file.fsync
end
# Move complete file to "done" and make confirm rename persistence via
# directory fsync.
File.rename(pending_file_path, "#{metrics_dir}/done/#{filename}.txt")
File.open("#{metrics_dir}/done") { _1.fsync }
# Trim the done directory to keep only max_file_retention files
done_files = Dir.children("#{metrics_dir}/done").sort
num_files_to_remove = [done_files.count - max_file_retention, 0].max
# Remove oldest files
done_files.slice(0, num_files_to_remove).each { File.delete("#{metrics_dir}/done/#{_1}") }