oh_my_log 1.0.2 → 1.0.3

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +10 -4
  4. data/Appraisals +9 -7
  5. data/README.md +30 -2
  6. data/blue_print/oh_my_log_initializer.rb +2 -4
  7. data/gemfiles/rails_4.2_stable.gemfile +2 -1
  8. data/gemfiles/rails_5.0_stable.gemfile +1 -1
  9. data/gemfiles/rails_5.1_stable.gemfile +1 -1
  10. data/gemfiles/rails_5.2_stable.gemfile +1 -1
  11. data/lib/oh_my_log/configuration.rb +9 -3
  12. data/lib/oh_my_log/log.rb +21 -3
  13. data/lib/oh_my_log/observer_factory.rb +3 -4
  14. data/lib/oh_my_log/orm/active_record.rb +10 -0
  15. data/lib/oh_my_log/orm/mongoid.rb +4 -0
  16. data/lib/oh_my_log/request.rb +4 -3
  17. data/lib/oh_my_log/result.rb +11 -4
  18. data/lib/oh_my_log/selector.rb +5 -4
  19. data/lib/oh_my_log/syslog_configuration.rb +30 -0
  20. data/lib/oh_my_log/syslog_implementor.rb +71 -0
  21. data/lib/oh_my_log/syslog_processors/r_f_c_3164.rb +36 -0
  22. data/lib/oh_my_log/version.rb +1 -1
  23. data/lib/oh_my_log.rb +19 -19
  24. data/lib/tasks/oh_my_log.rake +6 -0
  25. data/oh_my_log.gemspec +4 -2
  26. data/spec/controllers/foos_controller_spec.rb +31 -0
  27. data/spec/dummy/app/models/application_record.rb +10 -3
  28. data/spec/dummy/app/models/doo.rb +6 -0
  29. data/spec/dummy/app/models/foo.rb +6 -0
  30. data/spec/dummy/config/application.rb +3 -2
  31. data/spec/dummy/config/environments/test.rb +10 -11
  32. data/spec/dummy/config/initializers/migration_class.rb +10 -6
  33. data/spec/dummy/config/mongoid.yml +6 -0
  34. data/spec/orm/active_record.rb +12 -0
  35. data/spec/orm/mongoid.rb +11 -0
  36. data/spec/spec_helper.rb +6 -10
  37. data/spec/support/mongoid.yml +6 -0
  38. metadata +52 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3ad89d588fc30b289b18a1dc6c25a83b8d3cc0be5d25a97322107a92c3a940c
4
- data.tar.gz: d2989764451af11771bc75d854ab9124b4e27205048eb1642fedcd4162f244fe
3
+ metadata.gz: 9c4268bb618f37425f9cd4b005699fc75d43902b54a612b9bd49f26ae32e9997
4
+ data.tar.gz: 8f81f6d1c522e22db26ef46e4f04476dba1af2f3cedf63ec4256bc56dbbd2c16
5
5
  SHA512:
6
- metadata.gz: 80b18c3a433380f7a9624f93c2e1404ca6656a97064f8c39e754bac567aba13eead98a36a151074d4d5229b5a0681c55c91cc248e47cb1186b6e6abd5be14752
7
- data.tar.gz: d14628e11566426de6fc07bb61474b17ffb5655a12f864701d7557f8952a9451d410729edc37bdae8dae191a8585225a85e3ab5f07ab970c40066f44c76408da
6
+ metadata.gz: 2d8ab1ac0d258c0938eedc7ec31320e179c27e920d579c7bd3a1e4d4548a2290fa18fc24bab063378a8d919415eaf497ebe12904a1ec8ef9bcd29d6eed3ca190
7
+ data.tar.gz: 7a49e9f1fc303ed1ed39e21a0d45a9674c453f603aed0864f33306c4d71b8d16d7e6b956f5d213c7aab5ff1f7502b87f873aeba99e016bac192df77b3afea8ab
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3
1
+ 2.3.0
data/.travis.yml CHANGED
@@ -2,12 +2,18 @@ language: ruby
2
2
  before_install: gem install bundler -v '1.17.3'
3
3
  install: bundle _1.17.3_ install --jobs=3 --retry=3
4
4
  script: bundle exec rspec
5
+ services:
6
+ - mongodb
5
7
  rvm:
6
8
  - 2.3.0
7
9
  - 2.4.0
8
10
  - 2.5.0
9
11
  - 2.6.0
10
12
  - ruby-head
13
+ env:
14
+ matrix:
15
+ - OHMYLOG_ORM=active_record
16
+ - OHMYLOG_ORM=mongoid
11
17
  matrix:
12
18
  exclude:
13
19
  # Skip these combinations because they have incompatible dependencies
@@ -16,10 +22,10 @@ matrix:
16
22
  gemfile: gemfiles/rails_4.2_stable.gemfile
17
23
  - rvm: ruby-head
18
24
  gemfile: gemfiles/rails_4.2_stable.gemfile
19
- # - rvm: 2.3
20
- # gemfile: gemfiles/rails_6.0_beta.gemfile
21
- # - rvm: 2.4
22
- # gemfile: gemfiles/rails_6.0_beta.gemfile
25
+ # - rvm: 2.3
26
+ # gemfile: gemfiles/rails_6.0_beta.gemfile
27
+ # - rvm: 2.4
28
+ # gemfile: gemfiles/rails_6.0_beta.gemfile
23
29
  allow_failures:
24
30
  # - gemfile: gemfiles/rails_6.0_beta.gemfile
25
31
  # - rvm: ruby-head
data/Appraisals CHANGED
@@ -1,25 +1,27 @@
1
1
  appraise 'rails-4.2-stable' do
