chook 1.0.1.b1 → 1.1.5b1
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 +5 -5
- data/CHANGES.md +56 -0
- data/README.md +397 -145
- data/bin/chook-server +31 -1
- data/data/chook.conf.example +183 -0
- data/data/com.pixar.chook-server.plist +20 -0
- data/data/sample_handlers/RestAPIOperation.rb +11 -11
- data/data/sample_handlers/SmartGroupComputerMembershipChange.rb +3 -6
- data/data/sample_jsons/SmartGroupComputerMembershipChange.json +3 -1
- data/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +3 -1
- data/lib/chook/configuration.rb +27 -8
- data/lib/chook/event.rb +6 -1
- data/lib/chook/event/handled_event.rb +36 -9
- data/lib/chook/event/handled_event/handlers.rb +252 -99
- data/lib/chook/event/handled_event_logger.rb +86 -0
- data/lib/chook/event_handling.rb +1 -0
- data/lib/chook/foundation.rb +3 -0
- data/lib/chook/procs.rb +17 -1
- data/lib/chook/server.rb +73 -72
- data/lib/chook/server/auth.rb +164 -0
- data/lib/chook/server/log.rb +215 -0
- data/lib/chook/server/public/css/chook.css +133 -0
- data/lib/chook/server/public/imgs/ChookLogoAlMcWhiggin.png +0 -0
- data/lib/chook/server/public/js/chook.js +126 -0
- data/lib/chook/server/public/js/logstream.js +101 -0
- data/lib/chook/server/routes.rb +28 -0
- data/lib/chook/server/routes/handle_by_name.rb +65 -0
- data/lib/chook/server/routes/handle_webhook_event.rb +27 -3
- data/lib/chook/server/routes/handlers.rb +52 -0
- data/lib/chook/server/routes/home.rb +48 -1
- data/lib/chook/server/routes/log.rb +105 -0
- data/lib/chook/server/routes/login_logout.rb +48 -0
- data/lib/chook/server/views/admin.haml +11 -0
- data/lib/chook/server/views/bak.haml +48 -0
- data/lib/chook/server/views/config.haml +15 -0
- data/lib/chook/server/views/handlers.haml +63 -0
- data/lib/chook/server/views/layout.haml +64 -0
- data/lib/chook/server/views/logstream.haml +33 -0
- data/lib/chook/server/views/sketch_admin +44 -0
- data/lib/chook/subject.rb +13 -2
- data/lib/chook/subject/dep_device.rb +81 -0
- data/lib/chook/subject/policy_finished.rb +43 -0
- data/lib/chook/subject/smart_group.rb +6 -0
- data/lib/chook/subject/test_subject.rb +2 -2
- data/lib/chook/version.rb +1 -1
- metadata +78 -17
@@ -1,36 +1,45 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
1
|
+
# Copyright 2017 Pixar
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "Apache License")
|
4
|
+
# with the following modification; you may not use this file except in
|
5
|
+
# compliance with the Apache License and the following modification to it:
|
6
|
+
# Section 6. Trademarks. is deleted and replaced with:
|
7
|
+
#
|
8
|
+
# 6. Trademarks. This License does not grant permission to use the trade
|
9
|
+
# names, trademarks, service marks, or product names of the Licensor
|
10
|
+
# and its affiliates, except as required to comply with Section 4(c) of
|
11
|
+
# the License and to reproduce the content of the NOTICE file.
|
12
|
+
#
|
13
|
+
# You may obtain a copy of the Apache License at
|
14
|
+
#
|
15
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
16
|
+
#
|
17
|
+
# Unless required by applicable law or agreed to in writing, software
|
18
|
+
# distributed under the Apache License with the above modification is
|
19
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
20
|
+
# KIND, either express or implied. See the Apache License for the specific
|
21
|
+
# language governing permissions and limitations under the Apache License.
|
22
|
+
#
|
23
|
+
#
|
24
|
+
|
25
25
|
module Chook
|
26
26
|
|
27
|
-
# This method is used by the Ruby event-handler files.
|
27
|
+
# This method is used by the Ruby 'internal' event-handler files.
|
28
|
+
#
|
29
|
+
# those handlers are defined by passing a block to this method, like so:
|
30
|
+
#
|
31
|
+
# Chook.event_handler do |event|
|
32
|
+
# # so something with the event
|
33
|
+
# end
|
28
34
|
#
|
29
|
-
# Loading them
|
35
|
+
# Loading them will call this method and pass in a block
|
30
36
|
# with one parameter: a Chook::HandledEvent subclass instance.
|
31
37
|
#
|
32
|
-
# The block is then converted to a
|
33
|
-
#
|
38
|
+
# The block is then converted to a #handle method in an anonymous object.
|
39
|
+
# The object is stored for use by the event identified by the filename.
|
40
|
+
#
|
41
|
+
# By storing it as a method in an object, the handlers themselves
|
42
|
+
# can use #break or #return to exit (or even #next)
|
34
43
|
#
|
35
44
|
# NOTE: the files should be read with 'load' not 'require', so that they can
|
36
45
|
# be re-loaded as needed
|
@@ -44,7 +53,13 @@ module Chook
|
|
44
53
|
# @return [Proc] the block converted to a Proc
|
45
54
|
#
|
46
55
|
def self.event_handler(&block)
|
47
|
-
|
56
|
+
obj = Object.new
|
57
|
+
obj.define_singleton_method(:handle, &block)
|
58
|
+
# Loading the file created the object by calling this method
|
59
|
+
# but to access it after loading the file, we need to
|
60
|
+
# store it in here:
|
61
|
+
HandledEvent::Handlers.loaded_handler = obj
|
62
|
+
Chook.logger.debug "Code block for 'Chook.event_handler' loaded into \#handle method of runner-object #{obj.object_id}"
|
48
63
|
end
|
49
64
|
|
50
65
|
# the server class
|
@@ -53,56 +68,101 @@ module Chook
|
|
53
68
|
# The Handlers namespace module
|
54
69
|
module Handlers
|
55
70
|
|
56
|
-
# Module Constants
|
57
|
-
############################
|
58
|
-
|
59
71
|
DEFAULT_HANDLER_DIR = '/Library/Application Support/Chook'.freeze
|
60
72
|
|
61
|
-
#
|
62
|
-
|
73
|
+
# Handlers that are only called by name using the route:
|
74
|
+
# post '/handler/:handler_name'
|
75
|
+
# are located in this subdirection of the handler directory
|
76
|
+
NAMED_HANDLER_SUBDIR = 'NamedHandlers'.freeze
|
63
77
|
|
64
|
-
#
|
65
|
-
|
66
|
-
@loaded_handler = nil
|
78
|
+
# internal handler files must match this regex somewhere
|
79
|
+
INTERNAL_HANDLER_BLOCK_START_RE = /Chook.event_handler( ?\{| do) *\|/
|
67
80
|
|
68
|
-
#
|
81
|
+
# self loaded_handler=
|
69
82
|
#
|
70
|
-
# @return [
|
83
|
+
# @return [Obj,nil] the most recent Proc loaded from a handler file.
|
71
84
|
# destined for storage in @handlers
|
72
85
|
#
|
73
86
|
def self.loaded_handler
|
74
87
|
@loaded_handler
|
75
88
|
end
|
76
89
|
|
77
|
-
#
|
90
|
+
# A holding place for internal handlers as they are loaded
|
91
|
+
# before being added to the @handlers Hash
|
92
|
+
# see Chook.event_handler(&block)
|
78
93
|
#
|
79
|
-
# @param a_proc [
|
94
|
+
# @param a_proc [Object] An object instance with a #handle method
|
80
95
|
#
|
81
|
-
def self.loaded_handler=(
|
82
|
-
@loaded_handler =
|
96
|
+
def self.loaded_handler=(anon_obj)
|
97
|
+
@loaded_handler = anon_obj
|
83
98
|
end
|
84
99
|
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
|
90
|
-
|
91
|
-
#
|
100
|
+
# Getter for @handlers
|
101
|
+
#
|
102
|
+
# @return [Hash{String => Array}] a mapping of Event Names as they
|
103
|
+
# come from the JSS to an Array of handlers for the event.
|
104
|
+
# The handlers are either Pathnames to executable external handlers
|
105
|
+
# or Objcts with a #handle method, for internal handlers
|
106
|
+
# (The objects also have a #handler_file attribute that is the Pathname)
|
92
107
|
#
|
93
|
-
# @return [Hash{String => Array}] a mapping of Event Names as the come from
|
94
|
-
# the JSS to an Array of handlers for the event. The handlers are either
|
95
|
-
# Proc objects to call from within ruby, or Pathnames to executable files
|
96
|
-
# which will take raw JSON on stdin.
|
97
108
|
def self.handlers
|
98
|
-
@handlers
|
109
|
+
@handlers ||= {}
|
99
110
|
end
|
100
111
|
|
101
|
-
#
|
102
|
-
|
112
|
+
# Handlers can check Chook::HandledEvent::Handlers.reloading?
|
113
|
+
# and do stuff if desired.
|
114
|
+
def self.reloading?
|
115
|
+
@reloading
|
116
|
+
end
|
117
|
+
|
118
|
+
# getter for @named_handlers
|
119
|
+
# These handlers are called by name via the route
|
120
|
+
# " post '/handler/:handler_name'"
|
121
|
+
#
|
122
|
+
# They are not tied to any event type by their filenames
|
123
|
+
# its up to the writers of the handlers to make sure
|
124
|
+
# the webhook that calls them is sending the correct event
|
125
|
+
# type.
|
126
|
+
#
|
127
|
+
# The data structure of @named_handlers is a
|
128
|
+
# Hash of Strings to Pathnames or Anon Objects:
|
129
|
+
# {
|
130
|
+
# handler_filename => Pathname or Obj,
|
131
|
+
# handler_filename => Pathname or Obj,
|
132
|
+
# handler_filename => Pathname or Obj
|
133
|
+
# }
|
134
|
+
#
|
135
|
+
# @return [Hash {String => Pathname, Proc}]
|
136
|
+
def self.named_handlers
|
137
|
+
@named_handlers ||= {}
|
138
|
+
end
|
139
|
+
|
140
|
+
# the Pathname objects for all loaded handlers
|
141
|
+
#
|
142
|
+
# @return [Array<Pathname>]
|
143
|
+
#
|
144
|
+
def self.all_handler_paths
|
145
|
+
hndlrs = named_handlers.values
|
146
|
+
hndlrs += handlers.values.flatten
|
147
|
+
hndlrs.map do |hndlr|
|
148
|
+
hndlr.is_a?(Pathname) ? hndlr : hndlr.handler_file
|
149
|
+
end
|
150
|
+
end
|
103
151
|
|
104
152
|
# Load all the event handlers from the handler_dir or an arbitrary dir.
|
105
153
|
#
|
154
|
+
#
|
155
|
+
# Handler files must be either:
|
156
|
+
# - An executable file, which will have the raw JSON from the JSS piped
|
157
|
+
# to it's stdin when executed
|
158
|
+
# or
|
159
|
+
# - A non-executable file of ruby code like this:
|
160
|
+
# Chook.event_handler do |event|
|
161
|
+
# # your code goes here.
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# (see the Chook README for details about writing the ruby handlers)
|
165
|
+
#
|
106
166
|
# @param from_dir [String, Pathname] directory from which to load the
|
107
167
|
# handlers. Defaults to CONFIG.handler_dir or DEFAULT_HANDLER_DIR if
|
108
168
|
# config is unset
|
@@ -112,27 +172,49 @@ module Chook
|
|
112
172
|
#
|
113
173
|
# @return [void]
|
114
174
|
#
|
115
|
-
def self.load_handlers(from_dir: Chook
|
175
|
+
def self.load_handlers(from_dir: Chook.config.handler_dir, reload: false)
|
176
|
+
# use default if needed
|
116
177
|
from_dir ||= DEFAULT_HANDLER_DIR
|
178
|
+
handler_dir = Pathname.new(from_dir)
|
179
|
+
named_handler_dir = handler_dir + NAMED_HANDLER_SUBDIR
|
180
|
+
load_type = 'Loading'
|
181
|
+
|
117
182
|
if reload
|
118
|
-
@
|
183
|
+
@reloading = true
|
119
184
|
@handlers = {}
|
185
|
+
@named_handlers = {}
|
120
186
|
@loaded_handler = nil
|
187
|
+
load_type = 'Re-loading'
|
121
188
|
end
|
122
189
|
|
123
|
-
|
124
|
-
|
190
|
+
# General Handlers
|
191
|
+
Chook.logger.info "#{load_type} general handlers from directory: #{handler_dir}"
|
192
|
+
if handler_dir.directory? && handler_dir.readable?
|
193
|
+
handler_dir.children.each do |handler_file|
|
194
|
+
load_general_handler(handler_file) if handler_file.file? && handler_file.readable?
|
195
|
+
end
|
196
|
+
Chook.logger.info handlers.empty? ? 'No general handlers found' : "Loaded #{handlers.values.flatten.size} general handlers for #{handlers.keys.size} event triggers"
|
197
|
+
else
|
198
|
+
Chook.logger.error "General handler directory '#{from_dir}' not a readable directory. No general handlers loaded. "
|
199
|
+
end
|
125
200
|
|
126
|
-
|
127
|
-
|
201
|
+
# Named Handlers
|
202
|
+
Chook.logger.info "#{load_type} named handlers from directory: #{named_handler_dir}"
|
203
|
+
if named_handler_dir.directory? && named_handler_dir.readable?
|
204
|
+
named_handler_dir.children.each do |handler_file|
|
205
|
+
load_named_handler(handler_file) if handler_file.file? && handler_file.readable?
|
206
|
+
end
|
207
|
+
Chook.logger.info "Loaded #{named_handlers.size} named handlers"
|
208
|
+
else
|
209
|
+
Chook.logger.error "Named handler directory '#{named_handler_dir}' not a readable directory. No named handlers loaded. "
|
128
210
|
end
|
129
211
|
|
130
|
-
@
|
131
|
-
@handlers.values.flatten.size
|
212
|
+
@reloading = false
|
132
213
|
end # load handlers
|
133
214
|
|
134
|
-
# Load
|
135
|
-
#
|
215
|
+
# Load a general event handler from a file.
|
216
|
+
#
|
217
|
+
# General Handler files must begin with the name of the event they handle,
|
136
218
|
# e.g. ComputerAdded, followed by: nothing, a dot, a dash, or
|
137
219
|
# and underscore. Case doesn't matter.
|
138
220
|
# So all of these are OK:
|
@@ -142,49 +224,113 @@ module Chook
|
|
142
224
|
# Computeradded-update-ldap
|
143
225
|
# There can be as many as desired for each event.
|
144
226
|
#
|
145
|
-
#
|
146
|
-
# - An executable file, which will have the raw JSON from the JSS piped
|
147
|
-
# to it's stdin when executed
|
148
|
-
# or
|
149
|
-
# - A non-executable file of ruby code like this:
|
150
|
-
# Chook.event_handler do |event|
|
151
|
-
# # your code goes here.
|
152
|
-
# end
|
153
|
-
#
|
154
|
-
# (see the Chook README for details about writing the ruby handlers)
|
155
|
-
#
|
156
|
-
# @param from_file [Pathname] the file from which to load the handler
|
227
|
+
# @param handler_file [Pathname] the file from which to load the handler
|
157
228
|
#
|
158
229
|
# @return [void]
|
159
230
|
#
|
160
|
-
def self.
|
161
|
-
|
231
|
+
def self.load_general_handler(handler_file)
|
232
|
+
Chook.logger.debug "Starting load of general handler file '#{handler_file.basename}'"
|
233
|
+
|
162
234
|
event_name = event_name_from_handler_filename(handler_file)
|
163
|
-
|
235
|
+
unless event_name
|
236
|
+
Chook.logger.debug "Ignoring general handler file '#{handler_file.basename}': Filename doesn't start with event name"
|
237
|
+
return
|
238
|
+
end
|
164
239
|
|
165
240
|
# create an array for this event's handlers, if needed
|
166
|
-
|
241
|
+
handlers[event_name] ||= []
|
167
242
|
|
243
|
+
# external? if so, its executable and we only care about its pathname
|
168
244
|
if handler_file.executable?
|
169
|
-
|
170
|
-
|
171
|
-
@handlers[event_name] << handler_file
|
172
|
-
puts "===> Loaded executable handler file '#{handler_file.basename}'"
|
173
|
-
end
|
245
|
+
Chook.logger.info "Loading external general handler file '#{handler_file.basename}' for #{event_name} events"
|
246
|
+
handlers[event_name] << handler_file
|
174
247
|
return
|
175
248
|
end
|
176
249
|
|
177
|
-
#
|
178
|
-
|
179
|
-
|
180
|
-
if @loaded_handler
|
181
|
-
|
182
|
-
|
183
|
-
|
250
|
+
# Internal, we store an object with a .handle method
|
251
|
+
Chook.logger.info "Loading internal general handler file '#{handler_file.basename}' for #{event_name} events"
|
252
|
+
load_internal_handler handler_file
|
253
|
+
handlers[event_name] << @loaded_handler if @loaded_handler
|
254
|
+
|
255
|
+
end # self.load_general_handler(handler_file)
|
256
|
+
|
257
|
+
# Load a named event handler from a file.
|
258
|
+
#
|
259
|
+
# Named Handler files can have any name, as they are called directly
|
260
|
+
# from a Jamf webhook via URL.
|
261
|
+
#
|
262
|
+
# @param handler_file [Pathname] the file from which to load the handler
|
263
|
+
#
|
264
|
+
# @return [void]
|
265
|
+
#
|
266
|
+
def self.load_named_handler(handler_file)
|
267
|
+
Chook.logger.debug "Starting load of named handler file '#{handler_file.basename}'"
|
268
|
+
|
269
|
+
# external? if so, its executable and we only care about its pathname
|
270
|
+
if handler_file.executable?
|
271
|
+
Chook.logger.info "Loading external named handler file '#{handler_file.basename}'"
|
272
|
+
named_handlers[handler_file.basename.to_s] = handler_file
|
273
|
+
return
|
274
|
+
end
|
275
|
+
|
276
|
+
# Internal, we store an object with a .handle method
|
277
|
+
Chook.logger.info "Loading internal named handler file '#{handler_file.basename}'"
|
278
|
+
load_internal_handler handler_file
|
279
|
+
named_handlers[handler_file.basename.to_s] = @loaded_handler if @loaded_handler
|
280
|
+
end # self.load_general_handler(handler_file)
|
281
|
+
|
282
|
+
# if the given file is executable, store it's path as a handler for the event
|
283
|
+
#
|
284
|
+
# @return [Boolean] did we load an external handler?
|
285
|
+
#
|
286
|
+
def self.load_external_handler(handler_file, event_name, named)
|
287
|
+
return false unless handler_file.executable?
|
288
|
+
|
289
|
+
say_named = named ? 'named ' : ''
|
290
|
+
Chook.logger.info "Loading #{say_named}external handler file '#{handler_file.basename}' for #{event_name} events"
|
291
|
+
|
292
|
+
if named
|
293
|
+
named_handlers[event_name][handler_file.basename.to_s] = handler_file
|
184
294
|
else
|
185
|
-
|
295
|
+
# store the Pathname, we'll pipe JSON to it
|
296
|
+
handlers[event_name] << handler_file
|
297
|
+
end
|
298
|
+
|
299
|
+
true
|
300
|
+
end
|
301
|
+
|
302
|
+
# if a given path is not executable, try to load it as an internal handler
|
303
|
+
#
|
304
|
+
# @param handler_file[Pathname] the handler file
|
305
|
+
#
|
306
|
+
# @return [Object] and anonymous object that has a .handle method
|
307
|
+
#
|
308
|
+
def self.load_internal_handler(handler_file)
|
309
|
+
# load the file. If written correctly, it will
|
310
|
+
# put an anon. Object with a #handle method into @loaded_handler
|
311
|
+
unless handler_file.read =~ INTERNAL_HANDLER_BLOCK_START_RE
|
312
|
+
Chook.logger.error "Internal handler file '#{handler_file}' missing event_handler block"
|
313
|
+
return nil
|
314
|
+
end
|
315
|
+
|
316
|
+
# reset @loaded_handler - the `load` call will refill it
|
317
|
+
# see Chook.event_handler
|
318
|
+
@loaded_handler = nil
|
319
|
+
|
320
|
+
begin
|
321
|
+
load handler_file.to_s
|
322
|
+
raise '@loaded handler nil after loading file' unless @loaded_handler
|
323
|
+
rescue => e
|
324
|
+
Chook.logger.error "FAILED loading internal handler file '#{handler_file}': #{e}"
|
325
|
+
return
|
186
326
|
end
|
187
|
-
|
327
|
+
|
328
|
+
# add a method to the object to get its Pathname
|
329
|
+
@loaded_handler.define_singleton_method(:handler_file) { handler_file }
|
330
|
+
|
331
|
+
# return it
|
332
|
+
@loaded_handler
|
333
|
+
end
|
188
334
|
|
189
335
|
# Given a handler filename, return the event name it wants to handle
|
190
336
|
#
|
@@ -194,9 +340,16 @@ module Chook
|
|
194
340
|
# @return [String,nil] The matching event name or nil if no match
|
195
341
|
#
|
196
342
|
def self.event_name_from_handler_filename(filename)
|
343
|
+
filename = filename.basename
|
197
344
|
@event_names ||= Chook::Event::EVENTS.keys
|
198
|
-
desired_event_name = filename.
|
199
|
-
@event_names.select { |n| desired_event_name.casecmp(n).zero? }.first
|
345
|
+
desired_event_name = filename.to_s.split(/\.|-|_/).first
|
346
|
+
ename = @event_names.select { |n| desired_event_name.casecmp(n).zero? }.first
|
347
|
+
if ename
|
348
|
+
Chook.logger.debug "Found event name '#{ename}' at start of filename '#{filename}'"
|
349
|
+
else
|
350
|
+
Chook.logger.debug "No known event name at start of filename '#{filename}'"
|
351
|
+
end
|
352
|
+
ename
|
200
353
|
end
|
201
354
|
|
202
355
|
end # module Handler
|
@@ -0,0 +1,86 @@
|
|
1
|
+
### Copyright 2017 Pixar
|
2
|
+
|
3
|
+
###
|
4
|
+
### Licensed under the Apache License, Version 2.0 (the "Apache License")
|
5
|
+
### with the following modification; you may not use this file except in
|
6
|
+
### compliance with the Apache License and the following modification to it:
|
7
|
+
### Section 6. Trademarks. is deleted and replaced with:
|
8
|
+
###
|
9
|
+
### 6. Trademarks. This License does not grant permission to use the trade
|
10
|
+
### names, trademarks, service marks, or product names of the Licensor
|
11
|
+
### and its affiliates, except as required to comply with Section 4(c) of
|
12
|
+
### the License and to reproduce the content of the NOTICE file.
|
13
|
+
###
|
14
|
+
### You may obtain a copy of the Apache License at
|
15
|
+
###
|
16
|
+
### http://www.apache.org/licenses/LICENSE-2.0
|
17
|
+
###
|
18
|
+
### Unless required by applicable law or agreed to in writing, software
|
19
|
+
### distributed under the Apache License with the above modification is
|
20
|
+
### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
21
|
+
### KIND, either express or implied. See the Apache License for the specific
|
22
|
+
### language governing permissions and limitations under the Apache License.
|
23
|
+
###
|
24
|
+
###
|
25
|
+
|
26
|
+
module Chook
|
27
|
+
|
28
|
+
# a simple object embedded in a Handled Event that
|
29
|
+
# allows a standardize way to note event-related log entries
|
30
|
+
# with the event object_id.
|
31
|
+
#
|
32
|
+
# Every Handled Event has one of these instances exposed in it's
|
33
|
+
# #logger attribute, and usable from within 'internal' handlers
|
34
|
+
#
|
35
|
+
# Here's an example.
|
36
|
+
#
|
37
|
+
# Say you have a ComputerSmartGroupMembershipChanged event
|
38
|
+
#
|
39
|
+
# calling `event.logger.info "foobar"` will generate the log message:
|
40
|
+
#
|
41
|
+
# Event 1234567: foobar
|
42
|
+
#
|
43
|
+
class HandledEventLogger
|
44
|
+
|
45
|
+
def initialize(event)
|
46
|
+
@event = event
|
47
|
+
end
|
48
|
+
|
49
|
+
def event_message(msg)
|
50
|
+
"Event #{@event.id}: #{msg}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def debug(msg)
|
54
|
+
Chook::Server::Log.logger.debug event_message(msg)
|
55
|
+
end
|
56
|
+
|
57
|
+
def info(msg)
|
58
|
+
Chook::Server::Log.logger.info event_message(msg)
|
59
|
+
end
|
60
|
+
|
61
|
+
def warn(msg)
|
62
|
+
Chook::Server::Log.logger.warn event_message(msg)
|
63
|
+
end
|
64
|
+
|
65
|
+
def error(msg)
|
66
|
+
Chook::Server::Log.logger.error event_message(msg)
|
67
|
+
end
|
68
|
+
|
69
|
+
def fatal(msg)
|
70
|
+
Chook::Server::Log.logger.fatal event_message(msg)
|
71
|
+
end
|
72
|
+
|
73
|
+
def unknown(msg)
|
74
|
+
Chook::Server::Log.logger.unknown event_message(msg)
|
75
|
+
end
|
76
|
+
|
77
|
+
# log an exception - multiple log lines
|
78
|
+
# the first being the error message the rest being indented backtrace
|
79
|
+
def log_exception(exception)
|
80
|
+
error "#{exception.class}: #{exception}"
|
81
|
+
exception.backtrace.each { |l| error "..#{l}" }
|
82
|
+
end
|
83
|
+
|
84
|
+
end # class HandledEventLogger
|
85
|
+
|
86
|
+
end # module
|