prometheus_enumerated_store 0.0.1.183933

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 514c84eb0f23127b7ecf237e33f32a5e4b33c7b63437feecde65e44bf4a085ec
4
+ data.tar.gz: 1ae0fc91c573feb22cdfe1110f176ddd408ed7feed9ec9aed8cf9115a67bfe4e
5
+ SHA512:
6
+ metadata.gz: a6093fada7f4b37ba58bc68ce5a92a9a87437c9c6249dfb8c2e16431db13f7aa755aa992a7dd917acd7177ee462175367b3248f6fe7db5cb7bec4f63ac20f5b9
7
+ data.tar.gz: abefba09ff32857c324cf36953cce55c72a71a91cdcb6d435b2d0fc47673bdd17dd2dede0e213a84e1d8be9b2cc66ac3f5e17c39ac4fe1c1d6ad37f6465fcb6d
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2014-2023 Рнд Софт
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Enumerated File Store
2
+
3
+ <div align="center">
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/prometheus_enumerated_store.svg)](https://rubygems.org/gems/prometheus_enumerated_store)
6
+ [![Gem](https://img.shields.io/gem/dt/prometheus_enumerated_store.svg)](https://rubygems.org/gems/prometheus_enumerated_store/versions)
7
+ [![YARD](https://badgen.net/badge/YARD/doc/blue)](http://www.rubydoc.info/gems/prometheus_enumerated_store)
8
+
9
+
10
+ [![coverage](https://lysander.rnds.pro/api/v1/badges/enumerated_coverage.svg)](https://lysander.rnds.pro/api/v1/badges/enumerated_coverage.html)
11
+ [![quality](https://lysander.rnds.pro/api/v1/badges/enumerated_quality.svg)](https://lysander.rnds.pro/api/v1/badges/enumerated_quality.html)
12
+ [![outdated](https://lysander.rnds.pro/api/v1/badges/enumerated_outdated.svg)](https://lysander.rnds.pro/api/v1/badges/enumerated_outdated.html)
13
+ [![vulnerable](https://lysander.rnds.pro/api/v1/badges/enumerated_vulnerable.svg)](https://lysander.rnds.pro/api/v1/badges/enumerated_vulnerable.html)
14
+
15
+ </div>
16
+
17
+ `Enumerated File Store` - это гем для реализации [специального Data Store](https://github.com/prometheus/client_ruby#data-stores) для библиотеки [prometheus-client](https://github.com/prometheus/client_ruby).
18
+
19
+ Данная библиотека решает [проблему огромного числа файлов-метрик](https://github.com/prometheus/client_ruby/issues/143) при использовании стандартного [DirectFileStore](https://github.com/prometheus/client_ruby#directfilestore-caveats-and-things-to-keep-in-mind)
20
+
21
+ ---
22
+
23
+ `Enumerated File Store` provides [custom Data Store](https://github.com/prometheus/client_ruby#data-stores) for [prometheus-client](https://github.com/prometheus/client_ruby) library.
24
+
25
+ It fixes issue with [too many files for long running applications](https://github.com/prometheus/client_ruby/issues/143) when using [DirectFileStore](https://github.com/prometheus/client_ruby#directfilestore-caveats-and-things-to-keep-in-mind).
26
+
27
+ <div align="left">
28
+ <a href="https://rnds.pro/" >
29
+ <img src="https://library.rnds.pro/repository/public-blob/logo/RNDS.svg" alt="Supported by RNDSOFT" height="60">
30
+ </a>
31
+ </div>
32
+
33
+ ## Возможности / Features
34
+
35
+ Библиоетка использует последовательное присвоение номеров файлам метри вместо использования PID / It uses sequential numbering for metric filenames instead of PID-stamps.
36
+
37
+
38
+ ## Начало работы / Getting started
39
+
40
+ ```sh
41
+ gem install prometheus-enumerated-store
42
+ ```
43
+
44
+ При установке `prometheus_enumerated_store` через bundler добавьте следующую строку в `Gemfile`:
45
+
46
+ ---
47
+
48
+ If you'd rather install `prometheus_enumerated_store` using bundler, add a line for it in your `Gemfile`:
49
+
50
+ ```sh
51
+ gem 'prometheus_enumerated_store'
52
+ ```
53
+
54
+ Затем выполните / Then run:
55
+
56
+ ```sh
57
+ bundle install # для установки гема / gem installation
58
+
59
+ ```
60
+ ## Использование / Usage
61
+
62
+ Для использования необходимо в каком-нибудь файле `config/initializers/` настройить `Data Store` для библиотеки `prometheus-client`:
63
+
64
+ ---
65
+
66
+ Now you need to set `Data Store` for `prometheus-client` gem somewhere in `config/initializers/`:
67
+
68
+
69
+ ```ruby
70
+ Prometheus::Client.config.data_store = Prometheus::Enumerated::Store.new(dir: Rails.root.join('tmp', 'prometheus_metrics'))
71
+
72
+ if defined?(PhusionPassenger)
73
+ PhusionPassenger.on_event(:starting_worker_process) do |_forked|
74
+ Prometheus::Client.config.data_store.reset
75
+ end
76
+ end
77
+
78
+
79
+ # Or somewhere in Pum config if any:
80
+
81
+ on_restart do
82
+ Prometheus::Client.config.data_store.reset
83
+ end
84
+
85
+ on_worker_boot do
86
+ Prometheus::Client.config.data_store.reset
87
+ end
88
+ ```
89
+
90
+ ## Лицензия / License
91
+
92
+ Библиотека доступна с открытым исходным кодом в соответствии с условиями [лицензии MIT](./LICENSE).
93
+
94
+ ---
95
+
96
+ The gem is available as open source under the terms of the [MIT License](./LICENSE).
97
+
@@ -0,0 +1 @@
1
+ require_relative 'enumerated_store'
@@ -0,0 +1,95 @@
1
+ module Prometheus
2
+ # Класс мапит текущий PID на минимальный "свободный" номер
3
+ # "свободность" определяется по принципу процесс с пидом есть? - значит занято
4
+ # реестр хранится в файле в виде {"22655":1,"22760":2,"22813":3,"22832":4}
5
+ # где слева PID, справа занятый им (когда-то) номер
6
+ # Информация актуализируется (удаляются несуществующие записи) при очередном выделении
7
+ # многопроцессность синхронизируется через механизм эксключзивных блокировок flock
8
+ module EnumeratedStore
9
+ class PidEnumerator
10
+
11
+ MAX_INSTANCES = 1000
12
+
13
+ attr_reader :dir, :instances_path, :lock_path
14
+
15
+ def initialize(dir:)
16
+ @dir = dir
17
+
18
+ @lock_path = File.join(@dir, 'enumetated_instances.lock')
19
+ @instances_path = File.join(@dir, 'enumetated_instances.json')
20
+ reset
21
+ end
22
+
23
+ def reset
24
+ @obtained = nil
25
+ end
26
+
27
+ def with_lock
28
+ File.open(lock_path, File::RDWR | File::CREAT, 0o644) do |file|
29
+ file.flock(File::LOCK_EX)
30
+ Dir.chdir(@dir) do
31
+ tmpfilename = ".tmp-#{$$}-#{rand(0x100000000).to_s(36)}.json"
32
+ yield(tmpfilename)
33
+ ensure
34
+ File.delete(tmpfilename) rescue nil
35
+ end
36
+ end
37
+ end
38
+
39
+ def read_instances
40
+ raw = File.read(instances_path).strip
41
+ raw.empty? ? '{}' : raw
42
+ rescue Errno::ENOENT
43
+ # there is no file yet
44
+ '{}'
45
+ end
46
+
47
+ def obtained
48
+ @obtained ||= obtain_enumerated_number
49
+ end
50
+
51
+ def obtain_enumerated_number
52
+ with_lock do |tmpfilename|
53
+ break @obtained if @obtained # double check-lock
54
+
55
+ raw_data = read_instances
56
+ data = JSON.parse(raw_data) || {} # set {} if "null" in file
57
+ data = clean_dead_instances(data)
58
+
59
+ current = find_minimal_number(data)
60
+ File.write(tmpfilename, data.to_json) # We are inside tmpdir
61
+ File.rename(tmpfilename, instances_path)
62
+ current
63
+ end
64
+ end
65
+
66
+ def find_minimal_number(data)
67
+ values = data.values
68
+ current = data[Process.pid.to_s] || (1..MAX_INSTANCES).find{|i| !values.include?(i) }
69
+ raise "Unable to find any number between 1 and #{MAX_INSTANCES}" unless current
70
+
71
+ data[Process.pid.to_s] = current
72
+ end
73
+
74
+ def clean_dead_instances(data)
75
+ data.select do |pid, num|
76
+ next nil if num.to_i <= 0 || num.to_i > MAX_INSTANCES
77
+
78
+ alive?(pid.to_i)
79
+ end
80
+ end
81
+
82
+ def alive?(pid)
83
+ return nil if pid <= 1
84
+
85
+ Process.getpgid(pid)
86
+ true
87
+ rescue Errno::ESRCH
88
+ false
89
+ end
90
+
91
+
92
+ end
93
+ end
94
+ end
95
+
@@ -0,0 +1,35 @@
1
+ require 'prometheus/client/data_stores/direct_file_store'
2
+
3
+ module Prometheus
4
+ module EnumeratedStore
5
+ class Store < Prometheus::Client::DataStores::DirectFileStore
6
+
7
+ attr_reader :pid_enumerator
8
+
9
+ def initialize(*_args, dir:, **_kwargs)
10
+ super
11
+ @pid_enumerator = PidEnumerator.new(dir: dir)
12
+ # pass enumerator through store_settings to every MetricStore
13
+ @store_settings[:pid_enumerator] = @pid_enumerator
14
+ end
15
+
16
+ def reset
17
+ @pid_enumerator.reset
18
+ end
19
+
20
+ def self.metric_store_class
21
+ MetricStore
22
+ end
23
+
24
+ MetricStore.class_eval do
25
+ # Monkeypatch! there is no normal method to overload filename generation
26
+ # https://github.com/prometheus/client_ruby/blob/e144d6225d3c346e9a4dd0a11f41f8acde386dd8/lib/prometheus/client/data_stores/direct_file_store.rb#L190
27
+ def process_id
28
+ @store_settings[:pid_enumerator].obtained
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,8 @@
1
+ module Prometheus
2
+ module EnumeratedStore
3
+
4
+ VERSION = '0.0.1'.freeze
5
+
6
+ end
7
+ end
8
+
@@ -0,0 +1,11 @@
1
+ require 'prometheus/enumerated_store/version'
2
+ require 'prometheus/enumerated_store/pid_enumerator'
3
+ require 'prometheus/enumerated_store/store'
4
+
5
+
6
+ module Prometheus
7
+ module EnumeratedStore
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1 @@
1
+ require_relative 'prometheus_enumerated_store'
@@ -0,0 +1,5 @@
1
+ require 'prometheus/enumerated_store'
2
+
3
+ module Prometheus
4
+ end
5
+
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prometheus_enumerated_store
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.183933
5
+ platform: ruby
6
+ authors:
7
+ - Samoilenko Yuri
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-09-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: prometheus-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.0.1
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '2.0'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.0.1
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec_junit_formatter
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: simplecov
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: simplecov-console
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ description: Enchanced File Store for ruby Prometheus library
118
+ email:
119
+ - kinnalru@gmail.com
120
+ executables: []
121
+ extensions: []
122
+ extra_rdoc_files: []
123
+ files:
124
+ - LICENSE
125
+ - README.md
126
+ - lib/prometheus-enumerated-store.rb
127
+ - lib/prometheus/enumerated-store.rb
128
+ - lib/prometheus/enumerated_store.rb
129
+ - lib/prometheus/enumerated_store/pid_enumerator.rb
130
+ - lib/prometheus/enumerated_store/store.rb
131
+ - lib/prometheus/enumerated_store/version.rb
132
+ - lib/prometheus_enumerated_store.rb
133
+ homepage: https://github.com/RnD-Soft/prometheus_enumerated_store
134
+ licenses:
135
+ - MIT
136
+ metadata: {}
137
+ post_install_message:
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubygems_version: 3.4.10
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: Enchanced File Store for ruby Prometheus library
156
+ test_files: []