central_logger 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,22 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activesupport (3.0.1)
4
+ activesupport (3.0.3)
5
5
  archive-tar-minitar (0.5.2)
6
- bson (1.1.2)
7
- bson_ext (1.1.2)
6
+ bson (1.1.4)
7
+ bson_ext (1.1.4)
8
8
  columnize (0.3.2)
9
9
  git (1.2.5)
10
- i18n (0.4.2)
11
- jeweler (1.5.0.pre5)
10
+ i18n (0.5.0)
11
+ jeweler (1.5.1)
12
12
  bundler (~> 1.0.0)
13
13
  git (>= 1.2.5)
14
14
  rake
15
15
  linecache19 (0.5.11)
16
16
  ruby_core_source (>= 0.1.4)
17
- mocha (0.9.9)
17
+ mocha (0.9.10)
18
18
  rake
19
- mongo (1.1.2)
19
+ mongo (1.1.4)
20
20
  bson (>= 1.1.1)
21
21
  rake (0.8.7)
22
22
  ruby-debug-base19 (0.11.24)
data/README.md CHANGED
@@ -32,10 +32,11 @@ Log to a central MongoDB from Rails apps.
32
32
  database: my_app_development
33
33
  user: root
34
34
  mongo:
35
- database: my_app # required
35
+ database: my_app # required (the only required setting)
36
36
  capsize: <%= 10.megabytes %> # default: 250MB for production; 100MB otherwise
37
37
  host: localhost # default: localhost
38
38
  port: 27017 # default: 27017
39
+ replica_set: true # default: false - Adds safe inserts and retries for ConnectionFailure during voting
39
40
 
40
41
  central_logger.yml:
41
42
 
@@ -44,6 +45,7 @@ Log to a central MongoDB from Rails apps.
44
45
  capsize: <%= 10.megabytes %>
45
46
  host: localhost
46
47
  port: 27017
48
+ replica_set: true
47
49
 
48
50
  With that in place, a new MongoDB document (record) will be created for each request and,
49
51
  by default will record the following information: Runtime, IP Address, Request Time, Controller,
@@ -64,7 +66,7 @@ Log to a central MongoDB from Rails apps.
64
66
  'params' : { },
65
67
  'path' : path,
66
68
  'request_time' : date_of_request,
67
- 'runtime' : elapsed_execution_time_in_seconds,
69
+ 'runtime' : elapsed_execution_time_in_milliseconds,
68
70
  'url' : full_url
69
71
  }
70
72
 
@@ -75,7 +77,7 @@ Log to a central MongoDB from Rails apps.
75
77
 
76
78
  # make sure we're using the CentralLogger in this environment
77
79
  if Rails.logger.respond_to?(:add_metadata)
78
- Rails.logger.add_metadata(:user_guid =&gt; @user_guid)
80
+ Rails.logger.add_metadata(:user_guid => @user_guid)
79
81
  end
80
82
 
81
83
  ## Examples
data/Rakefile CHANGED
@@ -54,7 +54,14 @@ namespace :test do
54
54
  desc "Run unit tests"
55
55
  Rake::TestTask.new(:units) do |test|
56
56
  test.libs << 'lib' << 'test'
57
- test.pattern = 'test/unit/*_test.rb'
57
+ test.pattern = 'test/unit/central_logger_test.rb'
58
+ test.verbose = true
59
+ end
60
+
61
+ desc "Run replica set tests"
62
+ Rake::TestTask.new(:replica_set) do |test|
63
+ test.libs << 'lib' << 'test'
64
+ test.pattern = 'test/unit/central_logger_replica_test.rb'
58
65
  test.verbose = true
59
66
  end
