cz_system_info 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|