brpm_content_framework 0.1.55

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +38 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +21 -0
  6. data/README.md +308 -0
  7. data/Rakefile +23 -0
  8. data/TO_BE_MIGRATED.txt +9 -0
  9. data/architecture.png +0 -0
  10. data/automations/direct_execute.meta +10 -0
  11. data/automations/direct_execute.rb +10 -0
  12. data/automations/install_module.meta +10 -0
  13. data/automations/install_module.rb +13 -0
  14. data/bin/brpm_install +30 -0
  15. data/bin/brpm_uninstall +30 -0
  16. data/bin/event_handler +63 -0
  17. data/bin/webhook_receiver +49 -0
  18. data/brpm_content.gemspec +31 -0
  19. data/config.yml +8 -0
  20. data/infrastructure/.bashrc +6 -0
  21. data/infrastructure/.brpm +2 -0
  22. data/infrastructure/config/customer_include.rb +26 -0
  23. data/infrastructure/config/server.yml +3 -0
  24. data/infrastructure/log.html +39 -0
  25. data/infrastructure/scripts/backup_database.sh +19 -0
  26. data/infrastructure/scripts/ddns.sh +10 -0
  27. data/infrastructure/scripts/install_brpm.sh +63 -0
  28. data/infrastructure/scripts/maintenance.sh +4 -0
  29. data/infrastructure/scripts/patch_brpm.sh +90 -0
  30. data/infrastructure/scripts/restore_database.sh +33 -0
  31. data/infrastructure/scripts/run_event_handler.cmd +19 -0
  32. data/infrastructure/scripts/run_event_handler.sh +20 -0
  33. data/infrastructure/scripts/run_webhook_receiver.cmd +15 -0
  34. data/infrastructure/scripts/run_webhook_receiver.sh +15 -0
  35. data/infrastructure/silent_install_options_4.6.txt +93 -0
  36. data/infrastructure/silent_install_options_upgrade_4.6.txt +92 -0
  37. data/infrastructure/smtp_settings.rb +42 -0
  38. data/lib/brpm_auto.rb +358 -0
  39. data/lib/brpm_script_executor.rb +80 -0
  40. data/lib/logging/brpm_logger.rb +39 -0
  41. data/lib/logging/logger_base.rb +36 -0
  42. data/lib/logging/simple_logger.rb +27 -0
  43. data/lib/module_installer.rb +483 -0
  44. data/lib/params/all_params.rb +80 -0
  45. data/lib/params/integration_settings.rb +27 -0
  46. data/lib/params/params.rb +174 -0
  47. data/lib/params/params_base.rb +81 -0
  48. data/lib/params/request_params.rb +38 -0
  49. data/lib/rest_api.rb +155 -0
  50. data/lib/semaphore.rb +79 -0
  51. data/lib/utilities.rb +317 -0
  52. data/lib/version_control/git.rb +192 -0
  53. data/lib/version_control/svn.rb +221 -0
  54. data/lib/write_to.rb +1 -0
  55. data/tests/all_params_spec.rb +116 -0
  56. data/tests/brpm_auto_spec.rb +84 -0
  57. data/tests/customer_include/config/customer_include.rb +10 -0
  58. data/tests/customer_include/config/server.yml +3 -0
  59. data/tests/customer_include_spec.rb +29 -0
  60. data/tests/gemspec_spec.rb +11 -0
  61. data/tests/module_installer_spec.rb +46 -0
  62. data/tests/params_spec.rb +172 -0
  63. data/tests/request_params_spec.rb +86 -0
  64. data/tests/server_yaml_spec.rb +19 -0
  65. data/tests/spec_helper.rb +64 -0
  66. data/to_be_migrated/brpm_framework.rb +88 -0
  67. data/to_be_migrated/customer_include_default.rb +25 -0
  68. data/to_be_migrated/local_jirb.rb +15 -0
  69. data/to_be_migrated/resource_framework.rb +211 -0
  70. data/transport/dispatch_baa.rb +355 -0
  71. data/transport/dispatch_base.rb +345 -0
  72. data/transport/dispatch_nsh.rb +248 -0
  73. data/transport/dispatch_ssh.rb +154 -0
  74. data/transport/transport_baa.rb +1095 -0
  75. data/transport/transport_nsh.rb +359 -0
  76. data/transport/transport_ssh.rb +220 -0
  77. metadata +204 -0
