Skip to content

Commit

Permalink
Merge pull request #50 from zombocom/schneems/update-deps
Browse files Browse the repository at this point in the history
Update dependencies and housekeeping
  • Loading branch information
schneems authored Jul 22, 2024
2 parents 2897a5a + e8382f4 commit 1697131
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 103 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
- push
- pull_request

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby:
- 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' }}
1 change: 1 addition & 0 deletions .standard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ruby_version: 2.6
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## HEAD (unreleased)

- Minimum Ruby version is now Ruby 2.6
- 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)
Expand Down
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
source "https://rubygems.org"
gem 'sys-proctable'
gem "sys-proctable"

gemspec

gem "standard"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
18 changes: 8 additions & 10 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -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
29 changes: 15 additions & 14 deletions get_process_mem.gemspec
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
# -*- 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 = ["[email protected]"]
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 = ["[email protected]"]
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.6"

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"
Expand Down
47 changes: 24 additions & 23 deletions lib/get_process_mem.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require 'pathname'
require 'bigdecimal'
require "pathname"
require "bigdecimal"

# Cribbed from Unicorn Worker Killer, thanks!
class GetProcessMem
Expand All @@ -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
Expand All @@ -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
Expand All @@ -46,43 +46,44 @@ 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?
@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
Expand All @@ -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(/(?<value>(\d*\.{0,1}\d+))\s+(?<unit>\w\w)/) do |m|
line.match(/(?<value>\d*\.{0,1}\d+)\s+(?<unit>\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
Expand All @@ -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

Expand Down
62 changes: 29 additions & 33 deletions lib/get_process_mem/darwin.rb
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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
Expand Down
Loading

0 comments on commit 1697131

Please sign in to comment.