2
2
  gem 'rails', '~> 4.2.0'
3
- gem 'rails-observers'
3
+ gem 'bundler', '< 2'
4
+ gem "mongoid", "~> 4.0"
4
5
  end
5
6
 
6
7
  appraise 'rails-5.0-stable' do
7
8
  gem 'rails', '~> 5.0.0'
8
- gem 'rails-observers'
9
+ gem "mongoid", "~> 6.0"
9
10
  end
10
11
 
11
12
  appraise 'rails-5.1-stable' do
12
13
  gem 'rails', '~> 5.1.0'
13
- gem 'rails-observers'
14
+ gem "mongoid", "~> 6.0"
14
15
  end
15
16
 
16
-
17
17
  appraise 'rails-5.2-stable' do
18
18
  gem 'rails', '~> 5.2.0'
19
- gem 'rails-observers'
19
+ gem "mongoid", "~> 6.0"
20
20
  end
21
21
 
22
22
  # appraise 'rails-6.0-beta' do
23
- # gem 'rails', '~> 6.0.0.beta1'
24
- # gem 'rails-observers'
23
+ # gem 'rails', '~> 6.0.0.beta3'
24
+ # group :mongoid do
25
+ # gem "mongoid", "~> 6.0"
26
+ # end
25
27
  # end
data/README.md CHANGED
@@ -85,6 +85,8 @@ When using multiple selectors remember that if any of the conditions among all s
85
85
 
86
86
  >[read only] status_codes Hash(the key is the rule: ONLY/EXCEPT/ALL the value is an array of status codes)
87
87
 
88
+ >[read only] methods Hash(the key is the rule: ONLY/EXCEPT/ALL the value is an array of methods)
89
+
88
90
  ###### Instance methods:
89
91
 
90
92
  >set_controllers (controller ->Hash{string =>string[]})
@@ -95,10 +97,11 @@ When using multiple selectors remember that if any of the conditions among all s
95
97
 
96
98
  >set_status_codes (status_codes ->Hash{string =>Range[]})
97
99
 
100
+ >set_methods (methods ->Hash{string =>string[]})
101
+
98
102
  ###### Class methods:
99
103
 
100
- >universal_for(action: {"ALL" =>[]}, controllers: {"ALL" =>[]}) (inside the hash only or
101
- except you can put an array of actions)
104
+ >universal_for(action: {"ALL" =>[]}, controllers: {"ALL" =>[]}, methods: {"ALL" =>[]})
102
105
 
103
106
  Complex initializer example:
104
107
 
@@ -109,6 +112,7 @@ OhMyLog::Log.configure do |config|
109
112
  selector.set_controllers("EXCEPT" =>["ApplicationController"])
110
113
  selector.set_actions("ONLY" =>["index","create","destroy"])
111
114
  selector.set_status_codes("ONLY" =>[(0..200)])
115
+ selector.set_methods("EXCEPT" =>["GET"])
112
116
  selector.set_ips("EXCEPT"=>["192.168.0.1"])
113
117
  config.add_selector(selector)
114
118
  #put your configs here
@@ -174,6 +178,30 @@ end
174
178
  >changes string (changes that this model had before and after the action)
175
179
 
176
180
  ---
181
+
182
+ #### OhMyLog::SyslogConfiguration
183
+
184
+ ###### Class methods:
185
+
186
+ >[read only] processor_name string (the name of the processor in use)
187
+
188
+ >[read only] operation string/symbol (the operation to execute when the message is bigger that 1024 byte)
189
+
190
+ >use (processor_name, operation) (the name of the processor and the operation to apply)
191
+
192
+ >change_processor(processor_name)
193
+
194
+ >change_operation(operation) (supported operations are: split and trim)
195
+ ---
196
+
197
+ ### How to configure a syslog ready log:
198
+ * Include this in the config proc of the initializer:
199
+
200
+ ```sh
201
+ OhMyLog::SyslogConfiguration.use("RFC3164")
202
+ syslog = OhMyLog::SyslogImplementor.new(hostname: "Staging", priority: 101, tag: "HELLO", program_name: "WORLD")
203
+ config.syslog = syslog
204
+ ```
177
205
 
178
206
  ### Development
179
207
 
@@ -1,8 +1,6 @@
1
1
  OhMyLog::Log.configure do |config|
2
2
  config.print_log = true
3
3
  selector = OhMyLog::Log::Selector.universal_for(actions: {"EXCEPT" => ["index"]})
4
- #selector.set_status_codes("ONLY" => [(0..200)])
5
4
  config.add_selector(selector)
6
- OhMyLog.start if File.directory?(Rails.root + "app/models/observers/oh_my_log")
7
- #put your configs here
8
- end
5
+ end
6
+ OhMyLog.start
@@ -3,6 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 4.2.0"
6
- gem "rails-observers"
6
+ gem "bundler", "< 2"
7
+ gem "mongoid", "~> 4.0"
7
8
 
8
9
  gemspec path: "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 5.0.0"
6
- gem "rails-observers"
6
+ gem "mongoid", "~> 6.0"
7
7
 
8
8
  gemspec path: "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 5.1.0"
6
- gem "rails-observers"
6
+ gem "mongoid", "~> 6.0"
7
7
 
8
8
  gemspec path: "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 5.2.0"
6
- gem "rails-observers"
6
+ gem "mongoid", "~> 6.0"
7
7
 
8
8
  gemspec path: "../"
@@ -1,16 +1,17 @@
1
1
  module OhMyLog
2
2
  module Log
3
3
  class Configuration
