Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions lib/prometheus/client/data_stores/direct_file_store.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require 'fileutils'
require "cgi"

require 'prometheus/client/version'

module Prometheus
module Client
module DataStores
Expand Down Expand Up @@ -33,9 +35,15 @@ class InvalidStoreSettingsError < StandardError; end
DEFAULT_METRIC_SETTINGS = { aggregation: SUM }
DEFAULT_GAUGE_SETTINGS = { aggregation: ALL }

def initialize(dir:)
def initialize(dir:, clean_dir: false)
@store_settings = { dir: dir }
FileUtils.mkdir_p(dir)

if clean_dir
Dir.glob(File.join(dir, "#{ MetricStore::FILENAME_PREFIX }_*___*.bin")).each do |file_path|
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't delete files from old versions of the gem.. thoughts?

File.unlink(file_path)
end
end
end

def for_metric(metric_name, metric_type:, metric_settings: {})
Expand All @@ -52,6 +60,12 @@ def for_metric(metric_name, metric_type:, metric_settings: {})
metric_settings: settings)
end

def clean_pid(pid)
Dir.glob(File.join(@store_settings[:dir], "#{ MetricStore::FILENAME_PREFIX }_*___#{pid}.bin")).each do |file_path|
File.unlink(file_path)
end
end

private

def validate_metric_settings(metric_settings)
Expand All @@ -68,6 +82,7 @@ def validate_metric_settings(metric_settings)
end

class MetricStore
FILENAME_PREFIX = "prometheus_#{ Prometheus::Client::VERSION }"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this from metric to prometheus to reduce the chance of deleting unrelated files.. thoughts?

attr_reader :metric_name, :store_settings

def initialize(metric_name:, store_settings:, metric_settings:)
Expand Down Expand Up @@ -168,12 +183,12 @@ def internal_store

# Filename for this metric's PStore (one per process)
def filemap_filename
filename = "metric_#{ metric_name }___#{ process_id }.bin"
filename = "#{ FILENAME_PREFIX }_#{ metric_name }___#{ process_id }.bin"
File.join(@store_settings[:dir], filename)
end

def stores_for_metric
Dir.glob(File.join(@store_settings[:dir], "metric_#{ metric_name }___*"))
Dir.glob(File.join(@store_settings[:dir], "#{ FILENAME_PREFIX }_#{ metric_name }___*.bin"))
end

def process_id
Expand Down
16 changes: 10 additions & 6 deletions spec/prometheus/client/data_stores/direct_file_store_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,9 @@
require 'examples/data_store_example'

describe Prometheus::Client::DataStores::DirectFileStore do
subject { described_class.new(dir: "/tmp/prometheus_test") }
subject { described_class.new(dir: "/tmp/prometheus_test", clean_dir: true) }
let(:metric_store) { subject.for_metric(:metric_name, metric_type: :counter) }

# Reset the PStores
before do
Dir.glob('/tmp/prometheus_test/*').each { |file| File.delete(file) }
end

it_behaves_like Prometheus::Client::DataStores

it "only accepts valid :aggregation as Metric Settings" do
Expand Down Expand Up @@ -57,6 +52,15 @@
ms2.increment(labels: {}, by: 1)
end

it "can clean files from old processes" do
allow(Process).to receive(:pid).and_return(12345)
ms = metric_store
ms.increment(labels: {}, by: 1)
expect(ms.all_values).to eq({} => 1.0)
subject.clean_pid(12345)
expect(ms.all_values).to be_empty
end

context "when process is forked" do
it "opens a new internal store to avoid two processes using the same file" do
allow(Process).to receive(:pid).and_return(12345)
Expand Down