central_logger 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem "rake"
4
- gem "bundler", "~> 1.0.0"
4
+ gem "bundler"
5
5
  gem "mongo"
6
6
  gem "bson_ext"
7
7
 
data/Gemfile.lock CHANGED
@@ -1,23 +1,22 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activesupport (3.0.3)
4
+ activesupport (3.0.5)
5
5
  archive-tar-minitar (0.5.2)
6
- bson (1.1.4)
7
- bson_ext (1.1.4)
6
+ bson (1.2.4)
7
+ bson_ext (1.2.4)
8
8
  columnize (0.3.2)
9
9
  git (1.2.5)
10
10
  i18n (0.5.0)
11
- jeweler (1.5.1)
11
+ jeweler (1.5.2)
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.10)
18
- rake
19
- mongo (1.1.4)
20
- bson (>= 1.1.1)
17
+ mocha (0.9.12)
18
+ mongo (1.2.4)
19
+ bson (>= 1.2.4)
21
20
  rake (0.8.7)
22
21
  ruby-debug-base19 (0.11.24)
23
22
  columnize (>= 0.3.1)
@@ -37,7 +36,7 @@ PLATFORMS
37
36
  DEPENDENCIES
38
37
  activesupport
39
38
  bson_ext
40
- bundler (~> 1.0.0)
39
+ bundler
41
40
  i18n
42
41
  jeweler (~> 1.5.0.pre5)
43
42
  mocha
data/README.md CHANGED
@@ -36,7 +36,9 @@ Log to a central MongoDB from Rails apps.
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
+ replica_set: true # default: false - Adds retries for ConnectionFailure during voting for replica set master
40
+ safe_insert: true # default: false - Enable/Disable safe inserts (wait for insert to propagate to all nodes)
41
+ application_name: my_app # default: Rails.application - Only really needed for non-capistrano Rails 2 deployments. Otherwise should set automatically.
40
42
 
41
43
  central_logger.yml:
42
44
 
@@ -80,7 +82,12 @@ Log to a central MongoDB from Rails apps.
80
82
  Rails.logger.add_metadata(:user_guid => @user_guid)
81
83
  end
82
84
 