4
- attr_accessor :models, :print_log, :record_history, :log_instance, :log_path
5
- attr_reader :selectors
4
+ attr_accessor :models, :print_log, :record_history, :log_instance, :syslog
5
+ attr_reader :selectors, :log_path
6
6
 
7
7
  def initialize(*args)
8
8
  @selectors = []
9
9
  #models not to track
10
10
  @models = {"ALL" => []}
11
11
  @print_log = true
12
- @log_instance = Logger.new(File.join(Rails.root, 'log/oh_my_log.log'))
12
+ @log_instance = Logger.new(File.join(Rails.root, 'log/oh_my_log.log')) unless @log_path
13
13
  @log_path = nil
14
+ @syslog = nil
14
15
  #do we wanna keep track of all the actions?
15
16
  @record_history = false
16
17
  end
@@ -23,6 +24,11 @@ module OhMyLog
23
24
  @selectors = []
24
25
  end
25
26
 
27
+ def log_path=(path)
28
+ @log_path = path
29
+ process_path
30
+ end
31
+
26
32
  def get_actions(controller)
27
33
  @selectors.each do |selector|
28
34
  return selector.actions if selector.controller == controller
data/lib/oh_my_log/log.rb CHANGED
@@ -26,7 +26,6 @@ module OhMyLog
26
26
  self.history = []
27
27
  yield(configuration)
28
28
  self.configuration.add_selector(Selector.universal_for) if self.configuration.selectors.empty?
29
- self.configuration.process_path
30
29
  end
31
30
 
32
31
  def self.clear
@@ -113,19 +112,38 @@ module OhMyLog
113
112
  return permitted_action
114
113
  end
115
114
 
115
+ def self.permitted_method?(selector, ctrl_method)
116
+ permitted_method = true
117
+ case selector.methods.keys[0]
118
+ when "EXCEPT"
119
+ selector.methods.values[0].each {|method| permitted_method = false if method.upcase.to_sym == ctrl_method}
120
+ when "ONLY"
121
+ selector.methods.values[0].each {|method| permitted_method = true if method.upcase.to_sym == ctrl_method}
122
+ when "ALL"
123
+ permitted_method = true
124
+ else
125
+ raise "UNDEFINED RULE: please us any of [ONLY/EXCEPT/ALL]"
126
+ end
127
+ return permitted_method
128
+ end
129
+
116
130
  #TODO: implement filtering by method
117
131
  def self.loggable?(params, status, method)
118
132
  ctrl_name = params["controller"]
119
133
  ctrl_action = params["action"].to_sym
134
+ ctrl_method = method.to_sym
120
135
  final_response = false
121
136
  self.configuration.selectors.each do |selector|
122
137
  final_response = permitted_range?(selector, status)
123
138
  return false unless final_response
124
139
 
125
- final_response = final_response && permitted_controller?(selector, ctrl_name)
140
+ final_response &= permitted_method?(selector, ctrl_method)
141
+ return false unless final_response
142
+
143
+ final_response &= permitted_controller?(selector, ctrl_name)
126
144
  return false unless final_response
127
145
 
128
- final_response = final_response && permitted_ip?(selector, Thread.current[:remote_ip])
146
+ final_response &= permitted_ip?(selector, Thread.current[:remote_ip])
129
147
  return false unless final_response
130
148
 
131
149
  return false unless permitted_action?(selector, ctrl_action)
@@ -19,8 +19,7 @@ module OhMyLog
19
19
  #rebuild folder if it's already there
20
20
  FileUtils.rm_rf(Rails.root + "app/models/observers/oh_my_log") if File.directory?(Rails.root + "app/models/observers/oh_my_log")
21
21
  FileUtils.mkdir_p(Rails.root + "app/models/observers/oh_my_log")
22
- generate_collection_for(ActiveRecord) if defined?(ActiveRecord)
23
- generate_collection_for(Mongoid) if defined?(Mongoid)
22
+ generate_collection_for(OHMYLOG_ORM.to_s.classify.constantize)
24
23
  end
25
24
 
26
25
  def self.remove_collection
@@ -69,10 +68,10 @@ module OhMyLog
69
68
  config_rule = Log.configuration_rule
70
69
  config_models = Log.configuration_models
71
70
  models = []
72
- if klass == ActiveRecord
71
+ if klass.to_s == 'ActiveRecord'
73
72
  models = ActiveRecord::Base.subclasses.collect {|type| type.name}
74
73
  models = models + ApplicationRecord.subclasses.collect {|type| type.name} if defined?(ApplicationRecord)
75
- elsif klass == Mongoid
74
+ elsif klass.to_s == 'Mongoid'
76
75
  models = Mongoid.models.collect {|type| type.name}
77
76
  end
78
77
  #reject modules
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record'
4
+ require 'rails-observers'
5
+ require 'rails/observers/activerecord/base'
6
+ module ActiveRecord
7
+ autoload :Observer, 'rails/observers/activerecord/observer'
8
+ end
9
+ require_relative "../active_record_observer"
10
+
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ require 'mongoid'
3
+ require 'mongoid-observers'
4
+ require_relative "../mongoid_observer"
@@ -2,7 +2,7 @@ module OhMyLog
2
2
  module Log
3
3
  #the request is what the user is trying to do
4
4
  class Request
5
- attr_reader :sender, :date, :params, :method, :status
5
+ attr_reader :sender, :date, :params, :method, :status, :path
6
6
 
7
7
  def initialize(args)
8
8
  @sender = args[:sender]
@@ -10,11 +10,12 @@ module OhMyLog
10
10
  @params = args[:params]
11
11
  @method = args[:method]
12
12
  @status = args[:status]
13
+ @path = args[:path]
13
14
  end
14
15
 
15
16
  def to_s
