oh_my_log 1.0.2 → 1.0.3

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