60
67
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{central_logger}
8
- s.version = "0.2.0"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Phil Burrows", "Alex Stupka"]
12
- s.date = %q{2010-11-30}
12
+ s.date = %q{2010-12-08}
13
13
  s.description = %q{Centralized logging for rails apps using MongoDB. The idea and the core code is from http://github.com/peburrows/central_logger}
14
14
  s.email = %q{astupka@customink.com}
15
15
  s.extra_rdoc_files = [
@@ -30,15 +30,18 @@ Gem::Specification.new do |s|
30
30
  "lib/central_logger/initializer_mixin.rb",
31
31
  "lib/central_logger/mongo_logger.rb",
32
32
  "lib/central_logger/railtie.rb",
33
+ "lib/central_logger/replica_set_helper.rb",
33
34
  "test/active_record.rb",
34
35
  "test/config/samples/central_logger.yml",
35
36
  "test/config/samples/database.yml",
37
+ "test/config/samples/database_replica_set.yml",
36
38
  "test/config/samples/database_with_auth.yml",
37
39
  "test/config/samples/mongoid.yml",
38
40
  "test/rails.rb",
39
41
  "test/shoulda_macros/log_macros.rb",
40
42
  "test/test.sh",
41
43
  "test/test_helper.rb",
44
+ "test/unit/central_logger_replica_test.rb",
42
45
  "test/unit/central_logger_test.rb"
43
46
  ]
44
47
  s.homepage = %q{http://github.com/customink/central_logger}
@@ -50,6 +53,7 @@ Gem::Specification.new do |s|
50
53
  "test/rails.rb",
51
54
  "test/shoulda_macros/log_macros.rb",
52
55
  "test/test_helper.rb",
56
+ "test/unit/central_logger_replica_test.rb",
53
57
  "test/unit/central_logger_test.rb"
54
58
  ]
55
59
 
@@ -2,15 +2,18 @@ require 'erb'
2
2
  require 'mongo'
3
3
  require 'active_support'
4
4
  require 'active_support/core_ext'
5
+ require 'central_logger/replica_set_helper'
5
6
 
6
7
  module CentralLogger
7
8
  class MongoLogger < ActiveSupport::BufferedLogger
9
+ include ReplicaSetHelper
10
+
8
11
  PRODUCTION_COLLECTION_SIZE = 250.megabytes
9
12
  DEFAULT_COLLECTION_SIZE = 100.megabytes
10
13
  # Looks for configuration files in this order
11
14
  CONFIGURATION_FILES = ["central_logger.yml", "mongoid.yml", "database.yml"]
12
15
 
13
- attr_reader :db_configuration, :mongo_connection, :mongo_collection_name
16
+ attr_reader :db_configuration, :mongo_connection, :mongo_collection_name, :mongo_collection
14
17
 
15
18
  def initialize(options={})
16
19
  path = options[:path] || File.join(Rails.root, "log/#{Rails.env}.log")
@@ -43,7 +46,7 @@ module CentralLogger
43
46
 
44
47
  # Drop the capped_collection and recreate it
45
48
  def reset_collection
46
- @mongo_connection[@mongo_collection_name].drop
49
+ @mongo_collection.drop
47
50
  create_collection
48
51
  end
49
52
 
@@ -61,8 +64,8 @@ module CentralLogger
61
64
  raise e
62
65
  ensure
63
66
  # In case of exception, make sure runtime is set
64
- runtime ||= 0
65
- insert_log_record(runtime)
67
+ @mongo_record[:runtime] = ((runtime ||= 0) * 1000).ceil
68
+ @insert_block.call
66
69
  end
67
70
 
68
71
  def authenticated?
@@ -86,6 +89,10 @@ module CentralLogger
86
89
  'host' => 'localhost',
87
90
  'port' => 27017,
88
91
  'capsize' => default_capsize}.merge(resolve_config)
92
+
93
+ @insert_block = @db_configuration.has_key?('replica_set') && @db_configuration['replica_set'] ?
94
+ lambda { rescue_connection_failure{ insert_log_record(true) } } :
95
+ lambda { insert_log_record }
89
96
  end
90
97
 
91
98
  def resolve_config
@@ -123,11 +130,11 @@ module CentralLogger
123
130
  unless @mongo_connection.collection_names.include?(@mongo_collection_name)
124
131
  create_collection
125
132
  end
133
+ @mongo_collection = @mongo_connection[@mongo_collection_name]
126
134
  end
127
135
 
128
- def insert_log_record(runtime)
129
- @mongo_record[:runtime] = (runtime * 1000).ceil
130
- @mongo_connection[@mongo_collection_name].insert(@mongo_record) rescue nil
136
+ def insert_log_record(safe=false)
137
+ @mongo_collection.insert(@mongo_record, :safe => safe)
131
138
  end
132
139
 
133
140
  def level_to_sym(level)
@@ -0,0 +1,19 @@
1
+ module CentralLogger
2
+ module ReplicaSetHelper
3
+ # Use retry alg from mongodb to gobble up connection failures during replica set master vote
4
+ # Defaults to a 10 second wait
5
+ def rescue_connection_failure(max_retries=40)
6
+ success = false
7
+ retries = 0
8
+ while !success
9
+ begin
10
+ yield
11
+ success = true
12
+ rescue Mongo::ConnectionFailure => e
13
+ raise e if (retries += 1) >= max_retries
14
+ sleep 0.25
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ test:
2
+ adapter: mysql
3
+ username: user
4
+ database: database
5
+ mongo:
6
+ database: system_log
7
+ replica_set: true
@@ -17,6 +17,7 @@ class Test::Unit::TestCase
17
17
  DEFAULT_CONFIG = "database.yml"