16
- user_info = @sender.try(:email)
17
- sender = !user_info.blank? ? user_info : Thread.current["remote_ip"]
17
+ user_info = @sender.email rescue nil
18
+ sender = user_info || Thread.current["remote_ip"]
18
19
  "#{@date}, #{sender}, #{@method}, #{@params}, #{@status}"
19
20
  end
20
21
  end
@@ -33,10 +33,17 @@ module OhMyLog
33
33
  private
34
34
 
35
35
  def print_into_log
36
- OhMyLog::Log.configuration.log_instance.info('REQUEST')
37
- OhMyLog::Log.configuration.log_instance.info(@request.to_s)
38
- OhMyLog::Log.configuration.log_instance.info('RESPONSE') unless @effects.empty?
39
- @effects.each {|effect| OhMyLog::Log.configuration.log_instance.info(effect.to_s)}
36
+ if OhMyLog::Log.configuration.syslog
37
+ data = OhMyLog::Log.configuration.syslog.print(ip: OhMyLog::Log.configuration.syslog.public_ip, user: @request.sender, url: @request.path, m: @request.method, s: @request.status, p: @request.params, request_time: @request.date)
38
+ data.each do |data_info|
39
+ OhMyLog::Log.configuration.log_instance.info(data_info)
40
+ end
41
+ else
42
+ OhMyLog::Log.configuration.log_instance.info('REQUEST')
43
+ OhMyLog::Log.configuration.log_instance.info(@request.to_s)
44
+ OhMyLog::Log.configuration.log_instance.info('RESPONSE') unless @effects.empty?
45
+ @effects.each {|effect| OhMyLog::Log.configuration.log_instance.info(effect.to_s)}
46
+ end
40
47
  end
41
48
 
42
49
  def calculate_effects
@@ -2,17 +2,18 @@ module OhMyLog
2
2
  module Log
3
3
  #Selector is a set of rule that Log.loggable? will have to respect
4
4
  class Selector
5
- attr_reader :controllers, :actions, :status_codes, :ips
5
+ attr_reader :controllers, :actions, :status_codes, :ips, :methods
6
6
  METHODS = ["GET", "HEAD", "POST", "PATCH", "PUT", "DELETE"].freeze
7
7
  ACTIONS = ["ONLY", "EXCEPT", "ALL"].freeze
8
8
  # TODO: add methods in the same style as anything else
9
9
  # and it will affect the parameter method in the loggable function in LOG.rb
10
10
  # EXCEPT O ONLY
11
- def initialize(controllers: default_hash_setting, actions: default_hash_setting, ips: default_hash_setting, status_codes: default_hash_setting)
11
+ def initialize(controllers: default_hash_setting, actions: default_hash_setting, ips: default_hash_setting, status_codes: default_hash_setting, methods: default_hash_setting)
12
12
  @controllers = controllers
13
13
  @actions = actions
14
14
  @ips = ips
15
15
  @status_codes = status_codes
16
+ @methods = methods
16
17
  build_attr_setters
17
18
  end
18
19
 
@@ -36,8 +37,8 @@ module OhMyLog
36
37
  end
37
38
  end
38
39
 
39
- def self.universal_for(actions: default_hash_setting, controllers: default_hash_setting)
40
- return Selector.new(controllers: controllers, actions: actions)
40
+ def self.universal_for(actions: default_hash_setting, controllers: default_hash_setting, methods: default_hash_setting)
41
+ return Selector.new(controllers: controllers, actions: actions, methods: methods)
41
42
  end
42
43
  end
43
44
  end
