From 7e3f467059abdec38e802812236d37d3687e2b61 Mon Sep 17 00:00:00 2001 From: Schneems Date: Mon, 22 Jul 2024 15:19:45 -0500 Subject: [PATCH 1/4] Fix Ruby 3.4.0 deprecation warning: ``` /Users/rschneeman/.gem/ruby/3.3.1/gems/get_process_mem-0.2.7/lib/get_process_mem.rb:2: warning: bigdecimal was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add bigdecimal to your Gemfile or gemspec. Also contact author of get_process_mem-0.2.7 to add bigdecimal into its gemspec. ``` --- CHANGELOG.md | 2 ++ get_process_mem.gemspec | 1 + 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d03f3c0..a0371f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## HEAD (unreleased) +- Add `bigdecimal` as a dependency. + ## 0.2.7 - Native (faster) support for returning memory from different PIDs on mac (https://github.com/schneems/get_process_mem/pull/42) diff --git a/get_process_mem.gemspec b/get_process_mem.gemspec index 96e9142..854507b 100644 --- a/get_process_mem.gemspec +++ b/get_process_mem.gemspec @@ -19,6 +19,7 @@ Gem::Specification.new do |gem| gem.require_paths = ["lib"] gem.add_dependency "ffi", "~> 1.0" + gem.add_dependency "bigdecimal", ">= 2.0" gem.add_development_dependency "sys-proctable", "~> 1.2" gem.add_development_dependency "rake", "~> 12" From 72cd215d292ccd9a529b0c5e3af24ca40e026ca9 Mon Sep 17 00:00:00 2001 From: Schneems Date: Mon, 22 Jul 2024 15:22:05 -0500 Subject: [PATCH 2/4] Add CI and standard linting --- .github/workflows/ci.yml | 34 ++++++++++++++++++++++++++++++++++ .standard.yml | 1 + CHANGELOG.md | 1 + Gemfile | 2 ++ README.md | 4 ++-- get_process_mem.gemspec | 2 ++ 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .standard.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..366a053 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + - push + - pull_request + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + ruby: + - 2.5 + - 2.6 + - 2.7 + - 3.0 + - 3.1 + - 3.2 + - 3.3 + - head + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Ruby linting + run: bundle exec standardrb + - name: test + run: bundle exec rake test + continue-on-error: ${{ matrix.ruby == 'head' }} diff --git a/.standard.yml b/.standard.yml new file mode 100644 index 0000000..33ea7ae --- /dev/null +++ b/.standard.yml @@ -0,0 +1 @@ +ruby_version: 2.5 diff --git a/CHANGELOG.md b/CHANGELOG.md index a0371f9..4a920d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## HEAD (unreleased) +- Minimum Ruby version is now Ruby 2.5 - Add `bigdecimal` as a dependency. ## 0.2.7 diff --git a/Gemfile b/Gemfile index dd02ade..31ee3f3 100644 --- a/Gemfile +++ b/Gemfile @@ -2,3 +2,5 @@ source "https://rubygems.org" gem 'sys-proctable' gemspec + +gem "standard" diff --git a/README.md b/README.md index b5627d1..02d7b88 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Get Process Memory -[![Build Status](https://travis-ci.org/schneems/get_process_mem.svg?branch=master)](https://travis-ci.org/schneems/get_process_mem) -[![Help Contribute to Open Source](https://www.codetriage.com/schneems/get_process_mem/badges/users.svg)](https://www.codetriage.com/schneems/get_process_mem) +[![CI](https://github.com/zombocom/get_process_mem/actions/workflows/ci.yml/badge.svg)](https://github.com/zombocom/get_process_mem/actions/workflows/ci.yml) +[![Help Contribute to Open Source](https://www.codetriage.com/zombocom/get_process_mem/badges/users.svg)](https://www.codetriage.com/zombocom/get_process_mem) Do you need to get the memory usage of a process? Great because this library does that. diff --git a/get_process_mem.gemspec b/get_process_mem.gemspec index 854507b..bb01a0f 100644 --- a/get_process_mem.gemspec +++ b/get_process_mem.gemspec @@ -18,6 +18,8 @@ Gem::Specification.new do |gem| gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) gem.require_paths = ["lib"] + gem.required_ruby_version = '>= 2.5' + gem.add_dependency "ffi", "~> 1.0" gem.add_dependency "bigdecimal", ">= 2.0" From 8573b6d8d1288894543e1de8d19fd767d2922d32 Mon Sep 17 00:00:00 2001 From: Schneems Date: Mon, 22 Jul 2024 15:30:34 -0500 Subject: [PATCH 3/4] Apply standard auto formatting Adjust named regex group ``` $ be standardrb --fix standard: Use Ruby Standard Style (https://github.com/standardrb/standard) Rakefile:8:1: Lint/UselessAssignment: Useless assignment to variable - `test_task`. lib/get_process_mem.rb:99:18: Lint/MixedRegexpCaptureTypes: Do not mix named captures and numbered captures in a Regexp literal. ``` --- Gemfile | 2 +- Rakefile | 18 +++++----- get_process_mem.gemspec | 28 ++++++++-------- lib/get_process_mem.rb | 47 +++++++++++++------------- lib/get_process_mem/darwin.rb | 62 ++++++++++++++++------------------- test/get_process_mem_test.rb | 34 +++++++++---------- test/test_helper.rb | 6 ++-- 7 files changed, 95 insertions(+), 102 deletions(-) diff --git a/Gemfile b/Gemfile index 31ee3f3..b27d851 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source "https://rubygems.org" -gem 'sys-proctable' +gem "sys-proctable" gemspec diff --git a/Rakefile b/Rakefile index 82744d2..4538da4 100644 --- a/Rakefile +++ b/Rakefile @@ -1,15 +1,13 @@ -# encoding: UTF-8 +require "bundler/gem_tasks" -require 'bundler/gem_tasks' +require "rake" +require "rake/testtask" -require 'rake' -require 'rake/testtask' +task default: [:test] -task :default => [:test] - -test_task = Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.libs << 'test' - t.pattern = 'test/**/*_test.rb' +Rake::TestTask.new(:test) do |t| + t.libs << "lib" + t.libs << "test" + t.pattern = "test/**/*_test.rb" t.verbose = false end diff --git a/get_process_mem.gemspec b/get_process_mem.gemspec index bb01a0f..5d980db 100644 --- a/get_process_mem.gemspec +++ b/get_process_mem.gemspec @@ -1,24 +1,22 @@ -# -*- encoding: utf-8 -*- -lib = File.expand_path('../lib', __FILE__) +lib = File.expand_path("../lib", __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'get_process_mem/version' +require "get_process_mem/version" Gem::Specification.new do |gem| - gem.name = "get_process_mem" - gem.version = GetProcessMem::VERSION - gem.authors = ["Richard Schneeman"] - gem.email = ["richard.schneeman+rubygems@gmail.com"] - gem.description = %q{ Get memory usage of a process in Ruby } - gem.summary = %q{ Use GetProcessMem to find out the amount of RAM used by any process } - gem.homepage = "https://github.com/schneems/get_process_mem" - gem.license = "MIT" + gem.name = "get_process_mem" + gem.version = GetProcessMem::VERSION + gem.authors = ["Richard Schneeman"] + gem.email = ["richard.schneeman+rubygems@gmail.com"] + gem.description = " Get memory usage of a process in Ruby " + gem.summary = " Use GetProcessMem to find out the amount of RAM used by any process " + gem.homepage = "https://github.com/schneems/get_process_mem" + gem.license = "MIT" - gem.files = `git ls-files`.split($/) - gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } - gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.files = `git ls-files`.split($/) + gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) } gem.require_paths = ["lib"] - gem.required_ruby_version = '>= 2.5' + gem.required_ruby_version = ">= 2.5" gem.add_dependency "ffi", "~> 1.0" gem.add_dependency "bigdecimal", ">= 2.0" diff --git a/lib/get_process_mem.rb b/lib/get_process_mem.rb index 67aaf25..957b192 100644 --- a/lib/get_process_mem.rb +++ b/lib/get_process_mem.rb @@ -1,5 +1,5 @@ -require 'pathname' -require 'bigdecimal' +require "pathname" +require "bigdecimal" # Cribbed from Unicorn Worker Killer, thanks! class GetProcessMem @@ -14,15 +14,15 @@ class GetProcessMem KB_TO_BYTE = number_to_bigdecimal 1024 # 2**10 = 1024 MB_TO_BYTE = number_to_bigdecimal 1_048_576 # 1024**2 = 1_048_576 GB_TO_BYTE = number_to_bigdecimal 1_073_741_824 # 1024**3 = 1_073_741_824 - CONVERSION = { "kb" => KB_TO_BYTE, "mb" => MB_TO_BYTE, "gb" => GB_TO_BYTE } - ROUND_UP = number_to_bigdecimal "0.5" + CONVERSION = {"kb" => KB_TO_BYTE, "mb" => MB_TO_BYTE, "gb" => GB_TO_BYTE} + ROUND_UP = number_to_bigdecimal "0.5" attr_reader :pid RUNS_ON_WINDOWS = Gem.win_platform? if RUNS_ON_WINDOWS begin - require 'sys/proctable' + require "sys/proctable" rescue LoadError => e message = "Please add `sys-proctable` to your Gemfile for windows machines\n" message << e.message @@ -31,13 +31,13 @@ class GetProcessMem include Sys end - RUNS_ON_DARWIN = Gem.platforms.detect do |p| - p.is_a?(Gem::Platform) && p.os == 'darwin' - end + RUNS_ON_DARWIN = Gem.platforms.detect do |p| + p.is_a?(Gem::Platform) && p.os == "darwin" + end if RUNS_ON_DARWIN begin - require 'get_process_mem/darwin' + require "get_process_mem/darwin" rescue LoadError => e message = "Please add `ffi` to your Gemfile for darwin (macos) machines\n" message << e.message @@ -46,10 +46,10 @@ class GetProcessMem end def initialize(pid = Process.pid) - @status_file = Pathname.new "/proc/#{pid}/status" + @status_file = Pathname.new "/proc/#{pid}/status" @process_file = Pathname.new "/proc/#{pid}/smaps" - @pid = pid - @linux = @status_file.exist? + @pid = pid + @linux = @status_file.exist? end def linux? @@ -57,32 +57,33 @@ def linux? end def bytes - memory = linux_status_memory if linux? + memory = linux_status_memory if linux? memory ||= darwin_memory if RUNS_ON_DARWIN memory ||= ps_memory + memory end def kb(b = bytes) - (b/KB_TO_BYTE).to_f + (b / KB_TO_BYTE).to_f end def mb(b = bytes) - (b/MB_TO_BYTE).to_f + (b / MB_TO_BYTE).to_f end def gb(b = bytes) - (b/GB_TO_BYTE).to_f + (b / GB_TO_BYTE).to_f end def inspect b = bytes - "#<#{self.class}:0x%08x @mb=#{ mb b } @gb=#{ gb b } @kb=#{ kb b } @bytes=#{b}>" % (object_id * 2) + "#<#{self.class}:0x%08x @mb=#{mb b} @gb=#{gb b} @kb=#{kb b} @bytes=#{b}>" % (object_id * 2) end # linux stores memory info in a file "/proc/#{pid}/status" # If it's available it uses less resources than shelling out to ps def linux_status_memory(file = @status_file) - line = file.each_line.detect {|line| line.start_with? 'VmRSS'.freeze } + line = file.each_line.detect { |line| line.start_with? "VmRSS".freeze } return unless line return unless (_name, value, unit = line.split(nil)).length == 3 CONVERSION[unit.downcase!] * value.to_i @@ -92,13 +93,13 @@ def linux_status_memory(file = @status_file) # linux stores detailed memory info in a file "/proc/#{pid}/smaps" def linux_memory(file = @process_file) - lines = file.each_line.select {|line| line.match(/^Rss/) } + lines = file.each_line.select { |line| line.match(/^Rss/) } return if lines.empty? lines.reduce(0) do |sum, line| - line.match(/(?(\d*\.{0,1}\d+))\s+(?\w\w)/) do |m| + line.match(/(?\d*\.{0,1}\d+)\s+(?\w\w)/) do |m| value = number_to_bigdecimal(m[:value]) + ROUND_UP - unit = m[:unit].downcase - sum += CONVERSION[unit] * value + unit = m[:unit].downcase + sum += CONVERSION[unit] * value end sum end @@ -114,7 +115,7 @@ def ps_memory number_to_bigdecimal(size) else mem = `ps -o rss= -p #{pid}` - KB_TO_BYTE * number_to_bigdecimal(mem == "" ? 0 : mem) + KB_TO_BYTE * number_to_bigdecimal((mem == "") ? 0 : mem) end end diff --git a/lib/get_process_mem/darwin.rb b/lib/get_process_mem/darwin.rb index 111f734..ebda45a 100644 --- a/lib/get_process_mem/darwin.rb +++ b/lib/get_process_mem/darwin.rb @@ -1,46 +1,42 @@ -require 'ffi' +require "ffi" class GetProcessMem class Darwin extend FFI::Library - ffi_lib 'proc' - + ffi_lib "proc" class TaskInfo < FFI::Struct layout :pti_virtual_size, :uint64, - :pti_resident_size, :uint64, - :pti_total_user, :uint64, - :pti_total_system, :uint64, - :pti_threads_user, :uint64, - :pti_threads_system, :uint64, - :pti_policy, :int32, - :pti_faults, :int32, - :pti_pageins, :int32, - :pti_cow_faults, :int32, - :pti_messages_sent, :int32, - :pti_messages_received, :int32, - :pti_syscalls_mach, :int32, - :pti_syscalls_unix, :int32, - :pti_csw, :int32, - :pti_threadnum, :int32, - :pti_numrunning, :int32, - :pti_priority, :int32 - + :pti_resident_size, :uint64, + :pti_total_user, :uint64, + :pti_total_system, :uint64, + :pti_threads_user, :uint64, + :pti_threads_system, :uint64, + :pti_policy, :int32, + :pti_faults, :int32, + :pti_pageins, :int32, + :pti_cow_faults, :int32, + :pti_messages_sent, :int32, + :pti_messages_received, :int32, + :pti_syscalls_mach, :int32, + :pti_syscalls_unix, :int32, + :pti_csw, :int32, + :pti_threadnum, :int32, + :pti_numrunning, :int32, + :pti_priority, :int32 end - attach_function :proc_pidinfo, - [ - :int, #pid - :int, # flavour - :uint64, #arg, not needed for this selector - TaskInfo.by_ref, #output buffer - :int, #size of buffer - ], - :int - + [ + :int, # pid + :int, # flavour + :uint64, # arg, not needed for this selector + TaskInfo.by_ref, # output buffer + :int # size of buffer + ], + :int - PROC_PIDTASKINFO = 4 #from sys/proc_info.h + PROC_PIDTASKINFO = 4 # from sys/proc_info.h class << self def resident_size(pid) @@ -55,7 +51,7 @@ def get_proc_pidinfo(pid) if result == TaskInfo.size data else - raise SystemCallError.new("proc_pidinfo returned #{result}", FFI.errno); + raise SystemCallError.new("proc_pidinfo returned #{result}", FFI.errno) end end end diff --git a/test/get_process_mem_test.rb b/test/get_process_mem_test.rb index f7b831f..6385828 100644 --- a/test/get_process_mem_test.rb +++ b/test/get_process_mem_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require "test_helper" class GetProcessMemTest < Test::Unit::TestCase def setup @@ -11,14 +11,14 @@ def test_different_pid_returns_different_memory other_mem = GetProcessMem.new(pid) assert @mem.kb > other_mem.kb ensure - Process.kill('TERM', pid) if pid + Process.kill("TERM", pid) if pid Process.wait(pid) if pid end def test_seems_to_work - assert @mem.kb > 0 - assert @mem.mb > 0 - assert @mem.gb > 0 + assert @mem.kb > 0 + assert @mem.mb > 0 + assert @mem.gb > 0 assert @mem.bytes > 0 end @@ -36,26 +36,26 @@ def test_linux_status def test_conversions bytes = 0 delta = BigDecimal("0.0000001") - assert_in_delta 0.0, @mem.kb(bytes), delta - assert_in_delta 0.0, @mem.mb(bytes), delta - assert_in_delta 0.0, @mem.gb(bytes), delta + assert_in_delta 0.0, @mem.kb(bytes), delta + assert_in_delta 0.0, @mem.mb(bytes), delta + assert_in_delta 0.0, @mem.gb(bytes), delta # kb bytes = 1024 - assert_in_delta 1.0, @mem.kb(bytes), delta - assert_in_delta 0.0009765625, @mem.mb(bytes), delta - assert_in_delta 9.5367431640625e-07, @mem.gb(bytes), delta + assert_in_delta 1.0, @mem.kb(bytes), delta + assert_in_delta 0.0009765625, @mem.mb(bytes), delta + assert_in_delta 9.5367431640625e-07, @mem.gb(bytes), delta # mb bytes = 1_048_576 - assert_in_delta 1024.0, @mem.kb(bytes), delta - assert_in_delta 1.0, @mem.mb(bytes), delta - assert_in_delta 0.0009765625, @mem.gb(bytes), delta + assert_in_delta 1024.0, @mem.kb(bytes), delta + assert_in_delta 1.0, @mem.mb(bytes), delta + assert_in_delta 0.0009765625, @mem.gb(bytes), delta # gb bytes = 1_073_741_824 - assert_in_delta 1048576.0, @mem.kb(bytes), delta - assert_in_delta 1024.0, @mem.mb(bytes), delta - assert_in_delta 1.0, @mem.gb(bytes), delta + assert_in_delta 1048576.0, @mem.kb(bytes), delta + assert_in_delta 1024.0, @mem.mb(bytes), delta + assert_in_delta 1.0, @mem.gb(bytes), delta end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 95cfc4a..0a0d288 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,10 +1,10 @@ Bundler.require -require 'get_process_mem' -require 'test/unit' +require "get_process_mem" +require "test/unit" def fixture_path(name = nil) path = Pathname.new(File.expand_path("../fixtures", __FILE__)) return path.join(name) if name path -end \ No newline at end of file +end From e8382f43084bce54b0420ee9b2b6819de88a1738 Mon Sep 17 00:00:00 2001 From: Schneems Date: Mon, 22 Jul 2024 15:34:06 -0500 Subject: [PATCH 4/4] Minimum is now 2.6 Getting an error with 2.5 on CI ``` Your RubyGems version (2.7.6.3) has a bug that prevents `required_ruby_version` from working for Bundler. Any scripts that use `gem install bundler` will break as soon as Bundler drops support for your Ruby version. Please upgrade RubyGems to avoid future breakage and silence this warning by running `gem update --system 3.2.3` ``` It's easier to rev the version than to work around the problem --- .github/workflows/ci.yml | 1 - .standard.yml | 2 +- CHANGELOG.md | 2 +- get_process_mem.gemspec | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 366a053..a320273 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,6 @@ jobs: fail-fast: false matrix: ruby: - - 2.5 - 2.6 - 2.7 - 3.0 diff --git a/.standard.yml b/.standard.yml index 33ea7ae..3af9da5 100644 --- a/.standard.yml +++ b/.standard.yml @@ -1 +1 @@ -ruby_version: 2.5 +ruby_version: 2.6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a920d0..4a41647 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## HEAD (unreleased) -- Minimum Ruby version is now Ruby 2.5 +- Minimum Ruby version is now Ruby 2.6 - Add `bigdecimal` as a dependency. ## 0.2.7 diff --git a/get_process_mem.gemspec b/get_process_mem.gemspec index 5d980db..e5b97b0 100644 --- a/get_process_mem.gemspec +++ b/get_process_mem.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |gem| gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) } gem.require_paths = ["lib"] - gem.required_ruby_version = ">= 2.5" + gem.required_ruby_version = ">= 2.6" gem.add_dependency "ffi", "~> 1.0" gem.add_dependency "bigdecimal", ">= 2.0"