cz_system_info 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +18 -0
- data/.gitignore +8 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/cz_system_info.gemspec +36 -0
- data/lib/cz_system_info/cpu.rb +167 -0
- data/lib/cz_system_info/filesystem/constants.rb +72 -0
- data/lib/cz_system_info/filesystem/functions.rb +75 -0
- data/lib/cz_system_info/filesystem/structs.rb +216 -0
- data/lib/cz_system_info/filesystem.rb +450 -0
- data/lib/cz_system_info/memory.rb +66 -0
- data/lib/cz_system_info/uptime.rb +222 -0
- data/lib/cz_system_info/version.rb +5 -0
- data/lib/cz_system_info.rb +12 -0
- metadata +78 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The CzSystemInfo module serves as a namespace only.
|
4
|
+
module CzSystemInfo
|
5
|
+
# The Memory module provides various functions that return information
|
6
|
+
# regarding the memory on your system.
|
7
|
+
module Memory
|
8
|
+
MEMORY_FILE = '/proc/meminfo'
|
9
|
+
MEMINFO_REGEX = /(.*)?:\s+?(\d+)/.freeze
|
10
|
+
|
11
|
+
private_constant :MEMORY_FILE
|
12
|
+
private_constant :MEMINFO_REGEX
|
13
|
+
|
14
|
+
# Obtain detailed memory information about your host in the form of a hash.
|
15
|
+
# Note that the exact nature of this hash is largely dependent on your
|
16
|
+
# operating system.
|
17
|
+
#
|
18
|
+
def memory
|
19
|
+
hash = {}
|
20
|
+
|
21
|
+
File.foreach(MEMORY_FILE) do |line|
|
22
|
+
key, value = MEMINFO_REGEX.match(line.chomp).captures
|
23
|
+
hash[key] = value.to_i
|
24
|
+
end
|
25
|
+
|
26
|
+
hash
|
27
|
+
end
|
28
|
+
|
29
|
+
# Total memory in bytes. By default this is only physical memory, but
|
30
|
+
# if the +extended+ option is set to true, then swap memory is included
|
31
|
+
# as part of the total.
|
32
|
+
#
|
33
|
+
def total(extended: false)
|
34
|
+
hash = memory
|
35
|
+
extended ? (hash['MemTotal'] + hash['SwapTotal']) * 1024 : hash['MemTotal'] * 1024
|
36
|
+
end
|
37
|
+
|
38
|
+
# The memory currently available, in bytes. By default this is only
|
39
|
+
# physical memory, but if the +extended+ option is set to true, then free
|
40
|
+
# swap memory is also included.
|
41
|
+
#
|
42
|
+
def free(extended: false)
|
43
|
+
hash = memory
|
44
|
+
extended ? (hash['MemFree'] + hash['SwapFree']) * 1024 : hash['MemFree'] * 1024
|
45
|
+
end
|
46
|
+
|
47
|
+
# The memory, in bytes, currently in use. By default this is only
|
48
|
+
# physical memory, but if the +extended+ option is set to true then
|
49
|
+
# swap is included in the calculation.
|
50
|
+
#
|
51
|
+
def used(extended: false)
|
52
|
+
hash = memory
|
53
|
+
(total(extended: extended) - free(extended: extended) - hash['Buffers'] - hash['Cached'] - hash['Slab']) * 1024
|
54
|
+
end
|
55
|
+
|
56
|
+
# A number between 0 and 100 that specifies the approximate percentage of
|
57
|
+
# memory that is in use. If the +extended+ option is set to true then
|
58
|
+
# swap memory is included in the calculation.
|
59
|
+
#
|
60
|
+
def load(extended: false)
|
61
|
+
(used(extended: extended) / total(extended: extended).to_f).round(2) * 100
|
62
|
+
end
|
63
|
+
|
64
|
+
module_function :memory, :total, :free, :used, :load
|
65
|
+
end # Memory
|
66
|
+
end # CzSystemInfo
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
# The CzSystemInfo module serves as a namespace only.
|
6
|
+
module CzSystemInfo
|
7
|
+
# The Uptime class encapsulates various bits of information regarding your
|
8
|
+
# system's uptime, including boot time.
|
9
|
+
class Uptime
|
10
|
+
extend FFI::Library
|
11
|
+
ffi_lib FFI::Library::LIBC
|
12
|
+
|
13
|
+
# Error typically raised in one of the Uptime methods should fail.
|
14
|
+
class Error < StandardError; end
|
15
|
+
|
16
|
+
# Hit this issue on Linux, not sure why
|
17
|
+
begin
|
18
|
+
find_type(:clock_t)
|
19
|
+
rescue TypeError
|
20
|
+
typedef(:long, :clock_t)
|
21
|
+
end
|
22
|
+
|
23
|
+
attach_function :strerror, [:int], :string
|
24
|
+
attach_function :sysconf, [:int], :long
|
25
|
+
attach_function :time, [:pointer], :time_t
|
26
|
+
attach_function :times, [:pointer], :clock_t
|
27
|
+
|
28
|
+
private_class_method :strerror, :sysconf, :time, :times, :new
|
29
|
+
|
30
|
+
begin
|
31
|
+
attach_function :sysctl, %i[pointer uint pointer pointer pointer size_t], :int
|
32
|
+
private_class_method :sysctl
|
33
|
+
rescue FFI::NotFoundError
|
34
|
+
attach_function :setutxent, [], :void
|
35
|
+
attach_function :getutxent, [], :pointer
|
36
|
+
attach_function :endutxent, [], :void
|
37
|
+
private_class_method :setutxent, :getutxent, :endutxent
|
38
|
+
end
|
39
|
+
|
40
|
+
CTL_KERN = 1 # Kernel
|
41
|
+
KERN_BOOTTIME = 21 # Time kernel was booted
|
42
|
+
TICKS = 100 # Ticks per second (TODO: use sysconf)
|
43
|
+
BOOT_TIME = 2 # Boot time
|
44
|
+
|
45
|
+
private_constant :CTL_KERN
|
46
|
+
private_constant :KERN_BOOTTIME
|
47
|
+
private_constant :TICKS
|
48
|
+
private_constant :BOOT_TIME
|
49
|
+
|
50
|
+
class Tms < FFI::Struct
|
51
|
+
layout(
|
52
|
+
:tms_utime, :clock_t,
|
53
|
+
:tms_stime, :clock_t,
|
54
|
+
:tms_cutime, :clock_t,
|
55
|
+
:tms_cstime, :clock_t
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
private_constant :Tms
|
60
|
+
|
61
|
+
class Timeval < FFI::Struct
|
62
|
+
layout(
|
63
|
+
:tv_sec, :long,
|
64
|
+
:tv_usec, :long
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
private_constant :Timeval
|
69
|
+
|
70
|
+
class ExitStatus < FFI::Struct
|
71
|
+
layout(
|
72
|
+
:e_termination, :short,
|
73
|
+
:e_exit, :short
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
private_constant :ExitStatus
|
78
|
+
|
79
|
+
class Utmpx < FFI::Struct
|
80
|
+
layout(
|
81
|
+
:ut_user, [:char, 32],
|
82
|
+
:ut_id, [:char, 4],
|
83
|
+
:ut_line, [:char, 32],
|
84
|
+
:ut_pid, :pid_t,
|
85
|
+
:ut_type, :short,
|
86
|
+
:ut_exit, ExitStatus,
|
87
|
+
:ut_tv, Timeval,
|
88
|
+
:ut_session, :int,
|
89
|
+
:padding, [:int, 5],
|
90
|
+
:ut_host, [:char, 257]
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
private_constant :Utmpx
|
95
|
+
|
96
|
+
# Returns a Time object indicating the time the system was last booted.
|
97
|
+
#
|
98
|
+
# Example:
|
99
|
+
#
|
100
|
+
# CzSystemInfo::Uptime.boot_time # => Mon Jul 13 06:08:25 -0600 2009
|
101
|
+
#
|
102
|
+
def self.boot_time
|
103
|
+
if RbConfig::CONFIG['host_os'] =~ /linux/i
|
104
|
+
Time.now - seconds
|
105
|
+
elsif respond_to?(:sysctl, true)
|
106
|
+
tv = Timeval.new
|
107
|
+
mib = FFI::MemoryPointer.new(:int, 2).write_array_of_int([CTL_KERN, KERN_BOOTTIME])
|
108
|
+
size = FFI::MemoryPointer.new(:long, 1).write_int(tv.size)
|
109
|
+
|
110
|
+
if sysctl(mib, 2, tv, size, nil, 0) != 0
|
111
|
+
raise SystemCallError, "sysctl function failed: #{strerror(FFI.errno)}"
|
112
|
+
end
|
113
|
+
|
114
|
+
Time.at(tv[:tv_sec], tv[:tv_usec])
|
115
|
+
else
|
116
|
+
begin
|
117
|
+
setutxent()
|
118
|
+
while ent = Utmpx.new(getutxent())
|
119
|
+
if ent[:ut_type] == BOOT_TIME
|
120
|
+
time = Time.at(ent[:ut_tv][:tv_sec], ent[:ut_tv][:tv_usec])
|
121
|
+
break
|
122
|
+
end
|
123
|
+
end
|
124
|
+
ensure
|
125
|
+
endutxent()
|
126
|
+
end
|
127
|
+
time
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns the total number of seconds of uptime.
|
132
|
+
#
|
133
|
+
# Example:
|
134
|
+
#
|
135
|
+
# CzSystemInfo::Uptime.seconds => 118800
|
136
|
+
#
|
137
|
+
def self.seconds
|
138
|
+
if RbConfig::CONFIG['host_os'] =~ /linux/i
|
139
|
+
# rubocop:disable Lint/RescueException
|
140
|
+
begin
|
141
|
+
File.read('/proc/uptime').split.first.to_i
|
142
|
+
rescue Exception => err
|
143
|
+
raise Error, err
|
144
|
+
end
|
145
|
+
# rubocop:enable Lint/RescueException
|
146
|
+
elsif respond_to?(:sysctl, true)
|
147
|
+
tv = Timeval.new
|
148
|
+
mib = FFI::MemoryPointer.new(:int, 2).write_array_of_int([CTL_KERN, KERN_BOOTTIME])
|
149
|
+
size = FFI::MemoryPointer.new(:long, 1).write_int(tv.size)
|
150
|
+
|
151
|
+
if sysctl(mib, 2, tv, size, nil, 0) != 0
|
152
|
+
raise SystemCallError, "sysctl function failed: #{strerror(FFI.errno)}"
|
153
|
+
end
|
154
|
+
|
155
|
+
time(nil) - tv[:tv_sec]
|
156
|
+
else
|
157
|
+
tms = Tms.new
|
158
|
+
times(tms) / TICKS
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns the total number of minutes of uptime.
|
163
|
+
#
|
164
|
+
# Example:
|
165
|
+
#
|
166
|
+
# CzSystemInfo::Uptime.minutes # => 678
|
167
|
+
#
|
168
|
+
def self.minutes
|
169
|
+
seconds / 60
|
170
|
+
end
|
171
|
+
|
172
|
+
# Returns the total number of hours of uptime.
|
173
|
+
#
|
174
|
+
# Example:
|
175
|
+
#
|
176
|
+
# CzSystemInfo::Uptime.hours # => 31
|
177
|
+
#
|
178
|
+
def self.hours
|
179
|
+
seconds / 3600
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns the total number of days of uptime.
|
183
|
+
#
|
184
|
+
# Example:
|
185
|
+
#
|
186
|
+
# CzSystemInfo::Uptime.days # => 2
|
187
|
+
#
|
188
|
+
def self.days
|
189
|
+
seconds / 86400
|
190
|
+
end
|
191
|
+
|
192
|
+
# Returns the uptime as a colon separated string, including days,
|
193
|
+
# hours, minutes and seconds.
|
194
|
+
#
|
195
|
+
# Example:
|
196
|
+
#
|
197
|
+
# CzSystemInfo::Uptime.uptime # => "1:9:24:57"
|
198
|
+
#
|
199
|
+
def self.uptime
|
200
|
+
secs = seconds
|
201
|
+
days = secs / 86400
|
202
|
+
secs -= days * 86400
|
203
|
+
hours = secs / 3600
|
204
|
+
secs -= hours * 3600
|
205
|
+
mins = secs / 60
|
206
|
+
secs -= mins * 60
|
207
|
+
|
208
|
+
"#{days}:#{hours}:#{mins}:#{secs}"
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns the uptime as a four element array, including days, hours,
|
212
|
+
# minutes and seconds.
|
213
|
+
#
|
214
|
+
# Example:
|
215
|
+
#
|
216
|
+
# CzSystemInfo::Uptime.dhms # => [1,9,24,57]
|
217
|
+
#
|
218
|
+
def self.dhms
|
219
|
+
uptime.split(':')
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "cz_system_info/version"
|
4
|
+
require_relative "cz_system_info/cpu"
|
5
|
+
require_relative "cz_system_info/filesystem"
|
6
|
+
require_relative "cz_system_info/memory"
|
7
|
+
require_relative "cz_system_info/uptime"
|
8
|
+
|
9
|
+
module CzSystemInfo
|
10
|
+
class Error < StandardError; end
|
11
|
+
# Your code goes here...
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cz_system_info
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- hayate
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-10-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
27
|
+
description: Move Daniel Berger's sys code into one.
|
28
|
+
email:
|
29
|
+
- holdstock@yeah.net
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".github/workflows/main.yml"
|
35
|
+
- ".gitignore"
|
36
|
+
- Gemfile
|
37
|
+
- LICENSE.txt
|
38
|
+
- README.md
|
39
|
+
- Rakefile
|
40
|
+
- bin/console
|
41
|
+
- bin/setup
|
42
|
+
- cz_system_info.gemspec
|
43
|
+
- lib/cz_system_info.rb
|
44
|
+
- lib/cz_system_info/cpu.rb
|
45
|
+
- lib/cz_system_info/filesystem.rb
|
46
|
+
- lib/cz_system_info/filesystem/constants.rb
|
47
|
+
- lib/cz_system_info/filesystem/functions.rb
|
48
|
+
- lib/cz_system_info/filesystem/structs.rb
|
49
|
+
- lib/cz_system_info/memory.rb
|
50
|
+
- lib/cz_system_info/uptime.rb
|
51
|
+
- lib/cz_system_info/version.rb
|
52
|
+
homepage: https://github.com/hinagiku/cz_system_info
|
53
|
+
licenses:
|
54
|
+
- MIT
|
55
|
+
metadata:
|
56
|
+
homepage_uri: https://github.com/hinagiku/cz_system_info
|
57
|
+
source_code_uri: https://github.com/hinagiku/cz_system_info
|
58
|
+
changelog_uri: https://github.com/hinagiku/cz_system_info
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 2.3.0
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubygems_version: 3.2.3
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Move Daniel Berger's sys code into one.
|
78
|
+
test_files: []
|