apple-system-logger 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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGES.md +2 -0
- data/MANIFEST.md +11 -0
- data/README.md +51 -0
- data/Rakefile +27 -0
- data/apple-system-logger.gemspec +33 -0
- data/certs/djberg96_pub.pem +26 -0
- data/lib/apple-system-logger.rb +1 -0
- data/lib/apple/system/logger.rb +288 -0
- data/lib/apple/system/logger/constants.rb +50 -0
- data/lib/apple/system/logger/functions.rb +29 -0
- data/spec/apple-system-logger_spec.rb +115 -0
- metadata +138 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ba6fde620c359b96d2b984227aa7b22088a997366138e36652761f4df26f293b
|
4
|
+
data.tar.gz: d00f1c2f28139714f6ce39f2d582f5e4b19d34bad4bc3b87f10a0b1adb6b1bc5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 939ff1063daba3109af937b97110af11cacff4e0f3bae322cf9da146f89b5f54b73cba7a23452af7c69c9593fa27885f331726465baf02050c0daacb33244041
|
7
|
+
data.tar.gz: afa1977b52a308db5d7ab84c27e50d0aa5458983611b2c70de8c82f584c0f35f84a2792916c8eafe79befed3db95d49a16fcae970c3c05087095c419637ba10f
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/CHANGES.md
ADDED
data/MANIFEST.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
* CHANGES.md
|
2
|
+
* MANIFEST.md
|
3
|
+
* Rakefile
|
4
|
+
* README.md
|
5
|
+
* apple-system-logger.gemspec
|
6
|
+
* certs/djberg96_pub.pem
|
7
|
+
* lib/apple-system-logger.rb
|
8
|
+
* lib/apple/system/logger.rb
|
9
|
+
* lib/apple/system/logger/constants.rb
|
10
|
+
* lib/apple/system/logger/functions.rb
|
11
|
+
* spec/apple-system-logger_spec.rb
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
## apple-system-logger
|
2
|
+
A Ruby interface for the Apple system logger.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
gem install apple-system-logger
|
6
|
+
|
7
|
+
## Synopsis
|
8
|
+
```
|
9
|
+
require 'apple-system-logger'
|
10
|
+
|
11
|
+
# With defaults
|
12
|
+
log = Apple::System::Logger.new
|
13
|
+
log.warn("This is a warning")
|
14
|
+
|
15
|
+
# With all possible options, including multicast to $stderr
|
16
|
+
log = Apple::System::Logger.new(
|
17
|
+
facility: 'com.apple.console',
|
18
|
+
level: Apple::System::Logger::ASL_LEVEL_WARNING,
|
19
|
+
progname: 'myprog',
|
20
|
+
logdev: $stderr
|
21
|
+
)
|
22
|
+
|
23
|
+
log.warn("This is also a warning")
|
24
|
+
|
25
|
+
# Search for logs
|
26
|
+
log = Apple::System::Logger.new
|
27
|
+
results = log.search(:sender => 'bootlog', :level => 5)
|
28
|
+
|
29
|
+
# Always do this when finished, or use the block version of the constructor
|
30
|
+
log.close
|
31
|
+
```
|
32
|
+
|
33
|
+
## License
|
34
|
+
Apache-2.0
|
35
|
+
|
36
|
+
## Known Issues
|
37
|
+
It does not seem that you can multicast to any fileno except stdout and
|
38
|
+
stderr. I am not sure if this is by design, or if I am missing something,
|
39
|
+
because the API does not explicitly forbid other file descriptors, nor
|
40
|
+
does it raise an error.
|
41
|
+
|
42
|
+
## Copyright
|
43
|
+
(C) 2019 Daniel J. Berger, All Rights Reserved
|
44
|
+
|
45
|
+
## Warranty
|
46
|
+
This package is provided "as is" and without any express or
|
47
|
+
implied warranties, including, without limitation, the implied
|
48
|
+
warranties of merchantability and fitness for a particular purpose.
|
49
|
+
|
50
|
+
## Author
|
51
|
+
Daniel J. Berger
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
include RbConfig
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
CLEAN.include('**/*.gem', '**/*.rbc', '**/*.rbx')
|
10
|
+
|
11
|
+
namespace 'gem' do
|
12
|
+
desc "Create the apple-system-logger gem"
|
13
|
+
task :create => [:clean] do
|
14
|
+
require 'rubygems/package'
|
15
|
+
spec = eval(IO.read('apple-system-logger.gemspec'))
|
16
|
+
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
17
|
+
Gem::Package.build(spec, true)
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Install the apple-system-logger gem"
|
21
|
+
task :install => [:create] do
|
22
|
+
file = Dir["*.gem"].first
|
23
|
+
sh "gem install -l #{file}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
task :default => :spec
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'apple-system-logger'
|
5
|
+
spec.version = '0.1.0'
|
6
|
+
spec.author = 'Daniel J. Berger'
|
7
|
+
spec.email = 'djberg96@gmail.com'
|
8
|
+
spec.license = 'Apache-2.0'
|
9
|
+
spec.homepage = 'https://github.com/djberg96/apple-system-logger'
|
10
|
+
spec.summary = 'A Ruby interface for the Apple System Logger'
|
11
|
+
spec.test_file = 'spec/apple-system-logger_spec.rb'
|
12
|
+
spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
13
|
+
spec.cert_chain = ['certs/djberg96_pub.pem']
|
14
|
+
|
15
|
+
spec.add_dependency('ffi')
|
16
|
+
spec.add_development_dependency('rake')
|
17
|
+
spec.add_development_dependency('rspec')
|
18
|
+
|
19
|
+
spec.metadata = {
|
20
|
+
'homepage_uri' => 'https://github.com/djberg96/apple-system-logger',
|
21
|
+
'bug_tracker_uri' => 'https://github.com/djberg96/apple-system-logger/issues',
|
22
|
+
'changelog_uri' => 'https://github.com/djberg96/apple-system-logger/blob/master/CHANGES',
|
23
|
+
'documentation_uri' => 'https://github.com/djberg96/apple-system-logger/wiki',
|
24
|
+
'source_code_uri' => 'https://github.com/djberg96/apple-system-logger',
|
25
|
+
'wiki_uri' => 'https://github.com/djberg96/apple-system-logger/wiki'
|
26
|
+
}
|
27
|
+
|
28
|
+
spec.description = <<-EOF
|
29
|
+
The apple-system-logger library provides an interface for the Apple System
|
30
|
+
Library. You can both write to, and search, your mac's system logs using
|
31
|
+
this library using an API that is very similar to the stdlib Logger interface.
|
32
|
+
EOF
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIEcDCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MREwDwYDVQQDDAhkamJl
|
3
|
+
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
4
|
+
MB4XDTE4MDMxODE1MjIwN1oXDTI4MDMxNTE1MjIwN1owPzERMA8GA1UEAwwIZGpi
|
5
|
+
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
6
|
+
bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALgfaroVM6CI06cxr0/h
|
7
|
+
A+j+pc8fgpRgBVmHFaFunq28GPC3IvW7Nvc3Y8SnAW7pP1EQIbhlwRIaQzJ93/yj
|
8
|
+
u95KpkP7tA9erypnV7dpzBkzNlX14ACaFD/6pHoXoe2ltBxk3CCyyzx70mTqJpph
|
9
|
+
75IB03ni9a8yqn8pmse+s83bFJOAqddSj009sGPcQO+QOWiNxqYv1n5EHcvj2ebO
|
10
|
+
6hN7YTmhx7aSia4qL/quc4DlIaGMWoAhvML7u1fmo53CYxkKskfN8MOecq2vfEmL
|
11
|
+
iLu+SsVVEAufMDDFMXMJlvDsviolUSGMSNRTujkyCcJoXKYYxZSNtIiyd9etI0X3
|
12
|
+
ctu0uhrFyrMZXCedutvXNjUolD5r9KGBFSWH1R9u2I3n3SAyFF2yzv/7idQHLJJq
|
13
|
+
74BMnx0FIq6fCpu5slAipvxZ3ZkZpEXZFr3cIBtO1gFvQWW7E/Y3ijliWJS1GQFq
|
14
|
+
058qERadHGu1yu1dojmFRo6W2KZvY9al2yIlbkpDrD5MYQIDAQABo3cwdTAJBgNV
|
15
|
+
HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUFZsMapgzJimzsbaBG2Tm8j5e
|
16
|
+
AzgwHQYDVR0RBBYwFIESZGpiZXJnOTZAZ21haWwuY29tMB0GA1UdEgQWMBSBEmRq
|
17
|
+
YmVyZzk2QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAW2tnYixXQtKxgGXq
|
18
|
+
/3iSWG2bLwvxS4go3srO+aRXZHrFUMlJ5W0mCxl03aazxxKTsVVpZD8QZxvK91OQ
|
19
|
+
h9zr9JBYqCLcCVbr8SkmYCi/laxIZxsNE5YI8cC8vvlLI7AMgSfPSnn/Epq1GjGY
|
20
|
+
6L1iRcEDtanGCIvjqlCXO9+BmsnCfEVehqZkQHeYczA03tpOWb6pon2wzvMKSsKH
|
21
|
+
ks0ApVdstSLz1kzzAqem/uHdG9FyXdbTAwH1G4ZPv69sQAFAOCgAqYmdnzedsQtE
|
22
|
+
1LQfaQrx0twO+CZJPcRLEESjq8ScQxWRRkfuh2VeR7cEU7L7KqT10mtUwrvw7APf
|
23
|
+
DYoeCY9KyjIBjQXfbj2ke5u1hZj94Fsq9FfbEQg8ygCgwThnmkTrrKEiMSs3alYR
|
24
|
+
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
25
|
+
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
26
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'apple/system/logger'
|
@@ -0,0 +1,288 @@
|
|
1
|
+
require_relative 'logger/functions'
|
2
|
+
require_relative 'logger/constants'
|
3
|
+
|
4
|
+
module Apple
|
5
|
+
module System
|
6
|
+
class Logger
|
7
|
+
include Apple::System::LoggerFunctions
|
8
|
+
include Apple::System::LoggerConstants
|
9
|
+
|
10
|
+
# The version of this library.
|
11
|
+
VERSION = '0.1.0'.freeze
|
12
|
+
|
13
|
+
# A syslogd facility. The system default is 'user'.
|
14
|
+
attr_reader :facility
|
15
|
+
|
16
|
+
# The logging severity threshold. The default is debug.
|
17
|
+
attr_reader :level
|
18
|
+
|
19
|
+
# The program name, or ident, that becomes the key sender. The default is nil.
|
20
|
+
attr_reader :progname
|
21
|
+
|
22
|
+
# If provided, a file or filehandle that the logger will multicast to. The default is nil.
|
23
|
+
attr_reader :logdev
|
24
|
+
|
25
|
+
# Create and return an Apple::System::Logger instance. The constructor takes a series
|
26
|
+
# of optional arguments:
|
27
|
+
#
|
28
|
+
# * facility
|
29
|
+
# * level
|
30
|
+
# * progname
|
31
|
+
# * logdev
|
32
|
+
#
|
33
|
+
# Note that the logdev only seems to work with $stdout or $stderr, if provided.
|
34
|
+
#
|
35
|
+
# For the severity level, the possible values are:
|
36
|
+
#
|
37
|
+
# * ASL_LEVEL_EMERG
|
38
|
+
# * ASL_LEVEL_ALERT
|
39
|
+
# * ASL_LEVEL_CRIT
|
40
|
+
# * ASL_LEVEL_ERR
|
41
|
+
# * ASL_LEVEL_WARNING
|
42
|
+
# * ASL_LEVEL_NOTICE
|
43
|
+
# * ASL_LEVEL_INFO
|
44
|
+
# * ASL_LEVEL_DEBUG
|
45
|
+
#
|
46
|
+
# You may optionally use a block, which will yield the logger instance and
|
47
|
+
# automatically close itself.
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
#
|
51
|
+
# # Typical
|
52
|
+
# log = Apple::System::Logger.new(facility: 'com.apple.console', progname: 'my-program')
|
53
|
+
# log.warn("Some warning message")
|
54
|
+
#
|
55
|
+
# # Block form
|
56
|
+
# Apple::System::Logger.new(facility: 'com.apple.console', progname: 'my-program') do |log|
|
57
|
+
# log.warn("Some warning message")
|
58
|
+
# end
|
59
|
+
#--
|
60
|
+
# TODO: Add string format support and apply it to messages.
|
61
|
+
#
|
62
|
+
def initialize(**kwargs)
|
63
|
+
@facility = kwargs[:facility]
|
64
|
+
@level = kwargs[:level] || ASL_LEVEL_DEBUG
|
65
|
+
@progname = kwargs[:progname]
|
66
|
+
@logdev = kwargs[:logdev]
|
67
|
+
|
68
|
+
if @logdev || @facility || @progname
|
69
|
+
options = ASL_OPT_NO_DELAY | ASL_OPT_NO_REMOTE
|
70
|
+
@aslclient = asl_open(@progname, @facility, options)
|
71
|
+
|
72
|
+
if @logdev
|
73
|
+
asl_add_log_file(@aslclient, @logdev.fileno)
|
74
|
+
end
|
75
|
+
else
|
76
|
+
@aslclient = nil
|
77
|
+
end
|
78
|
+
|
79
|
+
@aslmsg = asl_new(ASL_TYPE_MSG)
|
80
|
+
asl_set(@aslmsg, ASL_KEY_FACILITY, @facility) if @facility
|
81
|
+
asl_set_filter(@aslclient, @level)
|
82
|
+
|
83
|
+
if block_given?
|
84
|
+
begin
|
85
|
+
yield self
|
86
|
+
ensure
|
87
|
+
close
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Dump a message with no formatting at the current severity level.
|
93
|
+
#
|
94
|
+
def <<(message)
|
95
|
+
asl_log(@aslclient, @aslmsg, @level, message)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Log a message at the given level.
|
99
|
+
#
|
100
|
+
def add(level, message)
|
101
|
+
asl_log(@aslclient, @aslmsg, level, message)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Log a debug message.
|
105
|
+
#
|
106
|
+
def debug(message)
|
107
|
+
asl_log(@aslclient, @aslmsg, ASL_LEVEL_DEBUG, message)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns true if the current severity level allows for the printing of debug messages.
|
111
|
+
#
|
112
|
+
def debug?
|
113
|
+
level >= ASL_LEVEL_DEBUG
|
114
|
+
end
|
115
|
+
|
116
|
+
# Log an info message.
|
117
|
+
#
|
118
|
+
def info(message)
|
119
|
+
asl_log(@aslclient, @aslmsg, ASL_LEVEL_INFO, message)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns true if the current severity level allows for the printing of info messages.
|
123
|
+
#
|
124
|
+
def info?
|
125
|
+
level >= ASL_LEVEL_INFO
|
126
|
+
end
|
127
|
+
|
128
|
+
# Log a warning message.
|
129
|
+
#
|
130
|
+
def warn(message)
|
131
|
+
asl_log(@aslclient, @aslmsg, ASL_LEVEL_WARNING, message)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns true if the current severity level allows for the printing of warning messages.
|
135
|
+
#
|
136
|
+
def warn?
|
137
|
+
level >= ASL_LEVEL_WARNING
|
138
|
+
end
|
139
|
+
|
140
|
+
# Log an error message.
|
141
|
+
#
|
142
|
+
def error
|
143
|
+
asl_log(@aslclient, @aslmsg, ASL_LEVEL_ERR, message)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns true if the current severity level allows for the printing of erro messages.
|
147
|
+
#
|
148
|
+
def error?
|
149
|
+
level >= ASL_LEVEL_ERR
|
150
|
+
end
|
151
|
+
|
152
|
+
# Log a fatal message. For this library that means an ASL_LEVEL_CRIT message.
|
153
|
+
#
|
154
|
+
def fatal
|
155
|
+
asl_log(@aslclient, @aslmsg, ASL_LEVEL_CRIT, message)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns true if the current severity level allows for the printing of fatal messages.
|
159
|
+
#
|
160
|
+
def fatal?
|
161
|
+
level >= ASL_LEVEL_CRIT
|
162
|
+
end
|
163
|
+
|
164
|
+
# Log an unknown message. For this library that means an ASL_LEVEL_EMERG message.
|
165
|
+
#
|
166
|
+
def unknown(message)
|
167
|
+
asl_log(@aslclient, @aslmsg, ASL_LEVEL_EMERG, message)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Search the logs using the provided query. The query should be a hash of
|
171
|
+
# options. Returns an array of hashes.
|
172
|
+
#
|
173
|
+
# Example:
|
174
|
+
#
|
175
|
+
# log = Apple::System::Logger.new
|
176
|
+
#
|
177
|
+
# options = {
|
178
|
+
# :sender => 'bootlog'
|
179
|
+
# :level => 5
|
180
|
+
# }
|
181
|
+
#
|
182
|
+
# results = log.search(options)
|
183
|
+
#
|
184
|
+
# # Sample output
|
185
|
+
#
|
186
|
+
# [{
|
187
|
+
# "ASLMessageID" => "1",
|
188
|
+
# "Time" => "1570858104",
|
189
|
+
# "TimeNanoSec" => "0",
|
190
|
+
# "Level" => "5",
|
191
|
+
# "PID" => "0",
|
192
|
+
# "UID" => "0",
|
193
|
+
# "GID" => "0",
|
194
|
+
# "ReadGID" => "80",
|
195
|
+
# "Host" => "localhost",
|
196
|
+
# "Sender" => "bootlog",
|
197
|
+
# "Facility" => "com.apple.system.utmpx",
|
198
|
+
# "Message" => "BOOT_TIME 1570858104 0",
|
199
|
+
# "ut_id" => "0x00 0x00 0x00 0x00",
|
200
|
+
# "ut_pid" => "1",
|
201
|
+
# "ut_type" => "2",
|
202
|
+
# "ut_tv.tv_sec" => "1570858104",
|
203
|
+
# "ut_tv.tv_usec" => "0",
|
204
|
+
# "ASLExpireTime" => "1602480504"
|
205
|
+
# }]
|
206
|
+
#
|
207
|
+
# Only equality checks are used for most options. In the future, I will allow
|
208
|
+
# for more advanced queries, such as substrings and <, >, <=, >=.
|
209
|
+
#
|
210
|
+
# Note that Time objects are queried using "greater than or equal to" for now.
|
211
|
+
#
|
212
|
+
# Example:
|
213
|
+
#
|
214
|
+
# # Find all logs from uid 501 from the last hour.
|
215
|
+
# log.search(:uid => 501, :time => Time.now - 3600)
|
216
|
+
#
|
217
|
+
def search(query)
|
218
|
+
value = nil
|
219
|
+
aslmsg = asl_new(ASL_TYPE_QUERY)
|
220
|
+
result = []
|
221
|
+
|
222
|
+
query.each do |key, value|
|
223
|
+
asl_key = map_key_to_asl_key(key)
|
224
|
+
flags = ASL_QUERY_OP_EQUAL
|
225
|
+
flags = (flags | ASL_QUERY_OP_NUMERIC) if value.is_a?(Numeric)
|
226
|
+
flags = (flags | ASL_QUERY_OP_TRUE) if value == true
|
227
|
+
|
228
|
+
if value.is_a?(Time)
|
229
|
+
flags = (flags | ASL_QUERY_OP_GREATER_EQUAL)
|
230
|
+
value = value.to_i
|
231
|
+
end
|
232
|
+
|
233
|
+
if value.is_a?(Regexp)
|
234
|
+
flags = (flags | ASL_QUERY_OP_REGEX)
|
235
|
+
flags = (flags | ASL_QUERY_OP_CASEFOLD) if value.casefold?
|
236
|
+
end
|
237
|
+
|
238
|
+
asl_set_query(aslmsg, asl_key, value.to_s, flags)
|
239
|
+
end
|
240
|
+
|
241
|
+
response = asl_search(@aslclient, aslmsg)
|
242
|
+
|
243
|
+
while m = aslresponse_next(response)
|
244
|
+
break if m.null?
|
245
|
+
i = 0
|
246
|
+
hash = {}
|
247
|
+
while key = asl_key(m, i)
|
248
|
+
break if key.nil? || key.empty?
|
249
|
+
value = asl_get(m, key)
|
250
|
+
hash[key] = value
|
251
|
+
i += 1
|
252
|
+
end
|
253
|
+
result << hash
|
254
|
+
end
|
255
|
+
|
256
|
+
result
|
257
|
+
ensure
|
258
|
+
aslresponse_free(response) if response
|
259
|
+
asl_free(aslmsg)
|
260
|
+
end
|
261
|
+
|
262
|
+
# Close the logger instance. You should always do this.
|
263
|
+
#
|
264
|
+
def close
|
265
|
+
asl_free(@aslmsg) if @aslmsg
|
266
|
+
asl_close(@aslclient) if @aslclient
|
267
|
+
@aslmsg = nil
|
268
|
+
@aslclient = nil
|
269
|
+
end
|
270
|
+
|
271
|
+
private
|
272
|
+
|
273
|
+
def map_key_to_asl_key(key)
|
274
|
+
{
|
275
|
+
:time => ASL_KEY_TIME,
|
276
|
+
:host => ASL_KEY_HOST,
|
277
|
+
:sender => ASL_KEY_SENDER,
|
278
|
+
:facility => ASL_KEY_FACILITY,
|
279
|
+
:pid => ASL_KEY_PID,
|
280
|
+
:uid => ASL_KEY_UID,
|
281
|
+
:gid => ASL_KEY_GID,
|
282
|
+
:level => ASL_KEY_LEVEL,
|
283
|
+
:message => ASL_KEY_MSG
|
284
|
+
}[key]
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Apple
|
2
|
+
module System
|
3
|
+
module LoggerConstants
|
4
|
+
ASL_KEY_TIME = "Time"
|
5
|
+
ASL_KEY_HOST = "Host"
|
6
|
+
ASL_KEY_SENDER = "Sender"
|
7
|
+
ASL_KEY_FACILITY = "Facility"
|
8
|
+
ASL_KEY_PID = "PID"
|
9
|
+
ASL_KEY_UID = "UID"
|
10
|
+
ASL_KEY_GID = "GID"
|
11
|
+
ASL_KEY_LEVEL = "Level"
|
12
|
+
ASL_KEY_MSG = "Message"
|
13
|
+
|
14
|
+
ASL_LEVEL_EMERG = 0
|
15
|
+
ASL_LEVEL_ALERT = 1
|
16
|
+
ASL_LEVEL_CRIT = 2
|
17
|
+
ASL_LEVEL_ERR = 3
|
18
|
+
ASL_LEVEL_WARNING = 4
|
19
|
+
ASL_LEVEL_NOTICE = 5
|
20
|
+
ASL_LEVEL_INFO = 6
|
21
|
+
ASL_LEVEL_DEBUG = 7
|
22
|
+
|
23
|
+
ASL_TYPE_MSG = 0
|
24
|
+
ASL_TYPE_QUERY = 1
|
25
|
+
ASL_TYPE_LIST = 2
|
26
|
+
ASL_TYPE_FILE = 3
|
27
|
+
ASL_TYPE_STORE = 4
|
28
|
+
ASL_TYPE_CLIENT = 5
|
29
|
+
|
30
|
+
ASL_OPT_STDERR = 0x00000001
|
31
|
+
ASL_OPT_NO_DELAY = 0x00000002
|
32
|
+
ASL_OPT_NO_REMOTE = 0x00000004
|
33
|
+
|
34
|
+
ASL_QUERY_OP_CASEFOLD = 0x0010
|
35
|
+
ASL_QUERY_OP_PREFIX = 0x0020
|
36
|
+
ASL_QUERY_OP_SUFFIX = 0x0040
|
37
|
+
ASL_QUERY_OP_SUBSTRING = 0x0060
|
38
|
+
ASL_QUERY_OP_NUMERIC = 0x0080
|
39
|
+
ASL_QUERY_OP_REGEX = 0x0100
|
40
|
+
|
41
|
+
ASL_QUERY_OP_EQUAL = 0x0001
|
42
|
+
ASL_QUERY_OP_GREATER = 0x0002
|
43
|
+
ASL_QUERY_OP_GREATER_EQUAL = 0x0003
|
44
|
+
ASL_QUERY_OP_LESS = 0x0004
|
45
|
+
ASL_QUERY_OP_LESS_EQUAL = 0x0005
|
46
|
+
ASL_QUERY_OP_NOT_EQUAL = 0x0006
|
47
|
+
ASL_QUERY_OP_TRUE = 0x0007
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module Apple
|
4
|
+
module System
|
5
|
+
module LoggerFunctions
|
6
|
+
extend FFI::Library
|
7
|
+
ffi_lib FFI::Library::LIBC
|
8
|
+
|
9
|
+
attach_function(:asl_add_log_file, [:pointer, :int], :int)
|
10
|
+
attach_function(:asl_close, [:pointer], :void)
|
11
|
+
attach_function(:asl_free, [:pointer], :void)
|
12
|
+
attach_function(:asl_get, [:pointer, :string], :string)
|
13
|
+
attach_function(:asl_key, [:pointer, :uint32], :string)
|
14
|
+
attach_function(:asl_log, [:pointer, :pointer, :int, :string, :varargs], :int)
|
15
|
+
attach_function(:asl_new, [:uint32], :pointer)
|
16
|
+
attach_function(:asl_open, [:string, :string, :uint32], :pointer)
|
17
|
+
attach_function(:asl_remove_log_file, [:pointer, :int], :int)
|
18
|
+
attach_function(:asl_search, [:pointer, :pointer], :pointer)
|
19
|
+
attach_function(:asl_send, [:pointer, :pointer], :int)
|
20
|
+
attach_function(:asl_set, [:pointer, :string, :string], :int)
|
21
|
+
attach_function(:asl_set_filter, [:pointer, :int], :int)
|
22
|
+
attach_function(:asl_set_query, [:pointer, :string, :string, :uint32], :int)
|
23
|
+
attach_function(:asl_unset, [:pointer, :string], :int)
|
24
|
+
attach_function(:asl_vlog, [:pointer, :pointer, :int, :string, :pointer], :int)
|
25
|
+
attach_function(:aslresponse_free, [:pointer], :void)
|
26
|
+
attach_function(:aslresponse_next, [:pointer], :pointer)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'apple-system-logger'
|
2
|
+
|
3
|
+
RSpec.describe Apple::System::Logger do
|
4
|
+
let(:log){ described_class.new }
|
5
|
+
|
6
|
+
context "instance methods" do
|
7
|
+
example "defines a facility method" do
|
8
|
+
expect(log).to respond_to(:facility)
|
9
|
+
end
|
10
|
+
|
11
|
+
example "the default facility is nil" do
|
12
|
+
expect(log.facility).to be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
example "defines a level method" do
|
16
|
+
expect(log).to respond_to(:level)
|
17
|
+
end
|
18
|
+
|
19
|
+
example "the default level is debug" do
|
20
|
+
expect(log.level).to eql(Apple::System::Logger::ASL_LEVEL_DEBUG)
|
21
|
+
end
|
22
|
+
|
23
|
+
example "defines a progname method" do
|
24
|
+
expect(log).to respond_to(:progname)
|
25
|
+
end
|
26
|
+
|
27
|
+
example "the default progname is nil" do
|
28
|
+
expect(log.progname).to be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
example "defines a logdev method" do
|
32
|
+
expect(log).to respond_to(:logdev)
|
33
|
+
end
|
34
|
+
|
35
|
+
example "the default logdev is nil" do
|
36
|
+
expect(log.logdev).to be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "logging methods" do
|
41
|
+
example "there is a << method" do
|
42
|
+
expect(log).to respond_to(:<<)
|
43
|
+
end
|
44
|
+
|
45
|
+
example "there is an add method" do
|
46
|
+
expect(log).to respond_to(:add)
|
47
|
+
end
|
48
|
+
|
49
|
+
example "there is a debug method" do
|
50
|
+
expect(log).to respond_to(:debug)
|
51
|
+
end
|
52
|
+
|
53
|
+
example "there is a debug? method that returns the expected value" do
|
54
|
+
expect(log.debug?).to be true
|
55
|
+
end
|
56
|
+
|
57
|
+
example "there is an info method" do
|
58
|
+
expect(log).to respond_to(:info)
|
59
|
+
end
|
60
|
+
|
61
|
+
example "there is a info? method that returns the expected value" do
|
62
|
+
expect(log.info?).to be true
|
63
|
+
end
|
64
|
+
|
65
|
+
example "there is a warn method" do
|
66
|
+
expect(log).to respond_to(:warn)
|
67
|
+
end
|
68
|
+
|
69
|
+
example "there is a warn? method that returns the expected value" do
|
70
|
+
expect(log.warn?).to be true
|
71
|
+
end
|
72
|
+
|
73
|
+
example "there is an error method" do
|
74
|
+
expect(log).to respond_to(:error)
|
75
|
+
end
|
76
|
+
|
77
|
+
example "there is a error? method that returns the expected value" do
|
78
|
+
expect(log.error?).to be true
|
79
|
+
end
|
80
|
+
|
81
|
+
example "there is a fatal method" do
|
82
|
+
expect(log).to respond_to(:error)
|
83
|
+
end
|
84
|
+
|
85
|
+
example "there is a fatal? method that returns the expected value" do
|
86
|
+
expect(log.fatal?).to be true
|
87
|
+
end
|
88
|
+
|
89
|
+
example "there is an unknown method" do
|
90
|
+
expect(log).to respond_to(:unknown)
|
91
|
+
end
|
92
|
+
|
93
|
+
example "there is a close method" do
|
94
|
+
expect(log).to respond_to(:close)
|
95
|
+
end
|
96
|
+
|
97
|
+
example "calling close on the logger instance works as expected" do
|
98
|
+
expect(log.close).to be_nil
|
99
|
+
expect(log.close).to be_nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "search" do
|
104
|
+
example "there is a search method" do
|
105
|
+
expect(log).to respond_to(:search)
|
106
|
+
end
|
107
|
+
|
108
|
+
example "a basic search returns the expected results" do
|
109
|
+
result = log.search(:sender => 'bootlog', :level => 5)
|
110
|
+
expect(result).to be_a_kind_of(Array)
|
111
|
+
expect(result.first).to be_a_kind_of(Hash)
|
112
|
+
expect(result.size).to eql(1)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apple-system-logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel J. Berger
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIEcDCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MREwDwYDVQQDDAhkamJl
|
14
|
+
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
15
|
+
MB4XDTE4MDMxODE1MjIwN1oXDTI4MDMxNTE1MjIwN1owPzERMA8GA1UEAwwIZGpi
|
16
|
+
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
17
|
+
bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALgfaroVM6CI06cxr0/h
|
18
|
+
A+j+pc8fgpRgBVmHFaFunq28GPC3IvW7Nvc3Y8SnAW7pP1EQIbhlwRIaQzJ93/yj
|
19
|
+
u95KpkP7tA9erypnV7dpzBkzNlX14ACaFD/6pHoXoe2ltBxk3CCyyzx70mTqJpph
|
20
|
+
75IB03ni9a8yqn8pmse+s83bFJOAqddSj009sGPcQO+QOWiNxqYv1n5EHcvj2ebO
|
21
|
+
6hN7YTmhx7aSia4qL/quc4DlIaGMWoAhvML7u1fmo53CYxkKskfN8MOecq2vfEmL
|
22
|
+
iLu+SsVVEAufMDDFMXMJlvDsviolUSGMSNRTujkyCcJoXKYYxZSNtIiyd9etI0X3
|
23
|
+
ctu0uhrFyrMZXCedutvXNjUolD5r9KGBFSWH1R9u2I3n3SAyFF2yzv/7idQHLJJq
|
24
|
+
74BMnx0FIq6fCpu5slAipvxZ3ZkZpEXZFr3cIBtO1gFvQWW7E/Y3ijliWJS1GQFq
|
25
|
+
058qERadHGu1yu1dojmFRo6W2KZvY9al2yIlbkpDrD5MYQIDAQABo3cwdTAJBgNV
|
26
|
+
HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUFZsMapgzJimzsbaBG2Tm8j5e
|
27
|
+
AzgwHQYDVR0RBBYwFIESZGpiZXJnOTZAZ21haWwuY29tMB0GA1UdEgQWMBSBEmRq
|
28
|
+
YmVyZzk2QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAW2tnYixXQtKxgGXq
|
29
|
+
/3iSWG2bLwvxS4go3srO+aRXZHrFUMlJ5W0mCxl03aazxxKTsVVpZD8QZxvK91OQ
|
30
|
+
h9zr9JBYqCLcCVbr8SkmYCi/laxIZxsNE5YI8cC8vvlLI7AMgSfPSnn/Epq1GjGY
|
31
|
+
6L1iRcEDtanGCIvjqlCXO9+BmsnCfEVehqZkQHeYczA03tpOWb6pon2wzvMKSsKH
|
32
|
+
ks0ApVdstSLz1kzzAqem/uHdG9FyXdbTAwH1G4ZPv69sQAFAOCgAqYmdnzedsQtE
|
33
|
+
1LQfaQrx0twO+CZJPcRLEESjq8ScQxWRRkfuh2VeR7cEU7L7KqT10mtUwrvw7APf
|
34
|
+
DYoeCY9KyjIBjQXfbj2ke5u1hZj94Fsq9FfbEQg8ygCgwThnmkTrrKEiMSs3alYR
|
35
|
+
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
36
|
+
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
37
|
+
-----END CERTIFICATE-----
|
38
|
+
date:
|
39
|
+
dependencies:
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: ffi
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rake
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rspec
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
description: " The apple-system-logger library provides an interface for the Apple
|
83
|
+
System\n Library. You can both write to, and search, your mac's system logs using\n
|
84
|
+
\ this library using an API that is very similar to the stdlib Logger interface.
|
85
|
+
\n"
|
86
|
+
email: djberg96@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- apple-system-logger.gemspec
|
92
|
+
- spec
|
93
|
+
- spec/apple-system-logger_spec.rb
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- MANIFEST.md
|
97
|
+
- certs
|
98
|
+
- certs/djberg96_pub.pem
|
99
|
+
- lib
|
100
|
+
- lib/apple
|
101
|
+
- lib/apple/system
|
102
|
+
- lib/apple/system/logger
|
103
|
+
- lib/apple/system/logger/constants.rb
|
104
|
+
- lib/apple/system/logger/functions.rb
|
105
|
+
- lib/apple/system/logger.rb
|
106
|
+
- lib/apple-system-logger.rb
|
107
|
+
- CHANGES.md
|
108
|
+
homepage: https://github.com/djberg96/apple-system-logger
|
109
|
+
licenses:
|
110
|
+
- Apache-2.0
|
111
|
+
metadata:
|
112
|
+
homepage_uri: https://github.com/djberg96/apple-system-logger
|
113
|
+
bug_tracker_uri: https://github.com/djberg96/apple-system-logger/issues
|
114
|
+
changelog_uri: https://github.com/djberg96/apple-system-logger/blob/master/CHANGES
|
115
|
+
documentation_uri: https://github.com/djberg96/apple-system-logger/wiki
|
116
|
+
source_code_uri: https://github.com/djberg96/apple-system-logger
|
117
|
+
wiki_uri: https://github.com/djberg96/apple-system-logger/wiki
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubygems_version: 3.0.6
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: A Ruby interface for the Apple System Logger
|
137
|
+
test_files:
|
138
|
+
- spec/apple-system-logger_spec.rb
|
metadata.gz.sig
ADDED
Binary file
|