chook 1.0.1.b2 → 1.1.5
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 +363 -127
- 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 +260 -98
- 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/version.rb +1 -1
- metadata +79 -19
@@ -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,104 @@ module Chook
|
|
53
68
|
# The Handlers namespace module
|
54
69
|
module Handlers
|
55
70
|
|
56
|
-
#
|
57
|
-
|
71
|
+
# Don't load any handlers whose filenames start with this
|
72
|
+
DO_NOT_LOAD_PREFIX = 'Ignore-'.freeze
|
58
73
|
|
59
74
|
DEFAULT_HANDLER_DIR = '/Library/Application Support/Chook'.freeze
|
60
75
|
|
61
|
-
#
|
62
|
-
|
76
|
+
# Handlers that are only called by name using the route:
|
77
|
+
# post '/handler/:handler_name'
|
78
|
+
# are located in this subdirection of the handler directory
|
79
|
+
NAMED_HANDLER_SUBDIR = 'NamedHandlers'.freeze
|
63
80
|
|
64
|
-
#
|
65
|
-
|
66
|
-
@loaded_handler = nil
|
81
|
+
# internal handler files must match this regex somewhere
|
82
|
+
INTERNAL_HANDLER_BLOCK_START_RE = /Chook.event_handler( ?\{| do) *\|/
|
67
83
|
|
68
|
-
#
|
84
|
+
# self loaded_handler=
|
69
85
|
#
|
70
|
-
# @return [
|
86
|
+
# @return [Obj,nil] the most recent Proc loaded from a handler file.
|
71
87
|
# destined for storage in @handlers
|
72
88
|
#
|
73
89
|
def self.loaded_handler
|
74
90
|
@loaded_handler
|
75
91
|
end
|
76
92
|
|
77
|
-
#
|
93
|
+
# A holding place for internal handlers as they are loaded
|
94
|
+
# before being added to the @handlers Hash
|
95
|
+
# see Chook.event_handler(&block)
|
78
96
|
#
|
79
|
-
# @param a_proc [
|
97
|
+
# @param a_proc [Object] An object instance with a #handle method
|
80
98
|
#
|
81
|
-
def self.loaded_handler=(
|
82
|
-
@loaded_handler =
|
99
|
+
def self.loaded_handler=(anon_obj)
|
100
|
+
@loaded_handler = anon_obj
|
83
101
|
end
|
84
102
|
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
|
90
|
-
|
91
|
-
#
|
103
|
+
# Getter for @handlers
|
104
|
+
#
|
105
|
+
# @return [Hash{String => Array}] a mapping of Event Names as they
|
106
|
+
# come from the JSS to an Array of handlers for the event.
|
107
|
+
# The handlers are either Pathnames to executable external handlers
|
108
|
+
# or Objcts with a #handle method, for internal handlers
|
109
|
+
# (The objects also have a #handler_file attribute that is the Pathname)
|
92
110
|
#
|
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
111
|
def self.handlers
|
98
|
-
@handlers
|
112
|
+
@handlers ||= {}
|
99
113
|
end
|
100
114
|
|
101
|
-
#
|
102
|
-
|
115
|
+
# Handlers can check Chook::HandledEvent::Handlers.reloading?
|
116
|
+
# and do stuff if desired.
|
117
|
+
def self.reloading?
|
118
|
+
@reloading
|
119
|
+
end
|
120
|
+
|
121
|
+
# getter for @named_handlers
|
122
|
+
# These handlers are called by name via the route
|
123
|
+
# " post '/handler/:handler_name'"
|
124
|
+
#
|
125
|
+
# They are not tied to any event type by their filenames
|
126
|
+
# its up to the writers of the handlers to make sure
|
127
|
+
# the webhook that calls them is sending the correct event
|
128
|
+
# type.
|
129
|
+
#
|
130
|
+
# The data structure of @named_handlers is a
|
131
|
+
# Hash of Strings to Pathnames or Anon Objects:
|
132
|
+
# {
|
133
|
+
# handler_filename => Pathname or Obj,
|
134
|
+
# handler_filename => Pathname or Obj,
|
135
|
+
# handler_filename => Pathname or Obj
|
136
|
+
# }
|
137
|
+
#
|
138
|
+
# @return [Hash {String => Pathname, Proc}]
|
139
|
+
def self.named_handlers
|
140
|
+
@named_handlers ||= {}
|
141
|
+
end
|
142
|
+
|
143
|
+
# the Pathname objects for all loaded handlers
|
144
|
+
#
|
145
|
+
# @return [Array<Pathname>]
|
146
|
+
#
|
147
|
+
def self.all_handler_paths
|
148
|
+
hndlrs = named_handlers.values
|
149
|
+
hndlrs += handlers.values.flatten
|
150
|
+
hndlrs.map do |hndlr|
|
151
|
+
hndlr.is_a?(Pathname) ? hndlr : hndlr.handler_file
|
152
|
+
end
|
153
|
+
end
|
103
154
|
|
104
155
|
# Load all the event handlers from the handler_dir or an arbitrary dir.
|
105
156
|
#
|
157
|
+
#
|
158
|
+
# Handler files must be either:
|
159
|
+
# - An executable file, which will have the raw JSON from the JSS piped
|
160
|
+
# to it's stdin when executed
|
161
|
+
# or
|
162
|
+
# - A non-executable file of ruby code like this:
|
163
|
+
# Chook.event_handler do |event|
|
164
|
+
# # your code goes here.
|
165
|
+
# end
|
166
|
+
#
|
167
|
+
# (see the Chook README for details about writing the ruby handlers)
|
168
|
+
#
|
106
169
|
# @param from_dir [String, Pathname] directory from which to load the
|
107
170
|
# handlers. Defaults to CONFIG.handler_dir or DEFAULT_HANDLER_DIR if
|
108
171
|
# config is unset
|
@@ -112,27 +175,55 @@ module Chook
|
|
112
175
|
#
|
113
176
|
# @return [void]
|
114
177
|
#
|
115
|
-
def self.load_handlers(from_dir: Chook
|
178
|
+
def self.load_handlers(from_dir: Chook.config.handler_dir, reload: false)
|
179
|
+
# use default if needed
|
116
180
|
from_dir ||= DEFAULT_HANDLER_DIR
|
181
|
+
handler_dir = Pathname.new(from_dir)
|
182
|
+
named_handler_dir = handler_dir + NAMED_HANDLER_SUBDIR
|
183
|
+
load_type = 'Loading'
|
184
|
+
|
117
185
|
if reload
|
118
|
-
@
|
186
|
+
@reloading = true
|
119
187
|
@handlers = {}
|
188
|
+
@named_handlers = {}
|
120
189
|
@loaded_handler = nil
|
190
|
+
load_type = 'Re-loading'
|
121
191
|
end
|
122
192
|
|
123
|
-
|
124
|
-
|
193
|
+
# General Handlers
|
194
|
+
Chook.logger.info "#{load_type} general handlers from directory: #{handler_dir}"
|
195
|
+
if handler_dir.directory? && handler_dir.readable?
|
196
|
+
handler_dir.children.each do |handler_file|
|
197
|
+
# ignore if marked to
|
198
|
+
next if handler_file.basename.to_s.start_with? DO_NOT_LOAD_PREFIX
|
199
|
+
|
200
|
+
load_general_handler(handler_file) if handler_file.file? && handler_file.readable?
|
201
|
+
end
|
202
|
+
Chook.logger.info handlers.empty? ? 'No general handlers found' : "Loaded #{handlers.values.flatten.size} general handlers for #{handlers.keys.size} event triggers"
|
203
|
+
else
|
204
|
+
Chook.logger.error "General handler directory '#{from_dir}' not a readable directory. No general handlers loaded. "
|
205
|
+
end
|
206
|
+
|
207
|
+
# Named Handlers
|
208
|
+
Chook.logger.info "#{load_type} named handlers from directory: #{named_handler_dir}"
|
209
|
+
if named_handler_dir.directory? && named_handler_dir.readable?
|
210
|
+
named_handler_dir.children.each do |handler_file|
|
211
|
+
# ignore if marked to
|
212
|
+
next if handler_file.basename.to_s.start_with? DO_NOT_LOAD_PREFIX
|
125
213
|
|
126
|
-
|
127
|
-
|
214
|
+
load_named_handler(handler_file) if handler_file.file? && handler_file.readable?
|
215
|
+
end
|
216
|
+
Chook.logger.info "Loaded #{named_handlers.size} named handlers"
|
217
|
+
else
|
218
|
+
Chook.logger.error "Named handler directory '#{named_handler_dir}' not a readable directory. No named handlers loaded. "
|
128
219
|
end
|
129
220
|
|
130
|
-
@
|
131
|
-
@handlers.values.flatten.size
|
221
|
+
@reloading = false
|
132
222
|
end # load handlers
|
133
223
|
|
134
|
-
# Load
|
135
|
-
#
|
224
|
+
# Load a general event handler from a file.
|
225
|
+
#
|
226
|
+
# General Handler files must begin with the name of the event they handle,
|
136
227
|
# e.g. ComputerAdded, followed by: nothing, a dot, a dash, or
|
137
228
|
# and underscore. Case doesn't matter.
|
138
229
|
# So all of these are OK:
|
@@ -142,49 +233,113 @@ module Chook
|
|
142
233
|
# Computeradded-update-ldap
|
143
234
|
# There can be as many as desired for each event.
|
144
235
|
#
|
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
|
236
|
+
# @param handler_file [Pathname] the file from which to load the handler
|
157
237
|
#
|
158
238
|
# @return [void]
|
159
239
|
#
|
160
|
-
def self.
|
161
|
-
|
240
|
+
def self.load_general_handler(handler_file)
|
241
|
+
Chook.logger.debug "Starting load of general handler file '#{handler_file.basename}'"
|
242
|
+
|
162
243
|
event_name = event_name_from_handler_filename(handler_file)
|
163
|
-
|
244
|
+
unless event_name
|
245
|
+
Chook.logger.debug "Ignoring general handler file '#{handler_file.basename}': Filename doesn't start with event name"
|
246
|
+
return
|
247
|
+
end
|
164
248
|
|
165
249
|
# create an array for this event's handlers, if needed
|
166
|
-
|
250
|
+
handlers[event_name] ||= []
|
167
251
|
|
252
|
+
# external? if so, its executable and we only care about its pathname
|
168
253
|
if handler_file.executable?
|
169
|
-
|
170
|
-
|
171
|
-
@handlers[event_name] << handler_file
|
172
|
-
puts "===> Loaded executable handler file '#{handler_file.basename}'"
|
173
|
-
end
|
254
|
+
Chook.logger.info "Loading external general handler file '#{handler_file.basename}' for #{event_name} events"
|
255
|
+
handlers[event_name] << handler_file
|
174
256
|
return
|
175
257
|
end
|
176
258
|
|
177
|
-
#
|
178
|
-
|
179
|
-
|
180
|
-
if @loaded_handler
|
181
|
-
|
182
|
-
|
183
|
-
|
259
|
+
# Internal, we store an object with a .handle method
|
260
|
+
Chook.logger.info "Loading internal general handler file '#{handler_file.basename}' for #{event_name} events"
|
261
|
+
load_internal_handler handler_file
|
262
|
+
handlers[event_name] << @loaded_handler if @loaded_handler
|
263
|
+
|
264
|
+
end # self.load_general_handler(handler_file)
|
265
|
+
|
266
|
+
# Load a named event handler from a file.
|
267
|
+
#
|
268
|
+
# Named Handler files can have any name, as they are called directly
|
269
|
+
# from a Jamf webhook via URL.
|
270
|
+
#
|
271
|
+
# @param handler_file [Pathname] the file from which to load the handler
|
272
|
+
#
|
273
|
+
# @return [void]
|
274
|
+
#
|
275
|
+
def self.load_named_handler(handler_file)
|
276
|
+
Chook.logger.debug "Starting load of named handler file '#{handler_file.basename}'"
|
277
|
+
|
278
|
+
# external? if so, its executable and we only care about its pathname
|
279
|
+
if handler_file.executable?
|
280
|
+
Chook.logger.info "Loading external named handler file '#{handler_file.basename}'"
|
281
|
+
named_handlers[handler_file.basename.to_s] = handler_file
|
282
|
+
return
|
283
|
+
end
|
284
|
+
|
285
|
+
# Internal, we store an object with a .handle method
|
286
|
+
Chook.logger.info "Loading internal named handler file '#{handler_file.basename}'"
|
287
|
+
load_internal_handler handler_file
|
288
|
+
named_handlers[handler_file.basename.to_s] = @loaded_handler if @loaded_handler
|
289
|
+
end # self.load_general_handler(handler_file)
|
290
|
+
|
291
|
+
# if the given file is executable, store it's path as a handler for the event
|
292
|
+
#
|
293
|
+
# @return [Boolean] did we load an external handler?
|
294
|
+
#
|
295
|
+
def self.load_external_handler(handler_file, event_name, named)
|
296
|
+
return false unless handler_file.executable?
|
297
|
+
|
298
|
+
say_named = named ? 'named ' : ''
|
299
|
+
Chook.logger.info "Loading #{say_named}external handler file '#{handler_file.basename}' for #{event_name} events"
|
300
|
+
|
301
|
+
if named
|
302
|
+
named_handlers[event_name][handler_file.basename.to_s] = handler_file
|
184
303
|
else
|
185
|
-
|
304
|
+
# store the Pathname, we'll pipe JSON to it
|
305
|
+
handlers[event_name] << handler_file
|
306
|
+
end
|
307
|
+
|
308
|
+
true
|
309
|
+
end
|
310
|
+
|
311
|
+
# if a given path is not executable, try to load it as an internal handler
|
312
|
+
#
|
313
|
+
# @param handler_file[Pathname] the handler file
|
314
|
+
#
|
315
|
+
# @return [Object] and anonymous object that has a .handle method
|
316
|
+
#
|
317
|
+
def self.load_internal_handler(handler_file)
|
318
|
+
# load the file. If written correctly, it will
|
319
|
+
# put an anon. Object with a #handle method into @loaded_handler
|
320
|
+
unless handler_file.read =~ INTERNAL_HANDLER_BLOCK_START_RE
|
321
|
+
Chook.logger.error "Internal handler file '#{handler_file}' missing event_handler block"
|
322
|
+
return nil
|
323
|
+
end
|
324
|
+
|
325
|
+
# reset @loaded_handler - the `load` call will refill it
|
326
|
+
# see Chook.event_handler
|
327
|
+
@loaded_handler = nil
|
328
|
+
|
329
|
+
begin
|
330
|
+
load handler_file.to_s
|
331
|
+
raise '@loaded handler nil after loading file' unless @loaded_handler
|
332
|
+
rescue => e
|
333
|
+
Chook.logger.error "FAILED loading internal handler file '#{handler_file}': #{e}"
|
334
|
+
return
|
186
335
|
end
|
187
|
-
|
336
|
+
|
337
|
+
# add a method to the object to get its Pathname
|
338
|
+
@loaded_handler.define_singleton_method(:handler_file) { handler_file }
|
339
|
+
|
340
|
+
# return it
|
341
|
+
@loaded_handler
|
342
|
+
end
|
188
343
|
|
189
344
|
# Given a handler filename, return the event name it wants to handle
|
190
345
|
#
|
@@ -194,9 +349,16 @@ module Chook
|
|
194
349
|
# @return [String,nil] The matching event name or nil if no match
|
195
350
|
#
|
196
351
|
def self.event_name_from_handler_filename(filename)
|
352
|
+
filename = filename.basename
|
197
353
|
@event_names ||= Chook::Event::EVENTS.keys
|
198
|
-
desired_event_name = filename.
|
199
|
-
@event_names.select { |n| desired_event_name.casecmp(n).zero? }.first
|
354
|
+
desired_event_name = filename.to_s.split(/\.|-|_/).first
|
355
|
+
ename = @event_names.select { |n| desired_event_name.casecmp(n).zero? }.first
|
356
|
+
if ename
|
357
|
+
Chook.logger.debug "Found event name '#{ename}' at start of filename '#{filename}'"
|
358
|
+
else
|
359
|
+
Chook.logger.debug "No known event name at start of filename '#{filename}'"
|
360
|
+
end
|
361
|
+
ename
|
200
362
|
end
|
201
363
|
|
202
364
|
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
|