diff --git a/lib/prometheus_exporter/client.rb b/lib/prometheus_exporter/client.rb index 2302bd4..fac774c 100644 --- a/lib/prometheus_exporter/client.rb +++ b/lib/prometheus_exporter/client.rb @@ -5,6 +5,8 @@ module PrometheusExporter class Client + NAMING_VALIDATION_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*$/ + class RemoteMetric attr_reader :name, :type, :help @@ -128,6 +130,8 @@ def find_registered_metric(name, type: nil, help: nil) end def send_json(obj) + return false unless valid_naming?(obj) + payload = if @custom_labels if obj[:custom_labels] @@ -269,6 +273,28 @@ def wait_for_empty_queue_with_timeout(timeout_seconds) sleep(0.05) end end + + def valid_naming?(obj) + if obj[:name] + return false unless obj[:name].match?(NAMING_VALIDATION_REGEX) + end + + custom_label_names = [] + if obj[:custom_labels] + custom_label_names.concat(obj[:custom_labels].keys) + end + + if @custom_labels + custom_label_names.concat(@custom_labels.keys) + end + + return true if custom_label_names.empty? + + custom_label_names.all? { |name| + str = name.to_s + str.match?(NAMING_VALIDATION_REGEX) && !str.start_with?("__") + } + end end class LocalClient < Client diff --git a/test/client_test.rb b/test/client_test.rb index 5505114..763da55 100644 --- a/test/client_test.rb +++ b/test/client_test.rb @@ -65,4 +65,25 @@ def test_overriding_logger assert_includes(logs.string, "dropping message cause queue is full") end + + def test_invalid_naming + client = PrometheusExporter::Client.new(custom_labels: {"label" => 1}) + + refute_same(false, client.send_json({})) + refute_same(false, client.send_json({name: "valid_name"})) + refute_same(false, client.send_json({name: "__valid_name"})) + refute_same(false, client.send_json({name: "__valid_name_1"})) + refute_same(false, client.send_json({name: "__valid_name_1", custom_labels: {"valid_name" => "value"}})) + refute_same(false, client.send_json({name: "valid_name", custom_labels: {"_valid_name" => "value"}})) + + assert_equal(false, client.send_json({name: "invalid-name"})) + assert_equal(false, client.send_json({name: "valid_name", custom_labels: {"__invalid_name" => "value"}})) + assert_equal(false, client.send_json({name: "valid_name", custom_labels: {"invalid-name" => "value"}})) + + client.custom_labels = {"__invalid_name" => "value"} + assert_equal(false, client.send_json({})) + + client.custom_labels = {"invalid-name" => "value"} + assert_equal(false, client.send_json({})) + end end