apple-system-logger 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|