83
- ## Examples
85
+ ## Central Log Viewer
86
+
87
+ Please see the [central\_log\_viewer](https://github.com/customink/central_log_viewer):
88
+ a companion web application for querying and viewing your centralized logs.
89
+
90
+ ## Querying via the Rails console
84
91
 
85
92
  And now, for a couple quick examples on getting ahold of this log data...
86
93
  First, here's how to get a handle on the MongoDB from within a Rails console:
@@ -115,4 +122,4 @@ Find all requests with a request_date greater than '11/18/2010 22:59:52 GMT'
115
122
 
116
123
  >> collection.find({:request_time => {'$gt' => Time.utc(2010, 11, 18, 22, 59, 52)}})
117
124
 
118
- Copyright (c) 2009 Phil Burrows, released under the MIT license
125
+ Copyright (c) 2009-2011 Phil Burrows and CustomInk, released under the MIT license
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{central_logger}
8
- s.version = "0.3.0"
8
+ s.version = "0.3.1"
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-12-08}
12
+ s.date = %q{2011-03-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 = [
@@ -63,7 +63,7 @@ Gem::Specification.new do |s|
63
63
 
64
64
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
65
65
  s.add_runtime_dependency(%q<rake>, [">= 0"])
66
- s.add_runtime_dependency(%q<bundler>, ["~> 1.0.0"])
66
+ s.add_runtime_dependency(%q<bundler>, [">= 0"])
67
67
  s.add_runtime_dependency(%q<mongo>, [">= 0"])
68
68
  s.add_runtime_dependency(%q<bson_ext>, [">= 0"])
69
69
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.0.pre5"])
@@ -74,7 +74,7 @@ Gem::Specification.new do |s|
74
74
  s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
75
75
  else
76
76
  s.add_dependency(%q<rake>, [">= 0"])
77
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
77
+ s.add_dependency(%q<bundler>, [">= 0"])
78
78
  s.add_dependency(%q<mongo>, [">= 0"])
79
79
  s.add_dependency(%q<bson_ext>, [">= 0"])
80
80
  s.add_dependency(%q<jeweler>, ["~> 1.5.0.pre5"])
@@ -86,7 +86,7 @@ Gem::Specification.new do |s|
86
86
  end
87
87
  else
88
88
  s.add_dependency(%q<rake>, [">= 0"])
89
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
89
+ s.add_dependency(%q<bundler>, [">= 0"])
90
90
  s.add_dependency(%q<mongo>, [">= 0"])
91
91
  s.add_dependency(%q<bson_ext>, [">= 0"])
92
92
  s.add_dependency(%q<jeweler>, ["~> 1.5.0.pre5"])
@@ -12,6 +12,7 @@ module CentralLogger
12
12
  DEFAULT_COLLECTION_SIZE = 100.megabytes
13
13
  # Looks for configuration files in this order
14
14
  CONFIGURATION_FILES = ["central_logger.yml", "mongoid.yml", "database.yml"]
15
+ LOG_LEVEL_SYM = [:debug, :info, :warn, :error, :fatal, :unknown]
15
16
 
16
17
  attr_reader :db_configuration, :mongo_connection, :mongo_collection_name, :mongo_collection
17
18
 
@@ -36,12 +37,12 @@ module CentralLogger
36
37
  end
37
38
 
38
39
  def add(severity, message = nil, progname = nil, &block)
40
+ super
39
41
  if @level <= severity && message.present? && @mongo_record.present?
40
42
  # remove Rails colorization to get the actual message
41
43
  message.gsub!(/(\e(\[([\d;]*[mz]?))?)?/, '').strip! if logging_colorized?
42
- @mongo_record[:messages][level_to_sym(severity)] << message
44
+ @mongo_record[:messages][LOG_LEVEL_SYM[severity]] << message
43
45
  end
44
- super
45
46
  end
46
47
 
47
48
  # Drop the capped_collection and recreate it
@@ -57,7 +58,7 @@ module CentralLogger
57
58
  :application_name => @application_name
58
59
  })
59
60
 
60
- runtime = Benchmark.measure{ yield }.real
61
+ runtime = Benchmark.measure{ yield }.real if block_given?
61
62
  rescue Exception => e
62
63
  add(3, e.message + "\n" + e.backtrace.join("\n"))
63
64
  # Reraise the exception for anyone else who cares
@@ -65,7 +66,13 @@ module CentralLogger
65
66
  ensure
66
67
  # In case of exception, make sure runtime is set
67
68
  @mongo_record[:runtime] = ((runtime ||= 0) * 1000).ceil
68
- @insert_block.call
69
+ begin
70
+ @insert_block.call
71
+ rescue
72
+ # do extra work to inpect (and flatten)
73
+ force_serialize @mongo_record
74
+ @insert_block.call rescue nil
75
+ end
69
76
  end
70
77
 
71
78
  def authenticated?
@@ -82,19 +89,33 @@ module CentralLogger
82
89
 
83
90
  def configure
84
91
  default_capsize = Rails.env.production? ? PRODUCTION_COLLECTION_SIZE : DEFAULT_COLLECTION_SIZE
85
- @application_name = Rails.root.basename.to_s
86
92
  @mongo_collection_name = "#{Rails.env}_log"
87
93
  @authenticated = false
88
94
  @db_configuration = {
89
95
  'host' => 'localhost',
90
96
  'port' => 27017,
91
97
  'capsize' => default_capsize}.merge(resolve_config)
98
+ @application_name = resolve_application_name
99
+ @safe_insert = @db_configuration['safe_insert'] || false
92
100
 
93
101
  @insert_block = @db_configuration.has_key?('replica_set') && @db_configuration['replica_set'] ?
94
- lambda { rescue_connection_failure{ insert_log_record(true) } } :
102
+ lambda { rescue_connection_failure{ insert_log_record(@safe_insert) } } :
95
103
  lambda { insert_log_record }
96
104
  end
97
105
 
106
+ def resolve_application_name
107
+ if @db_configuration.has_key?('application_name')
108
+ @db_configuration['application_name']
109
+ elsif Rails::VERSION::MAJOR >= 3
110
+ Rails.application.class.to_s.split("::").first
111
+ else
112
+ # rails 2 requires detective work if it's been deployed by capistrano
113
+ # if last entry is a timestamp, go back 2 dirs (ex. /app_name/releases/20110304132847)
114
+ path = Rails.root.to_s.split('/')
115
+ path.length >= 4 && path.last =~ /^\d/ ? path.last(3)[0] : path.last
116
+ end
117
+ end
118
+
98
119
  def resolve_config
99
120
  config = {}
100
121
  CONFIGURATION_FILES.each do |filename|
@@ -137,17 +158,6 @@ module CentralLogger
137
158
  @mongo_collection.insert(@mongo_record, :safe => safe)
138
159
  end
139
160
 
140
- def level_to_sym(level)
141
- case level
142
- when 0 then :debug
143
- when 1 then :info
144
- when 2 then :warn
145
- when 3 then :error
146
- when 4 then :fatal
147
- when 5 then :unknown
148
- end
149
- end
150
-
151
161
  def logging_colorized?
152
162
  # Cache it since these ActiveRecord attributes are assigned after logger initialization occurs in Rails boot
153
163
  @colorized ||= Object.const_defined?(:ActiveRecord) &&
@@ -155,5 +165,18 @@ module CentralLogger
155
165
  ActiveRecord::LogSubscriber.colorize_logging :
156
166
  ActiveRecord::Base.colorize_logging)