18
18
  DEFAULT_CONFIG_WITH_AUTH = "database_with_auth.yml"
19
19
  MONGOID_CONFIG = "mongoid.yml"
20
+ REPLICA_SET_CONFIG = "database_replica_set.yml"
20
21
  LOGGER_CONFIG = "central_logger.yml"
21
22
 
22
23
  def log(msg)
@@ -33,10 +34,14 @@ class Test::Unit::TestCase
33
34
 
34
35
  def setup_for_config(source, dest=source)
35
36
  File.delete(File.join(CONFIG_DIR, DEFAULT_CONFIG))
36
- FileUtils.cp(File.join(SAMPLE_CONFIG_DIR, source), File.join(CONFIG_DIR, dest))
37
+ cp_config(source, dest)
37
38
  @central_logger.send(:configure)
38
39
  end
39
40
 
41
+ def cp_config(source, dest=source)
42
+ FileUtils.cp(File.join(SAMPLE_CONFIG_DIR, source), File.join(CONFIG_DIR, dest))
43
+ end
44
+
40
45
  def teardown_for_config(file)
41
46
  File.delete(File.join(CONFIG_DIR, file))
42
47
  end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+ require 'central_logger/mongo_logger'
3
+
4
+ # test the basic stuff
5
+ class CentralLogger::MongoLoggerReplicaTest < Test::Unit::TestCase
6
+ extend LogMacros
7
+
8
+ context "A CentralLogger::MongoLogger" do
9
+ setup do
10
+ # Can use different configs, but most tests use database.yml
11
+ cp_config(REPLICA_SET_CONFIG, DEFAULT_CONFIG)
12
+ @central_logger = CentralLogger::MongoLogger.new
13
+ @central_logger.reset_collection
14
+ end
15
+
16
+ context "upon trying to insert into a replica set voting on a new master" do
17
+ setup do
18
+ puts "Please disconnect the current master and hit ENTER"
19
+ STDIN.gets
20
+ end
21
+
22
+ should "insert a record successfully" do
23
+ assert_nothing_raised{ log("Test") }
24
+ @central_logger.rescue_connection_failure do
25
+ assert_equal 1, @central_logger.mongo_collection.count
26
+ end
27
+ end
28
+
29
+ teardown do
30
+ puts "Please reconnect the current master, wait for the vote to complete, then hit ENTER"
31
+ STDIN.gets
32
+ end
33
+ end
34
+
35
+ should "insert a record successfully" do
36
+ assert_nothing_raised{ log("Test") }
37
+ assert_equal 1, @central_logger.mongo_collection.count
38
+ end
39
+
40
+ teardown do
41
+ file = File.join(CONFIG_DIR, DEFAULT_CONFIG)
42
+ File.delete(file) if File.exist?(file)
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
7
+ - 3
8
8
  - 0
9
- version: 0.2.0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Phil Burrows
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-30 00:00:00 -05:00
18
+ date: 2010-12-08 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -176,15 +176,18 @@ files:
176
176
  - lib/central_logger/initializer_mixin.rb
177
177
  - lib/central_logger/mongo_logger.rb
178
178
  - lib/central_logger/railtie.rb
179
+ - lib/central_logger/replica_set_helper.rb
179
180
  - test/active_record.rb
180
181
  - test/config/samples/central_logger.yml
181
182
  - test/config/samples/database.yml
183
+ - test/config/samples/database_replica_set.yml
182
184
  - test/config/samples/database_with_auth.yml
183
185
  - test/config/samples/mongoid.yml
184
186
  - test/rails.rb
185
187
  - test/shoulda_macros/log_macros.rb
186
188
  - test/test.sh
187
189
  - test/test_helper.rb
190
+ - test/unit/central_logger_replica_test.rb
188
191
  - test/unit/central_logger_test.rb
189
192
  has_rdoc: true
190
193
  homepage: http://github.com/customink/central_logger
@@ -223,4 +226,5 @@ test_files:
223
226
  - test/rails.rb
224
227
  - test/shoulda_macros/log_macros.rb
225
228
  - test/test_helper.rb
229
+ - test/unit/central_logger_replica_test.rb
226
230
  - test/unit/central_logger_test.rb