Class: MongoProxy

Inherits:
Object
  • Object
show all
Defined in:
lib/mongo-proxy/proxy.rb

Overview

This class uses em-proxy to help listen to MongoDB traffic, with some parsing and filtering capabilities that allow you to enforce a read-only mode, or use your own arbitrary logic.

Constant Summary collapse

VERSION =
'1.0.1'

Instance Method Summary collapse

Constructor Details

#initialize(config = nil) ⇒ MongoProxy

Returns a new instance of MongoProxy.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/mongo-proxy/proxy.rb', line 15

def initialize(config = nil)
  # default config values
  @config = {
    :client_host => '127.0.0.1', # Set the host to bind the proxy socket on.
    :client_port => 29017,       # Set the port to bind the proxy socket on.
    :server_host => '127.0.0.1', # Set the backend host which we proxy.
    :server_port => 27017,       # Set the backend port which we proxy.
    :motd => nil,                # Set a message-of-the-day to display to clients when they connect. nil for none.
    :read_only => false,         # Prevent any traffic that writes to the database.
    :verbose => false,           # Print out MongoDB wire traffic.
    :logger => nil,              # Use this object as the logger instead of creating one.
    :debug => false              # Print log lines in a more human-readible format.
  }
  @front_callbacks = []
  @back_callbacks = []

  # apply argument config to the default values
  (config || []).each do |k, v|
    if @config.include?(k)
      @config[k] = v
    else
      raise "Unrecognized configuration value: #{k}"
    end
  end

  # debug implies verbose
  @config[:verbose] = true if @config[:debug]

  # Set up the logger for mongo proxy. Users can also pass their own
  # logger in with the :logger config value.
  unless @config[:logger]
    @config[:logger] = Logger.new(STDOUT)
    @config[:logger].level = (@config[:verbose] ? Logger::DEBUG : Logger::WARN)

    if @config[:debug]
      @config[:logger].formatter = proc do |_, _, _, msg|
        if msg.is_a?(Hash)
          "#{JSON::pretty_generate(msg)}\n\n"
        else
          "#{msg}\n\n"
        end
      end
    end
  end

  unless port_open?(@config[:server_host], @config[:server_port])
    raise "Could not connect to MongoDB server at #{@config[:server_host]}.#{@config[:server_port]}"
  end

  @log = @config[:logger]
  @auth = AuthMongo.new(@config)
end

Instance Method Details

#add_callback_to_back(&block) ⇒ Object



88
89
90
# File 'lib/mongo-proxy/proxy.rb', line 88

def add_callback_to_back(&block)
  @back_callbacks << block
end

#add_callback_to_front(&block) ⇒ Object



84
85
86
# File 'lib/mongo-proxy/proxy.rb', line 84

def add_callback_to_front(&block)
  @front_callbacks.insert(0, block)
end

#startObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/mongo-proxy/proxy.rb', line 68

def start
  # em proxy launches a thread, this is the error handler for it
  EM.error_handler do |e|
    @log.error [e.inspect, e.backtrace.first]
    raise e
  end

  # kick off em-proxy
  Proxy.start({
      :host => @config[:client_host],
      :port => @config[:client_port],
      :debug => false
    },
    &method(:callbacks))
end