Class: Frankenstein::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/frankenstein/server.rb,
lib/frankenstein/server/webrick_logger.rb

Overview

A straightforward Prometheus metrics server.

When you're looking to instrument your application which isn't, itself, a HTTP service, you need this class. It spawns a WEBrick server on a port you specify, and gives you a registry to put your metrics into. That's pretty much it.

The simplest example possible:

stats_server = Frankenstein::Server.new
stats_server.run   # We are now serving stats on port 8080!
counter = stats_server.registry.counter(:seconds_count, "Number of seconds")
# Give the counter something to count
loop { sleep 1; counter.increment({}) }

Now if you hit http://localhost:8080/metrics you should see a counter gradually going up, along with stats about the Frankenstein HTTP server itself. Neato!

You can change how the webserver logs, and the port it listens on, with options to #new. If for some reason you need to shut down the webserver manually, use

shutdown.

Defined Under Namespace

Classes: AlreadyRunningError, WEBrickLogger

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(port: 8080, logger: nil, metrics_prefix: "frankenstein_server", registry: Prometheus::Client::Registry.new) ⇒ Server

Create a new server instance.

Parameters:

  • port (Integer) (defaults to: 8080)

    the TCP to listen on.

  • logger (Logger) (defaults to: nil)

    send log messages from WEBrick to this logger. If not specified, all log messages will be silently eaten.

  • metrics_prefix (#to_s) (defaults to: "frankenstein_server")

    The prefix to apply to the metrics exposed instrumenting the metrics server itself.

  • registry (Prometheus::Client::Registry) (defaults to: Prometheus::Client::Registry.new)

    if you want to use an existing metrics registry for this server, pass it in here. Otherwise, a new one will be created for you, and be made available via #registry.



59
60
61
62
63
64
65
66
67
# File 'lib/frankenstein/server.rb', line 59

def initialize(port: 8080, logger: nil, metrics_prefix: "frankenstein_server", registry: Prometheus::Client::Registry.new)
  @port           = port
  @logger         = logger || Logger.new(RbConfig::CONFIG['host_os'] =~ /mingw|mswin/ ? 'NUL' : '/dev/null')
  @metrics_prefix = metrics_prefix
  @registry       = registry

  @op_mutex = Mutex.new
  @op_cv    = ConditionVariable.new
end

Instance Attribute Details

#registryObject (readonly)

The instance of Prometheus::Client::Registry that contains the metrics that will be presented by this instance of Frankenstein::Server.



43
44
45
# File 'lib/frankenstein/server.rb', line 43

def registry
  @registry
end

Instance Method Details

#runObject

Start the server instance running.

This method will return only after #shutdown is called (presumably from another thread).



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/frankenstein/server.rb', line 74

def run
  @op_mutex.synchronize do
    return AlreadyRunningError if @server

    begin
      wrapped_logger = Frankenstein::Server::WEBrickLogger.new(logger: @logger, progname: "Frankenstein::Server")
      @server = WEBrick::HTTPServer.new(Logger: wrapped_logger, BindAddress: nil, Port: @port, AccessLog: [[wrapped_logger, WEBrick::AccessLog::COMMON_LOG_FORMAT]])
      @server.mount "/", Rack::Handler::WEBrick, app
    rescue => ex
      #:nocov:
      @logger.fatal("Frankenstein::Server#run") { (["Exception while trying to create WEBrick::HTTPServer: #{ex.message} (#{ex.class})"] + ex.backtrace).join("\n  ") }
      #:nocov:
    ensure
      @op_cv.signal
    end
  end

  begin
    @server.start if @server
  rescue => ex
    #:nocov:
    @logger.fatal("Frankenstein::Server#run") { (["Exception while running WEBrick::HTTPServer: #{ex.message} (#{ex.class})"] + ex.backtrace).join("\n  ") }
    #:nocov:
  end
end

#shutdownObject

Terminate a running server instance.

If the server isn't currently running, this call is a no-op.



104
105
106
107
108
109
110
# File 'lib/frankenstein/server.rb', line 104

def shutdown
  @op_mutex.synchronize do
    return nil if @server.nil?
    @server.shutdown
    @server = nil
  end
end