@@ -0,0 +1,30 @@
1
+ module OhMyLog
2
+ class SyslogConfiguration
3
+ @@processor_name = "RFC3164"
4
+ @@split_operation = "split"
5
+
6
+ def self.use(processor_name = nil, operation = nil)
7
+ change_processor(processor_name) if processor_name
8
+ change_operation(operation) if operation
9
+ end
10
+
11
+ def self.processor_name
12
+ return @@processor_name
13
+ end
14
+
15
+ def self.split_operation
16
+ return @@split_operation
17
+ end
18
+
19
+ def self.change_processor(processor_name)
20
+ raise "We don't support the #{processor_name} format" unless (("SyslogProcessors::#{processor_name.upcase}".constantize) rescue false)
21
+ @@processor_name = processor_name
22
+ end
23
+
24
+ def self.change_operation(operation)
25
+ operation = operation.to_s.downcase.to_sym
26
+ raise ArgumentError "Supported mode are: 'split' or 'trim'" unless [:split, :trim].include? operation
27
+ @@split_operation = operation
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,71 @@
1
+ require_relative 'syslog_configuration'
2
+ require 'net/http'
3
+ require 'syslog/logger'
4
+ require 'securerandom'
5
+
6
+ module OhMyLog
7
+ class SyslogImplementor
8
+ include "::SyslogProcessors::#{OhMyLog::SyslogConfiguration.processor_name.upcase}".constantize
9
+ attr_accessor :facility, :severity
10
+ attr_reader :public_ip, :tag
11
+
12
+ def initialize(hostname: nil, priority: nil, facility: nil, severity: nil, tag: nil, program_name: "NA", syslog_facility: "Syslog::LOG_LOCAL1")
13
+ @hostname = retrive_hostname
14
+ @public_ip = retrive_public_ip
15
+ @priority = priority
16
+ @facility = facility
17
+ @severity = severity
18
+ @tag = tag
19
+ @program_name = program_name
20
+ @syslog_facility = syslog_facility
21
+ OhMyLog::Log.configuration.log_instance = Syslog::Logger.new program_name, syslog_facility.constantize
22
+ # override_log_formatter
23
+ end
24
+
25
+ def new_using(processor_name)
26
+ OhMyLog::SyslogConfiguration.use(processor_name)
27
+ SyslogImplementor.new(hostname: @hostname, priority: @priority, facility: @facility, severity: @severity, tag: @tag, program_name: @program_name, syslog_facility: @syslog_facility)
28
+ end
29
+
30
+ #TODO no need to pass :ip we can retrieve it from this class
31
+ def print(params)
32
+ data = [super(params)]
33
+ if data[0].bytesize >= 1024
34
+ if OhMyLog::SyslogConfiguration.split_operation == :split
35
+ id = SecureRandom.hex(8)
36
+ message = message_text(ip: params[:ip], user: params[:sender], url: params[:url], m: params[:m], s: params[:s], p: params[:p])
37
+ data = []
38
+ priority = priority_text
39
+ header = header_text(params[:request_time])
40
+ base_msg = priority + header + "#{@tag}[ID=#{id}]:"
41
+ remaining_byte = 1023 - base_msg.bytesize
42
+ message_chunks = get_binary_chunks(message, remaining_byte)
43
+ message_chunks.each {|chunk_data| data << base_msg + chunk_data + ";"}
44
+ else
45
+ data[0] = get_binary_chunks(data[0], 1021)[0] + "..."
46
+ end
47
+ end
48
+ data
49
+ end
50
+
51
+ private
52
+
53
+ def get_binary_chunks(string, size)
54
+ Array.new(((string.length + size - 1) / size)) {|i| string.byteslice(i * size, size)}
55
+ end
56
+
57
+ # def override_log_formatter
58
+ # OhMyLog::Log.configuration.log_instance.formatter = proc do |severity, datetime, progname, msg|
59
+ # "#{msg}\n"
60
+ # end
61
+ # end
62
+
63
+ def retrive_public_ip
64
+ Net::HTTP.get(URI("http://checkip.amazonaws.com")).gsub("\n", "") rescue nil
65
+ end
66
+
67
+ def retrive_hostname
68
+ Socket.gethostname rescue nil
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,36 @@
1
+ module SyslogProcessors
2
+ module RFC3164
3
+ def calculate_priority
4
+ self.class.calculate_priority(facility: @facility, severity: @severity)
5
+ end
6
+
7
+ def priority_text
8
+ return "<#{@priority || calculate_priority}>"
9
+ end
10
+
11
+ def message_text(ip:, user:, url:, m:, s:, p:)
12
+ text = "#{@tag.upcase}:"
13
+ text += "ip=#{ip};"
14
+ text += "u=#{user};"
15
+ text += "url=#{url};"
16
+ text += "m=#{m};"
17
+ text += "s=#{s};"
18
+ text += "p=#{p};"
19
+ text
20
+ end
21
+
22
+ def header_text(request_time)
23
+ #request_time.to_time. + " #{@hostname}"
24
+ request_time.strftime("%b %-d %H:%M:%S") + " #{@public_ip || @hostname || "FAK"}"
25
+ end
26
+
27
+ def print(params)
28
+ priority_text + header_text(params[:request_time]) + " " + message_text(params.reject {|k| k == :request_time})
29
+ end
30
+
31
+ def self.calculate_priority(facility: nil, severity: nil)
32
+ raise "You need facility and severity to calculate the priority" unless facility && severity
33
+ facility * 8 + severity
34
+ end
35
+ end
36
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OhMyLog
4
- VERSION = '1.0.2'
4
+ VERSION = '1.0.3'
5
5
  end
data/lib/oh_my_log.rb CHANGED
@@ -1,26 +1,28 @@
1
- require 'rails/observers/activerecord/base'
2
- #force LOAD the gem "rails-observers"
3
- module ActiveRecord
4
- autoload :Observer, 'rails/observers/activerecord/observer'
5
- end
6
-
1
+ require 'rails'
2
+ OHMYLOG_ORM rescue OHMYLOG_ORM = :active_record
3
+ #creare una classe depency loader e usare il preload e l'after load
4
+ require_relative "oh_my_log/orm/#{OHMYLOG_ORM.to_s}"
7
5
  #load the gem's lib folder
8
- Dir[File.dirname(__FILE__) + '/oh_my_log/*.rb'].each do |file|
9
- name = File.basename(file, File.extname(file))
10
- #we are gonna skip this file FOR NOW since it depends of gem loaded after the rails initializer
11
- next if name == "mongoid_observer"
12
- require_relative "oh_my_log/" + name
6
+ sources = ["oh_my_log/syslog_processors/", "oh_my_log/"]
7
+ sources.each do |base_path|
8
+ Dir[File.dirname(__FILE__) + "/#{base_path}*.rb"].each do |file|
9
+ name = File.basename(file, File.extname(file))
10
+ next if (["mongoid_observer", "active_record_observer"]).include? name
11
+ require_relative base_path + name
12
+ end
13
13
  end
14
14
 
15
+
15
16
  module OhMyLog
16
17
  #call this after you configured the Log Module
17
18
  def self.start
19
+ return unless File.directory?(Rails.root + "app/models/observers/oh_my_log")
18
20
  activate
19
21
  #the main loop to get callbacks from controllers
20
22
  ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
21
23
  data = args[-1]
22
24
  if Log::loggable?(data[:params], data[:status], data[:method])
23
- request = Log::Request.new(sender: Thread.current[:user], date: Time.now.utc, params: data[:params], method: data[:method], status: data[:status])
25
+ request = Log::Request.new(sender: Thread.current[:user], date: Time.now.utc, params: data[:params], method: data[:method], status: data[:status], path: data[:path])
24
26
  result = Log::Result.new(request)
25
27
  result.record!
