cz_system_info 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CzSystemInfo
4
+ VERSION = "0.1.0"
5
+ 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: []