data/lib/brpm_auto.rb ADDED
@@ -0,0 +1,358 @@
1
+ require "bundler"
2
+ require "yaml"
3
+
4
+ class BrpmAuto
5
+ private_class_method :new
6
+
7
+ class << self
8
+ attr_reader :config
9
+ attr_reader :version
10
+ attr_reader :logger
11
+ attr_reader :params
12
+ attr_reader :request_params
13
+ attr_reader :all_params
14
+ attr_reader :integration_settings
15
+
16
+ attr_reader :framework_root_path
17
+
18
+ attr_reader :gems_root_path
19
+ attr_reader :gemfile_lock
20
+
21
+ def init
22
+ @framework_root_path = File.expand_path("#{File.dirname(__FILE__)}/..")
23
+
24
+ require "logging/brpm_logger"
25
+
26
+ require_libs_no_file_logging @framework_root_path
27
+
28
+ self.extend Utilities
29
+
30
+ @config = get_config
31
+ @version = @config["version"]
32
+
33
+ @gems_root_path = get_gems_root_path
34
+ end
35
+
36
+ def setup(params = {})
37
+ @params = Params.new(params)
38
+
39
+ load_server_params
40
+ load_customer_include_file
41
+
42
+ if @params.run_from_brpm
43
+ @logger = BrpmLogger.new
44
+ @request_params = RequestParams.new_for_request(@params.automation_results_dir, @params.application, @params.request_id)
45
+ else
46
+ initialize_logger(@params.log_file, @params.also_log_to_console)
47
+ initialize_request_params(@params.output_dir)
48
+ end
49
+
50
+ @all_params = AllParams.new(@params, @request_params)
51
+
52
+ if @params["SS_integration_dns"]
53
+ @integration_settings = IntegrationSettings.new(
54
+ @params["SS_integration_dns"],
55
+ @params["SS_integration_username"],
56
+ @params["SS_integration_password"],
57
+ @params["SS_integration_details"],
58
+ @params["SS_project_server"],
59
+ @params["SS_project_server_id"]
60
+ )
61
+ elsif defined?(SS_integration_dns)
62
+ @integration_settings = IntegrationSettings.new(
63
+ SS_integration_dns,
64
+ SS_integration_username,
65
+ SS_integration_password,
66
+ SS_integration_details,
67
+ SS_project_server,
68
+ SS_project_server_id
69
+ )
70
+ end
71
+ end
72
+
73
+ def require_module(module_name, module_version = nil)
74
+ module_version ||= get_latest_installed_version(module_name)
75
+ module_gem_path = get_module_gem_path(module_name, module_version)
76
+
77
+ if File.exists?(module_gem_path)
78
+ BrpmAuto.log "Found module #{module_name} #{module_version || ""} in gem path #{module_gem_path}."
79
+ else
80
+ raise Gem::GemNotFoundException, "Module #{module_name} version #{module_version} is not installed. Expected it on path #{module_gem_path}."
81
+ end
82
+
83
+ gemfile_lock_path = "#{module_gem_path}/Gemfile.lock"
84
+ if File.exists?(gemfile_lock_path) # TODO: decide how to react when multiple gems are 'required', each with a gemfile.lock
85
+ BrpmAuto.log "Found a Gemfile.lock: #{gemfile_lock_path} so parsing the specified version numbers for later usage..."
86
+ Dir.chdir(File.dirname(gemfile_lock_path)) do
87
+ @gemfile_lock = Bundler::LockfileParser.new(Bundler.read_file(gemfile_lock_path))
88
+ end
89
+ end
90
+
91
+ require_module_internal(module_name, module_version)
92
+ end
93
+
94
+ def require_libs_no_file_logging(module_path)
95
+ require_libs(module_path, false)
96
+ end
97
+
98
+ def require_libs(module_path, log = true)
99
+ lib_path = "#{module_path}/lib/**/*.rb"
100
+ require_files(Dir[lib_path], log)
101
+ end
102
+
103
+ def require_files(files, log = true)
104
+ failed_files = []
105
+ error_messages = []
106
+ files.each do |file|
107
+ if File.file?(file)
108
+ log ? (BrpmAuto.log "Loading #{file}...") : (print "Loading #{file}...\n")
109
+
110
+ begin
111
+ require file
112
+ rescue NameError => ne # when we require a set of files with inter-dependencies, the order is important, therefore we will retry the failed files later
113
+ failed_files << file
114
+ error_messages << ne
115
+ end
116
+ end
117
+ end
118
+ if failed_files.count > 0
119
+ if failed_files.count == files.count
120
+ raise NameError, "Following files failed loading: #{failed_files.join(", ")}\nError messages: #{error_messages.join(", ")}"
121
+ else
122
+ require_files(failed_files, log)
123
+ end
124
+ end
125
+ end
126
+
127
+ def load_server_params
128
+ server_config_file_path = "#{self.params.config_dir}/server.yml"
129
+ if File.exists?(server_config_file_path)
130
+ server_config = YAML.load_file(server_config_file_path)
131
+ server_config.each do |key, value|
132
+ @params[key] = value unless @params.has_key?(key)
133
+ end
134
+ end
135
+ end
136
+
137
+ def load_customer_include_file
138
+ customer_include_file_path = "#{self.params.config_dir}/customer_include.rb"
139
+ if File.exists?(customer_include_file_path)
140
+ load customer_include_file_path # use load instead of require to avoid having to restart BRPM after modifying the customer include file in a resource automation scenario
141
+ if defined?(get_customer_include_params)
142
+ customer_include_params = get_customer_include_params
143
+ customer_include_params.each do |key, value|
144
+ @params[key] = value
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ def initialize_logger(log_file, also_log_to_console = false)
151
+ @logger = SimpleLogger.new(log_file, also_log_to_console)
152
+ end
153
+
154
+ def run_from_brpm
155
+ @params.run_from_brpm
156
+ end
157
+
158
+ def log(message)
159
+ @logger.log(message)
160
+ end
161
+
162
+ def log_error(message)
163
+ @logger.log_error(message)
164
+ end
165
+
166
+ def message_box(message, m_type = "sep")
167
+ @logger.message_box(message, m_type)
168
+ end
169
+
170
+ def initialize_request_params(path)
171
+ @request_params = RequestParams.new(path)
172
+ end
173
+
174
+ def get_request_params_for_request(automation_results_dir, application, request_id)
175
+ RequestParams.new_for_request(automation_results_dir, application, request_id)
176
+ end
177
+
178
+ def initialize_integration_settings(dns, username, password, details)
179
+ @integration_settings = IntegrationSettings.new(dns, username, password, details)
180
+ end
181
+
182
+ def get_gems_root_path
183
+ if ENV["BRPM_CONTENT_HOME"]
184
+ ENV["BRPM_CONTENT_HOME"] # gemset location is overridden
185
+ elsif ENV["BRPM_HOME"]
186
+ "#{ENV["BRPM_HOME"]}/modules" # default gemset location when BRPM is installed
187
+ elsif ENV["GEM_HOME"]
188
+ ENV["GEM_HOME"] # default gemset location when BRPM is not installed
189
+ else
190
+ raise "Unable to find out the gems root path."
191
+ end
192
+ end
193
+
194
+ ###############################################################################################################################
195
+ # Assure backward compatibility with the ssh_script_header methods when running the automation scripts in a separate process
196
+ def set_property_flag(prop, value = nil)
197
+ acceptable_fields = ["name", "value", "environment", "component", "global", "private"]
198
+ flag = "#------ Block to Set Property ---------------#\n"
199
+ if value.nil?
200
+ flag += set_build_flag_data("properties", prop, acceptable_fields)
201
+ else
202
+ flag += "$$SS_Set_property{#{prop}=>#{value}}$$"
203
+ end
204
+ flag += "\n#------- End Set Property ---------------#\n"
205
+ BrpmAuto.log flag
206
+ flag
207
+ end
208
+
209
+ def set_server_flag(servers)
210
+ # servers = "server_name, env\ncserver2_name, env2"
211
+ acceptable_fields = ["name", "environment", "group"]
212
+ flag = "#------ Block to Set Servers ---------------#\n"
213
+ flag += set_build_flag_data("servers", servers, acceptable_fields)
214
+ flag += "\n#------ End Set Servers ---------------#\n"
215
+ BrpmAuto.log flag
216
+ flag
217
+ end
218
+
219
+ def set_component_flag(components)
220
+ # comps = "comp_name, version\ncomp2_name, version2"
221
+ flag = "#------ Block to Set Components ---------------#\n"
222
+ acceptable_fields = ["name", "version", "environment", "application"]
223
+ flag += set_build_flag_data("components", components, acceptable_fields)
224
+ flag += "\n#------ End Set Components ---------------#\n"
225
+ BrpmAuto.log flag
226
+ flag
227
+ end
228
+
229
+ def set_titles_acceptable?(cur_titles, acceptable_titles)
230
+ cur_titles.each.reject{ |cur| acceptable_titles.include?(cur)}.count == 0
231
+ end
232
+
233
+ def set_build_flag_data(set_item, set_data, acceptable_titles)
234
+ flag = ""; msg = ""
235
+ lines = set_data.split("\n")
236
+ titles = lines[0].split(",").map{ |it| it.strip }
237
+ if set_titles_acceptable?(titles, acceptable_titles)
238
+ flag += "$$SS_Set_#{set_item}{\n"
239
+ flag += "#{titles.join(", ")}\n"
240
+ lines[1..-1].each do |line|
241
+ if line.split(",").count == titles.count
242
+ flag += "#{line}\n"
243
+ else
244
+ msg += "Skipped: #{line}"
245
+ end
246
+ end
247
+ flag += "}$$\n"
248
+ else
249
+ flag += "ERROR - Unable to set #{set_item} - improper format\n"
250
+ end
251
+ flag += msg
252
+ end
253
+
254
+ def set_application_version(prop, value)
255
+ # set_application_flag(app_name, version)
256
+ flag = "#------ Block to Set Application Version ---------------#\n"
257
+ flag += "$$SS_Set_application{#{prop}=>#{value}}$$"
258
+ flag += "\n#------ End Set Application ---------------#\n"
259
+ BrpmAuto.log(flag)
260
+ flag
261
+ end
262
+
263
+ def pack_response(argument_name, response)
264
+ flag = "#------ Block to Set Pack Response ---------------#\n"
265
+ unless argument_name.nil?
266
+ if response.is_a?(Hash)
267
+ # Used for out-table output parameter
268
+ flag += "$$SS_Pack_Response{#{argument_name}@@#{response.to_json}}$$"
269
+ else
270
+ flag += "$$SS_Pack_Response{#{argument_name}=>#{response}}$$"
271
+ end
272
+ end
273
+ flag += "\n#------- End Set Pack Response Block ---------------#\n"
274
+ BrpmAuto.log flag
275
+ flag
276
+ end
277
+ ###############################################################################################################################
278
+
279
+ private
280
+
281
+ def require_module_internal(module_name, module_version)
282
+ module_path = get_module_gem_path(module_name, module_version)
283
+
284
+ module_config_file_path = "#{module_path}/config.yml"
285
+
286
+ if File.exist?(module_config_file_path)
287
+ module_config = YAML.load_file(module_config_file_path)
288
+
289
+ if module_config["dependencies"]
290
+ BrpmAuto.log "Loading the dependent modules..."
291
+ module_config["dependencies"].each do |dependency|
292
+ if dependency.is_a?(Hash)
293
+ dep_module_name = dependency.keys[0]
294
+ if @gemfile_lock
295
+ dep_module_version = get_version_from_gemfile_lock(dep_module_name)
296
+ else
297
+ dep_module_version = dependency.values[0]["version"]
298
+ end
299
+ else
300
+ dep_module_name = dependency
301
+
302
+ if @gemfile_lock
303
+ dep_module_version = get_version_from_gemfile_lock(dep_module_name)
304
+ else
305
+ dep_module_version = get_latest_installed_version(dep_module_name)
306
+ end
307
+ end
308
+
309
+ BrpmAuto.log "Loading module #{dep_module_name} version #{dep_module_version}..."
310
+ require_module_internal(dep_module_name, dep_module_version)
311
+ end
312
+ end
313
+ else
314
+ BrpmAuto.log "No config file found."
315
+ end
316
+
317
+ BrpmAuto.log "Loading the libraries of module #{module_name}..."
318
+ require_libs(module_path)
319
+
320
+ module_path
321
+ end
322
+
323
+ def get_config
324
+ YAML.load_file("#{@framework_root_path}/config.yml")
325
+ end
326
+
327
+ def get_module_gem_path(module_name, module_version)
328
+ "#{@gems_root_path}/gems/#{module_name}-#{module_version}"
329
+ end
330
+
331
+ def get_latest_installed_version(module_name)
332
+ latest_version_path = get_module_gem_path(module_name, "latest")
333
+ return "latest" if File.exists?(latest_version_path)
334
+
335
+ all_version_search = get_module_gem_path(module_name, "*")
336
+ version_paths = Dir.glob(all_version_search)
337
+
338
+ raise GemNoVersionsInstalledError, "Could not find any installed version of module #{module_name}. Expected them in #{get_module_gem_path(module_name, "*")}" if version_paths.empty?
339
+
340
+ versions = version_paths.map { |path| File.basename(path).sub("#{module_name}-", "") }
341
+
342
+ versions.sort{ |a, b| Gem::Version.new(a) <=> Gem::Version.new(b) }.last
343
+ end
344
+
345
+ def get_version_from_gemfile_lock(module_name)
346
+ spec = @gemfile_lock.specs.find { |spec| spec.name == module_name }
347
+ spec.version
348
+ end
349
+ end
350
+
351
+ self.init
352
+ end
353
+
354
+ class GemNoVersionsInstalledError < Gem::GemNotFoundException
355
+ end
356
+
357
+ class GemNotInstalledError < Gem::GemNotFoundException
358
+ end
@@ -0,0 +1,80 @@
1
+ require_relative "brpm_auto"
2
+
3
+ class BrpmScriptExecutor
4
+ class << self
5
+ def execute_automation_script(modul, name, params)
6
+ begin
7
+ BrpmAuto.setup(params)
8
+
9
+ BrpmAuto.log ""
10
+ BrpmAuto.log ">>>>>>>>>>>>>> START automation #{name}"
11
+ start_time = Time.now
12
+
13
+ BrpmAuto.log "Loading module #{modul}#{params["module_version"] ? " #{params["module_version"]}" : ""} and its dependencies..."
14
+ module_path = BrpmAuto.require_module(modul, params["module_version"])
15
+ BrpmAuto.log "Finished loading the module."
16
+
17
+ automation_script_path = "#{module_path}/automations/#{name}.rb"
18
+
19
+ BrpmAuto.log "Loading the automation script #{automation_script_path}..."
20
+ load automation_script_path
21
+
22
+ rescue Exception => e
23
+ BrpmAuto.log_error "#{e}"
24
+ BrpmAuto.log "\n\t" + e.backtrace.join("\n\t")
25
+
26
+ raise e
27
+ ensure
28
+ stop_time = Time.now
29
+ duration = 0
30
+ duration = stop_time - start_time unless start_time.nil?
31
+
32
+ BrpmAuto.log ">>>>>>>>>>>>>> STOP automation #{name} - total duration: #{Time.at(duration).utc.strftime("%H:%M:%S")}"
33
+ BrpmAuto.log ""
34
+
35
+ #load "#{File.dirname(__FILE__)}/write_to.rb" if BrpmAuto.params.run_from_brpm
36
+ end
37
+ end
38
+
39
+ alias_method :execute_automation_script_from_gem, :execute_automation_script
40
+
41
+ def execute_resource_automation_script(modul, name, params, parent_id, offset, max_records)
42
+ begin
43
+ BrpmAuto.setup(params)
44
+
45
+ BrpmAuto.log ""
46
+ BrpmAuto.log ">>>>>>>>>>>>>> START resource automation #{name}"
47
+ start_time = Time.now
48
+
49
+ BrpmAuto.log "Loading module #{modul} and its dependencies..."
50
+ module_path = BrpmAuto.require_module(modul) #TODO: from where should we get the module version of the script?
51
+ BrpmAuto.log "Finished loading the module."
52
+
53
+ automation_script_path = "#{module_path}/resource_automations/#{name}.rb"
54
+
55
+ BrpmAuto.log "Loading the resource automation script #{automation_script_path}..."
56
+ load automation_script_path
57
+
58
+ BrpmAuto.log "Calling execute_resource_automation_script(params, parent_id, offset, max_records)..."
59
+ execute_script(params, parent_id, offset, max_records)
60
+
61
+ rescue Exception => e
62
+ BrpmAuto.log_error "#{e}"
63
+ BrpmAuto.log "\n\t" + e.backtrace.join("\n\t")
64
+
65
+ raise e
66
+ ensure
67
+ stop_time = Time.now
68
+ duration = stop_time - start_time
69
+
70
+ BrpmAuto.log ">>>>>>>>>>>>>> STOP resource automation #{name} - total duration: #{Time.at(duration).utc.strftime("%H:%M:%S")}"
71
+ BrpmAuto.log ""
72
+
73
+ #load "#{File.dirname(__FILE__)}/write_to.rb" if BrpmAuto.params.run_from_brpm
74
+ end
75
+ end
76
+
77
+ alias_method :execute_resource_automation_script_from_gem, :execute_resource_automation_script
78
+ end
79
+ end
80
+
@@ -0,0 +1,39 @@
1
+ require_relative "logger_base"
2
+
3
+ class BrpmLogger < LoggerBase
4
+ attr_reader :request_log_file_path
5
+ attr_reader :step_run_log_file_path
6
+
7
+ def initialize
8
+ @step_number = BrpmAuto.params.step_number
9
+ @step_name = BrpmAuto.params.step_name
10
+
11
+ @request_log_file_path = "#{BrpmAuto.params.automation_results_dir}/#{BrpmAuto.params.request_id}.log"
12
+
13
+ # @step_run_log_file_path = "#{BrpmAuto.params.automation_results_dir}/#{BrpmAuto.params.request_id}_#{BrpmAuto.params.step_id}_#{BrpmAuto.params.run_key}.log"
14
+ @step_run_log_file_path = BrpmAuto.params.output_file
15
+
16
+ print "Logging to #{@step_run_log_file_path} and #{@request_log_file_path}\n" unless BrpmAuto.params.also_log_to_console
17
+ end
18
+
19
+ def log(message)
20
+ message = message.to_s # in case booleans or whatever are passed
21
+ timestamp = "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}"
22
+ log_message = ""
23
+
24
+ prefix = "#{timestamp}|#{'%2.2s' % @step_number}|#{'%-20.20s' % @step_name}|"
25
+ message.gsub!("\n", "\n" + (" " * prefix.length))
26
+
27
+ log_message = "#{prefix}#{message}\n"
28
+
29
+ File.open(@request_log_file_path, "a") do |log_file|
30
+ log_file.print(log_message)
31
+ end
32
+
33
+ File.open(@step_run_log_file_path, "a") do |log_file|
34
+ log_file.print(log_message)
35
+ end
36
+
37
+ print(log_message) if BrpmAuto.params.also_log_to_console
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ class LoggerBase
2
+ # Provides a pretty box for titles
3
+ #
4
+ # ==== Attributes
5
+ #
6
+ # * +msg+ - the text to output
7
+ # * +mtype+ - box type to display sep: a separator line, title a box around the message
8
+ def message_box(msg, mtype = "sep")
9
+ return "" if msg.nil? || msg.length < 1
10
+ tot = 72
11
+ msg = msg[0..64] if msg.length > 65
12
+
13
+ ilen = tot - msg.length
14
+
15
+ if mtype == "sep"
16
+ start = "##{"-" * (ilen/2).to_i} #{msg} "
17
+ res = "#{start}#{"-" * (tot- start.length + 1)}#"
18
+ else
19
+ res = "##{"-" * tot}#\n"
20
+ start = "##{" " * (ilen/2).to_i} #{msg} "
21
+ res += "#{start}#{" " * (tot- start.length + 1)}#\n"
22
+ res += "##{"-" * tot}#\n"
23
+ end
24
+
25
+ log(res)
26
+ end
27
+
28
+ def log_error(message)
29
+ log ""
30
+ log "******** ERROR ********"
31
+ log "An error has occurred"
32
+ log "#{message}"
33
+ log "***********************"
34
+ log ""
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ require_relative "logger_base"
2
+
3
+ class SimpleLogger < LoggerBase
4
+ def initialize(log_file, also_log_to_console = false)
5
+ @log_file = log_file
6
+ @also_log_to_console = also_log_to_console
7
+
8
+ print "Logging to #{@log_file}\n" unless also_log_to_console
9
+ end
10
+
11
+ def log(message)
12
+ message = message.to_s # in case booleans or whatever are passed
13
+ timestamp = "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}"
14
+ log_message = ""
15
+
16
+ prefix = "#{timestamp}|"
17
+ message = message.gsub("\n", "\n" + (" " * prefix.length))
18
+
19
+ log_message = "#{prefix}#{message}\n"
20
+
21
+ File.open(@log_file, "a") do |log_file|
22
+ log_file.print(log_message)
23
+ end
24
+
25
+ print(log_message) if @also_log_to_console
26
+ end
27
+ end