lib/semantic_logger/appender/mongodb.rb in semantic_logger-3.4.1 vs lib/semantic_logger/appender/mongodb.rb in semantic_logger-4.0.0.beta1

- old
+ new

@@ -1,10 +1,10 @@ require 'socket' begin require 'mongo' rescue LoadError - raise 'Gem mongo is required for logging to MongoDB. Please add the gem "mongo" to your Gemfile.' + raise 'Gem mongo is required for logging to MongoDB. Please add the gem "mongo" v2.0 or greater to your Gemfile.' end module SemanticLogger module Appender # The Mongo Appender for the SemanticLogger @@ -47,18 +47,19 @@ # logger = SemanticLogger['Example'] # # # Log some messages # logger.info 'This message is written to mongo as a document' class MongoDB < SemanticLogger::Subscriber - attr_reader :db, :collection_name, :collection - attr_accessor :write_concern + attr_reader :client, :collection # Create a MongoDB Appender instance # # Parameters: - # db: [Mongo::Database] - # The MongoDB database connection to use, not the database name + # uri: [String] + # Mongo connection string. + # Example: + # mongodb://127.0.0.1:27017/test # # collection_name: [String] # Name of the collection to store log data in # Default: semantic_logger # @@ -76,10 +77,11 @@ # Test: File # Release: 4GB # # collection_max: [Integer] # Maximum number of log entries that the capped collection will hold. + # Default: no max limit # # level: [:trace | :debug | :info | :warn | :error | :fatal] # Override the log level for this appender. # Default: SemanticLogger.default_level # @@ -99,32 +101,34 @@ # Default: SemanticLogger.host # # application: [String] # Name of this application to appear in log messages. # Default: SemanticLogger.application - def initialize(options = {}, &block) - options = options.dup - @db = options.delete(:db) || raise('Missing mandatory parameter :db') - @collection_name = options.delete(:collection_name) || 'semantic_logger' - @write_concern = options.delete(:write_concern) || 0 + def initialize(uri:, collection_name: 'semantic_logger', write_concern: 0, collection_size: 1024**3, collection_max: nil, + level: nil, formatter: nil, filter: nil, host: SemanticLogger.host, application: SemanticLogger.application, &block) + @client = Mongo::Client.new(uri, logger: SemanticLogger::Processor.logger.clone) + @collection_name = collection_name + @options = { + capped: true, + size: collection_size, + write: {w: write_concern} + } + @options[:max] = collection_max if collection_max - # Create a collection that will hold the lesser of 1GB space or 10K documents - @collection_size = options.delete(:collection_size) || 1024**3 - @collection_max = options.delete(:collection_max) + reopen # Create the collection and necessary indexes create_indexes # Set the log level and formatter - super(options, &block) - reopen + super(level: level, formatter: formatter, filter: filter, host: host, application: application, &block) end # After forking an active process call #reopen to re-open # open the handles to resources def reopen - @collection = db[@collection_name] + @collection = client[@collection_name, @options] end # Create the required capped collection. # # Features of capped collection: @@ -134,36 +138,34 @@ # * Documents are always stored in insertion order # * A find will always return the documents in their insertion order # # Creates an index based on tags to support faster searches. def create_indexes - options = {capped: true, size: @collection_size} - options[:max] = @collection_max if @collection_max - db.create_collection(collection_name, options) - db[@collection_name].ensure_index('tags') + # Create Capped collection + begin + @collection.create + rescue Mongo::Error::OperationFailure + # Already exists + end + + @collection.indexes.create_one({tags: 1}) end # Purge all data from the capped collection by dropping the collection # and recreating it. # Also useful when the size of the capped collection needs to be changed def purge_all collection.drop - @collection = nil + reopen create_indexes end - # Flush all pending logs to disk. - # Waits for all sent documents to be written to disk - def flush - db.get_last_error - end - # Log the message to MongoDB def log(log) return false unless should_log?(log) # Insert log entry into Mongo - collection.insert(formatter.call(log, self), w: @write_concern) + collection.insert_one(formatter.call(log, self)) true end private