26
28
  end
@@ -29,12 +31,7 @@ module OhMyLog
29
31
  end
30
32
 
31
33
  def self.activate
32
- if defined?(Mongoid)
33
- require 'mongoid-observers'
34
- require_relative "oh_my_log/mongoid_observer"
35
- end
36
34
  begin
37
- require Rails.root + "config/initializers/oh_my_log_initializer.rb"
38
35
  ::OhMyLog::ObserverFactory.activate_observers
39
36
  rescue
40
37
  return "could not start the gem, did you run oh_my_log:install ?"
@@ -52,8 +49,11 @@ module OhMyLog
52
49
  p "Successfully destroyed the initializer!"
53
50
  end
54
51
 
52
+ def self.test_message(msg)
53
+ OhMyLog::Log.configuration.log_instance.info(msg)
54
+ end
55
+
55
56
  end
56
57
 
57
58
  #load the script to inject code to rails source and create rake task
58
- require_relative "railtie"
59
-
59
+ require_relative "railtie"
@@ -15,6 +15,12 @@ namespace :oh_my_log do
15
15
  OhMyLog.generate_initializer
16
16
  end
17
17
 
18
+ desc 'Write a test message int the logger'
19
+ # in futuro puoi passare direttamente qui alcune impostazioni dell' initialize
20
+ task test: :environment do
21
+ OhMyLog.test_message(ENV.fetch('MSG', 'Hello World!'))
22
+ end
23
+
18
24
  desc 'Install the gem by building initializer and observers'
19
25
  task install: :environment do
20
26
  Rake::Task['oh_my_log:generate_initializer'].invoke
data/oh_my_log.gemspec CHANGED
@@ -23,12 +23,14 @@ Gem::Specification.new do |s|
23
23
  else
24
24
  s.add_runtime_dependency 'railties', '>= 4.2.0', '< 6.0'
25
25
  end
26
- s.add_runtime_dependency("rails-observers", "~> 0.1.5")
26
+ s.add_runtime_dependency 'sqlite3', '~> 1.3.0'
27
+ s.add_runtime_dependency "rails-observers", "~> 0.1.5"
28
+ s.add_runtime_dependency 'mongoid', ">= 3.0"
29
+ s.add_runtime_dependency "mongoid-observers"
27
30
  s.add_development_dependency 'coveralls'
28
31
  s.add_development_dependency 'rubocop', '~> 0.59.2'
29
32
  s.add_development_dependency 'bundler'
30
33
  s.add_development_dependency 'appraisal'
31
- s.add_development_dependency 'sqlite3', '~> 1.3.10'
32
34
  s.add_development_dependency 'wwtd'
33
35
  s.add_development_dependency 'rspec-rails'
34
36
  end
@@ -17,6 +17,9 @@ RSpec.describe FoosController, type: :controller do
17
17
  config.print_log = true
18
18
  selector = oml::Selector.universal_for(actions: {"EXCEPT" => ["index"]})
19
19
  config.add_selector(selector)
20
+ OhMyLog::SyslogConfiguration.use("RFC3164")
21
+ syslog = OhMyLog::SyslogImplementor.new(hostname: "Staging", priority: 101, tag: "BRAINT", program_name: "audit", syslog_facility: "Syslog::LOG_LOCAL3")
22
+ config.syslog = syslog
20
23
  end
21
24
  end
22
25
 
@@ -60,6 +63,22 @@ RSpec.describe FoosController, type: :controller do
60
63
  put :create, params: {name: 'foo name'}
61
64
  expect(oml.last_recorded).to eq(nil)
62
65
  end
66
+ it "Should not log a get action if it's blacklisted" do
67
+ selector = OhMyLog::Log::Selector.new
68
+ selector.set_methods("EXCEPT" => ["GET"])
69
+ oml.configuration.reset_selectors
70
+ oml.configuration.add_selector(selector)
71
+ get :index
72
+ expect(oml.last_recorded).to eq(nil)
73
+ end
74
+ it "Should log a get action if it's whitelisted" do
75
+ selector = OhMyLog::Log::Selector.new
76
+ selector.set_methods("ONLY" => ["GET"])
77
+ oml.configuration.reset_selectors
78
+ oml.configuration.add_selector(selector)
79
+ get :index
80
+ expect(oml.last_recorded).not_to eq(nil)
81
+ end
63
82
  it "Should be able to correctly use multiple selector" do
64
83
  selector = OhMyLog::Log::Selector.new
65
84
  selector.set_controllers({"EXCEPT" => ["Foo"]})
@@ -81,6 +100,9 @@ RSpec.describe FoosController, type: :controller do
81
100
  config.print_log = true
82
101
  selector = oml::Selector.universal_for(actions: {"EXCEPT" => ["index"]})
83
102
  config.add_selector(selector)
103
+ OhMyLog::SyslogConfiguration.use("RFC3164")
104
+ syslog = OhMyLog::SyslogImplementor.new(hostname: "Staging", priority: 101, tag: "BRAINT", program_name: "audit", syslog_facility: "Syslog::LOG_LOCAL3")
105
+ config.syslog = syslog
84
106
  end
85
107
  end
86
108
  it "Should create a log in the path specified in teh configuration" do
@@ -99,6 +121,15 @@ RSpec.describe FoosController, type: :controller do
99
121
  expect(oml.last_recorded).not_to eq(nil)
100
122
  end
101
123
 
124
+ it "Should split the message bigger than 1024 char when using a syslog" do
125
+ if Rails::VERSION::MAJOR >= 5
126
+ put :update, params: {name: "dummy name" * 200, value: 1, id: @dummy.id}
127
+ else
128
+ put :update, {name: "dummy name" * 200, value: 1, id: @dummy.id}
129
+ end
130
+ expect(oml.last_recorded).not_to eq(nil)
131
+ end
132
+
102
133
  it "The log created should have a receiver if the action made any changes to the model" do