157
167
  end
168
+
169
+ # force the data in the db by inspecting each top level array and hash element
170
+ # this will flatten other hashes and arrays
171
+ def force_serialize(rec)
172
+ if msgs = rec[:messages]
173
+ LOG_LEVEL_SYM.each do |i|
174
+ msgs[i].collect! { |j| j.inspect } if msgs[i]
175
+ end
176
+ end
177
+ if pms = rec[:params]
178
+ pms.each { |i, j| pms[i] = j.inspect }
179
+ end
180
+ end
158
181
  end # class MongoLogger
159
182
  end
@@ -4,3 +4,5 @@ test:
4
4
  database: database
5
5
  mongo:
6
6
  database: system_log
7
+ application_name: central_foo
8
+ safe_insert: true
data/test/rails.rb CHANGED
@@ -1,3 +1,8 @@
1
+ module CentralLogger
2
+ class Application
3
+ end
4
+ end
5
+
1
6
  class Rails
2
7
  module VERSION
3
8
  MAJOR = 3
@@ -10,4 +15,8 @@ class Rails
10
15
  def self.root
11
16
  Pathname.new(File.dirname(__FILE__))
12
17
  end
18
+
19
+ def self.application
20
+ CentralLogger::Application.new
21
+ end
13
22
  end
data/test/test_helper.rb CHANGED
@@ -26,6 +26,10 @@ class Test::Unit::TestCase
26
26
  end
27
27
  end
28
28
 
29
+ def log_params(msg)
30
+ @central_logger.mongoize({:params => msg})
31
+ end
32
+
29
33
  def log_exception(msg)
30
34
  @central_logger.mongoize({"id" => 1}) do
31
35
  raise msg
@@ -1,5 +1,6 @@
1
1
  require 'test_helper'
2
2
  require 'central_logger/mongo_logger'
3
+ require 'tempfile'
3
4
 
4
5
  # test the basic stuff
5
6
  class CentralLogger::MongoLoggerTest < Test::Unit::TestCase
@@ -76,6 +77,14 @@ class CentralLogger::MongoLoggerTest < Test::Unit::TestCase
76
77
  assert_equal "#{Rails.env}_log", @central_logger.mongo_collection_name
77
78
  end
78
79
 
80
+ should "set the application name when specified in the config file" do
81
+ assert_equal "central_foo", @central_logger.instance_variable_get(:@application_name)
82
+ end
83
+
84
+ should "set safe insert when specified in the config file" do
85
+ assert @central_logger.instance_variable_get(:@safe_insert)
86
+ end
87
+
79
88
  should "use the database name in the config file" do
80
89
  assert_equal "system_log", @central_logger.db_configuration['database']
81
90
  end
@@ -150,6 +159,16 @@ class CentralLogger::MongoLoggerTest < Test::Unit::TestCase
150
159
  assert_equal 1, @collection.find({"application" => self.class.name}).count
151
160
  end
152
161
 
162
+ should "not raise an exception when bson-unserializable data is logged in the :messages key" do
163
+ log(Tempfile.new("foo"))
164
+ assert_equal 1, @collection.count
165
+ end
166
+
167
+ should "not raise an exception when bson-unserializable data is logged in the :params key" do
168
+ log_params({:foo => Tempfile.new("bar")})
169
+ assert_equal 1, @collection.count
170
+ end
171
+
153
172
  context "when an exception is raised" do
154
173
  should "log the exception" do
155
174
  assert_raise(RuntimeError, EXCEPTION_MSG) {log_exception(EXCEPTION_MSG)}
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 0
9
- version: 0.3.0
8
+ - 1
9
+ version: 0.3.1
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-12-08 00:00:00 -05:00
18
+ date: 2011-03-08 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -37,13 +37,11 @@ dependencies:
37
37
  requirement: &id002 !ruby/object:Gem::Requirement
38
38
  none: false
39
39
  requirements:
40
- - - ~>
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  segments:
43
- - 1
44
- - 0
45
43
  - 0
46
- version: 1.0.0
44
+ version: "0"
47
45
  type: :runtime
48
46
  version_requirements: *id002
49
47
  - !ruby/object:Gem::Dependency