103
134
  if Rails::VERSION::MAJOR >= 5
104
135
  put :update, params: {name: "not dummy name", value: 99, id: @dummy.id}
@@ -1,3 +1,10 @@
1
- class ApplicationRecord < ActiveRecord::Base
2
- self.abstract_class = true
3
- end
1
+ # frozen_string_literal: true
2
+ if OHMYLOG_ORM == :active_record
3
+ class ApplicationRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+ end
6
+ else
7
+ class ApplicationRecord
8
+ include Mongoid::Document
9
+ end
10
+ end
@@ -1,2 +1,8 @@
1
1
  class Doo < ApplicationRecord
2
+ if OHMYLOG_ORM == :mongoid
3
+ include Mongoid::Document
4
+ field :name, type: String
5
+ field :value, type: Integer
6
+ include ::Mongoid::Timestamps
7
+ end
2
8
  end
@@ -1,2 +1,8 @@
1
1
  class Foo < ApplicationRecord
2
+ if OHMYLOG_ORM == :mongoid
3
+ include Mongoid::Document
4
+ field :name, type: String
5
+ field :value, type: Integer
6
+ include ::Mongoid::Timestamps
7
+ end
2
8
  end
@@ -4,6 +4,7 @@ require 'oh_my_log'
4
4
 
5
5
  if defined?(Bundler)
6
6
  Bundler.require(*Rails.groups(assets: %w[development test]))
7
+ require "#{OHMYLOG_ORM}/railtie"
7
8
  end
8
9
 
9
10
  module RailsApp
@@ -12,9 +13,9 @@ module RailsApp
12
13
 
13
14
  config.filter_parameters += [:password]
14
15
 
15
- config.assets.enabled = true
16
+ config.autoload_paths += ["#{config.root}/app/#{OHMYLOG_ORM}"]
17
+ config.autoload_paths += ["#{config.root}/lib"]
16
18
 
17
- config.assets.version = '1.0'
18
19
  config.secret_key_base = 'fuuuuuuuuuuu'
19
20
  end
20
21
  end
@@ -6,32 +6,31 @@ RailsApp::Application.configure do
6
6
 
7
7
  if Rails.version > '5'
8
8
  config.public_file_server.enabled = true
9
- config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
9
+ config.public_file_server.headers = {'Cache-Control' => 'public, max-age=3600'}
10
10
  else
11
11
  config.serve_static_files = true
12
12
  config.static_cache_control = 'public, max-age=3600'
13
13
  end
14
14
 
15
- config.consider_all_requests_local = true
15
+ config.consider_all_requests_local = true
16
16
  config.action_controller.perform_caching = false
17
17
 
18
18
  config.action_dispatch.show_exceptions = false
19
19
 
20
20
  config.action_controller.allow_forgery_protection = false
21
21
 
22
- config.action_mailer.delivery_method = :test
23
- config.action_mailer.default_url_options = { host: 'test.host' }
24
-
25
22
  config.active_support.deprecation = :stderr
26
23
  I18n.enforce_available_locales = false
27
24
 
28
25
  config.active_support.test_order = :sorted
29
26
  config.log_level = :debug
30
- if Rails.gem_version >= Gem::Version.new('4.2') && Rails.gem_version < Gem::Version.new('5.0')
31
- config.active_record.raise_in_transactional_callbacks = true
32
- end
33
- if Rails.gem_version.release >= Gem::Version.new('5.2')
34
- config.active_record.sqlite3.represent_boolean_as_integer = true
27
+ if (OHMYLOG_ORM == "active_record")
28
+ if Rails.gem_version >= Gem::Version.new('4.2') && Rails.gem_version.release < Gem::Version.new('5.0')
29
+ config.active_record.raise_in_transactional_callbacks = true
30
+ end
31
+ if Rails.gem_version.release >= Gem::Version.new('5.2') && Rails.gem_version.release < Gem::Version.new('6.0')
32
+ config.active_record.sqlite3.represent_boolean_as_integer = true
33
+ end
35
34
  end
36
35
  end
37
- ActiveSupport::Deprecation.debug = true
36
+ ActiveSupport::Deprecation.debug = true
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- MIGRATION_CLASS =
4
- if ActiveRecord::VERSION::MAJOR >= 5
5
- ActiveRecord::Migration[4.2]
6
- else
7
- ActiveRecord::Migration
8
- end
3
+ require "oh_my_log/orm/#{OHMYLOG_ORM}"
4
+
5
+ if OHMYLOG_ORM == :active_record
6
+ MIGRATION_CLASS =
7
+ if Rails.gem_version >= Gem::Version.new('5.0')
8
+ ActiveRecord::Migration[Rails.version.to_f]
9
+ else
10
+ ActiveRecord::Migration
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ test:
2
+ <%= Mongoid::VERSION.to_i > 4 ? 'clients' : 'sessions' %>:
3
+ default:
4
+ database: devise_security_test
5
+ hosts:
6
+ - localhost:<%= ENV.fetch('MONGODB_PORT', '27017') %>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require 'active_record'
3
+
4
+ ActiveRecord::Migration.verbose = false
5
+ ActiveRecord::Base.logger = Logger.new(nil)
6
+ if Rails.gem_version >= Gem::Version.new('5.2.0')
7
+ ActiveRecord::MigrationContext.new(File.expand_path('../../dummy/db/migrate', __FILE__)).migrate
8
+ else
9
+ ActiveRecord::Migrator.migrate(File.expand_path('../../dummy/db/migrate', __FILE__))
10
+ end
11
+
12
+ ORMInvalidRecordException = ActiveRecord::RecordInvalid
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mongoid/version'
4
+ require 'mongoid'
5
+ Mongoid.configure do |config|
6
+ config.load!('spec/support/mongoid.yml', Rails.env)
7
+ config.use_utc = true
8
+ config.include_root_in_json = true
9
+ end
10
+
11
+ ORMInvalidRecordException = Mongoid::Errors::Validations
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,12 @@
1
1
  ENV['RAILS_ENV'] ||= 'test'
2
+ OHMYLOG_ORM = ENV.fetch('OHMYLOG_ORM', 'active_record').to_sym
2
3
  require 'simplecov'
3
4
  SimpleCov.start do
4
5
  add_filter 'gemfiles'
5
6
  add_filter 'lib/railtie.rb'
6
7
  add_filter 'lib/tasks/oh_my_log.rake'
8
+ add_filter 'lib/oh_my_log/orm'
9
+ add_filter 'lib/oh_my_log/syslog_processors'
7
10
  add_filter 'spec'
8
11
  add_filter 'blue_print'
9
12
  add_group 'Tests', 'test'
@@ -15,7 +18,9 @@ if ENV['CI']
15
18
  Coveralls.wear!
16
19
  end
17
20
  require 'active_support/all'
21
+ require 'rails'
18
22
  require 'dummy/config/environment'
23
+ require_relative "../spec/orm/#{OHMYLOG_ORM}"
19
24
  # note that require 'rspec-rails' does not work
20
25
  # https://stackoverflow.com/questions/14458122/framework-integration-testing-within-a-gem-how-to-set-up-rspec-controller-test
21
26
  require 'rspec/rails'
@@ -24,13 +29,4 @@ require 'rake'
24
29
 
25
30
  load File.expand_path("../../lib/tasks/oh_my_log.rake", __FILE__)
26
31
  # make sure you set correct relative path
27
- Rake::Task.define_task(:environment)
28
-
29
- ActiveRecord::Migration.verbose = false
30
- ActiveRecord::Base.logger = Logger.new(nil)
31
-
32
- if Rails.gem_version >= Gem::Version.new('5.2.0')
33
- ActiveRecord::MigrationContext.new(File.expand_path('../dummy/db/migrate', __FILE__)).migrate
34
- else
35
- ActiveRecord::Migrator.migrate(File.expand_path('../dummy/db/migrate', __FILE__))
36
- end
32
+ Rake::Task.define_task(:environment)
@@ -0,0 +1,6 @@
1
+ test:
2
+ <%= Mongoid::VERSION.to_i > 4 ? 'clients' : 'sessions' %>:
3
+ default:
4
+ database: devise_security_test
5
+ hosts:
6
+ - localhost:<%= ENV.fetch('MONGODB_PORT', '27017') %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oh_my_log
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabrizio Spadaro
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '6.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: sqlite3
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.3.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 1.3.0
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: rails-observers
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -44,6 +58,34 @@ dependencies:
44
58
  - - "~>"
45
59
  - !ruby/object:Gem::Version
46
60
  version: 0.1.5
61
+ - !ruby/object:Gem::Dependency
62
+ name: mongoid
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: mongoid-observers
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
47
89
  - !ruby/object:Gem::Dependency
48
90
  name: coveralls
49
91
  requirement: !ruby/object:Gem::Requirement
@@ -100,20 +142,6 @@ dependencies:
100
142
  - - ">="
101
143
  - !ruby/object:Gem::Version
102
144
  version: '0'
103
- - !ruby/object:Gem::Dependency
104
- name: sqlite3
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: 1.3.10
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - "~>"
115
- - !ruby/object:Gem::Version
116
- version: 1.3.10
117
145
  - !ruby/object:Gem::Dependency
118
146
  name: wwtd
119
147
  requirement: !ruby/object:Gem::Requirement
@@ -172,9 +200,14 @@ files:
172
200
  - lib/oh_my_log/log.rb
173
201
  - lib/oh_my_log/mongoid_observer.rb
174
202
  - lib/oh_my_log/observer_factory.rb
203
+ - lib/oh_my_log/orm/active_record.rb
204
+ - lib/oh_my_log/orm/mongoid.rb
175
205
  - lib/oh_my_log/request.rb
176
206
  - lib/oh_my_log/result.rb
177
207
  - lib/oh_my_log/selector.rb
208
+ - lib/oh_my_log/syslog_configuration.rb
209
+ - lib/oh_my_log/syslog_implementor.rb
210
+ - lib/oh_my_log/syslog_processors/r_f_c_3164.rb
178
211
  - lib/oh_my_log/version.rb
179
212
  - lib/railtie.rb
180
213
  - lib/tasks/oh_my_log.rake
@@ -198,11 +231,15 @@ files:
198
231
  - spec/dummy/config/environment.rb
199
232
  - spec/dummy/config/environments/test.rb
200
233
  - spec/dummy/config/initializers/migration_class.rb
234
+ - spec/dummy/config/mongoid.yml
201
235
  - spec/dummy/config/routes.rb
202
236
  - spec/dummy/config/secrets.yml
203
237
  - spec/dummy/db/migrate/20120508165529_create_tables.rb
238
+ - spec/orm/active_record.rb
239
+ - spec/orm/mongoid.rb
204
240
  - spec/rails_helper.rb
205
241
  - spec/spec_helper.rb
242
+ - spec/support/mongoid.yml
206
243
  homepage: https://github.com/fabriziospadaro/oh_my_log
207
244
  licenses:
208
245
  - MIT