2019-07-16 18:53:28 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2011-09-22 19:24:43 -07:00
|
|
|
# Standard libraries
|
|
|
|
require 'socket'
|
|
|
|
require 'tempfile'
|
|
|
|
require 'time'
|
|
|
|
require 'etc'
|
|
|
|
require 'uri'
|
|
|
|
require 'stringio'
|
|
|
|
|
|
|
|
require 'thread'
|
|
|
|
|
2022-09-21 01:00:30 -05:00
|
|
|
# use require, see https://github.com/puma/puma/pull/2381
|
2020-09-24 19:07:54 +02:00
|
|
|
require 'puma/puma_http11'
|
2022-09-21 01:00:30 -05:00
|
|
|
|
|
|
|
require_relative 'puma/detect'
|
|
|
|
require_relative 'puma/json_serialization'
|
2020-07-03 15:40:13 -05:00
|
|
|
|
2016-09-05 11:29:16 -07:00
|
|
|
module Puma
|
2022-09-21 01:00:30 -05:00
|
|
|
autoload :Const, "#{__dir__}/puma/const"
|
|
|
|
autoload :Server, "#{__dir__}/puma/server"
|
|
|
|
autoload :Launcher, "#{__dir__}/puma/launcher"
|
Expose top level Puma.stats API
Right now to get stats for a puma process the only way is to go through the control server. The puma-stats-logger does this by reading in a state file then querying the control server manually.
https://github.com/hired/puma-stats-logger/blob/7ad7798e9d06ff44e047ac56d0307c4ff9c73751/lib/puma_stats_logger/middleware.rb#L28
Instead, I’m proposing adding a top level `Puma.stats` method that will allow anyone inside of the same process to get access to the stats.
This could be instrumented by a gem to theoretically export these stats to say a Heroku dashboard where we could list out backlog or thread count.
The format of stats is a hash, and will change depending on if the server is in “single” or “clustered” mode.
Clustered:
```
{ "workers": 2, "phase": 0, "booted_workers": 2, "old_workers": 0, "worker_status": [{ "pid": 19832, "index": 0, "phase": 0, "booted": true, "last_checkin": "2018-03-12T16:03:12Z", "last_status": { "backlog":0, "running":5 } },{ "pid": 19833, "index": 1, "phase": 0, "booted": true, "last_checkin": "2018-03-12T16:03:12Z", "last_status": { "backlog":0, "running":5 } }] }
```
Single:
```
{ "backlog": 0, "running": 2 }
```
Alternatively if we could somehow enable another process to get these stats from Puma via pumactl by default without requiring any additional in app config, that would also work.
2018-03-12 11:41:39 -05:00
|
|
|
|
2021-02-01 15:10:28 -06:00
|
|
|
# at present, MiniSSL::Engine is only defined in extension code (puma_http11),
|
|
|
|
# not in minissl.rb
|
|
|
|
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
|
|
|
|
2021-03-15 09:10:43 -05:00
|
|
|
HAS_UNIX_SOCKET = Object.const_defined? :UNIXSocket
|
|
|
|
|
2021-02-01 15:10:28 -06:00
|
|
|
if HAS_SSL
|
2022-09-21 01:00:30 -05:00
|
|
|
require_relative 'puma/minissl'
|
2021-02-01 15:10:28 -06:00
|
|
|
else
|
|
|
|
module MiniSSL
|
|
|
|
# this class is defined so that it exists when Puma is compiled
|
|
|
|
# without ssl support, as Server and Reactor use it in rescue statements.
|
|
|
|
class SSLError < StandardError ; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.ssl?
|
|
|
|
HAS_SSL
|
|
|
|
end
|
|
|
|
|
2021-04-24 18:24:44 -05:00
|
|
|
def self.abstract_unix_socket?
|
|
|
|
@abstract_unix ||=
|
|
|
|
if HAS_UNIX_SOCKET
|
|
|
|
begin
|
|
|
|
::UNIXServer.new("\0puma.temp.unix").close
|
|
|
|
true
|
|
|
|
rescue ArgumentError # darwin
|
|
|
|
false
|
|
|
|
end
|
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-09-25 13:50:57 -05:00
|
|
|
# @!attribute [rw] stats_object=
|
Expose top level Puma.stats API
Right now to get stats for a puma process the only way is to go through the control server. The puma-stats-logger does this by reading in a state file then querying the control server manually.
https://github.com/hired/puma-stats-logger/blob/7ad7798e9d06ff44e047ac56d0307c4ff9c73751/lib/puma_stats_logger/middleware.rb#L28
Instead, I’m proposing adding a top level `Puma.stats` method that will allow anyone inside of the same process to get access to the stats.
This could be instrumented by a gem to theoretically export these stats to say a Heroku dashboard where we could list out backlog or thread count.
The format of stats is a hash, and will change depending on if the server is in “single” or “clustered” mode.
Clustered:
```
{ "workers": 2, "phase": 0, "booted_workers": 2, "old_workers": 0, "worker_status": [{ "pid": 19832, "index": 0, "phase": 0, "booted": true, "last_checkin": "2018-03-12T16:03:12Z", "last_status": { "backlog":0, "running":5 } },{ "pid": 19833, "index": 1, "phase": 0, "booted": true, "last_checkin": "2018-03-12T16:03:12Z", "last_status": { "backlog":0, "running":5 } }] }
```
Single:
```
{ "backlog": 0, "running": 2 }
```
Alternatively if we could somehow enable another process to get these stats from Puma via pumactl by default without requiring any additional in app config, that would also work.
2018-03-12 11:41:39 -05:00
|
|
|
def self.stats_object=(val)
|
|
|
|
@get_stats = val
|
|
|
|
end
|
|
|
|
|
2020-09-25 13:50:57 -05:00
|
|
|
# @!attribute [rw] stats_object
|
Expose top level Puma.stats API
Right now to get stats for a puma process the only way is to go through the control server. The puma-stats-logger does this by reading in a state file then querying the control server manually.
https://github.com/hired/puma-stats-logger/blob/7ad7798e9d06ff44e047ac56d0307c4ff9c73751/lib/puma_stats_logger/middleware.rb#L28
Instead, I’m proposing adding a top level `Puma.stats` method that will allow anyone inside of the same process to get access to the stats.
This could be instrumented by a gem to theoretically export these stats to say a Heroku dashboard where we could list out backlog or thread count.
The format of stats is a hash, and will change depending on if the server is in “single” or “clustered” mode.
Clustered:
```
{ "workers": 2, "phase": 0, "booted_workers": 2, "old_workers": 0, "worker_status": [{ "pid": 19832, "index": 0, "phase": 0, "booted": true, "last_checkin": "2018-03-12T16:03:12Z", "last_status": { "backlog":0, "running":5 } },{ "pid": 19833, "index": 1, "phase": 0, "booted": true, "last_checkin": "2018-03-12T16:03:12Z", "last_status": { "backlog":0, "running":5 } }] }
```
Single:
```
{ "backlog": 0, "running": 2 }
```
Alternatively if we could somehow enable another process to get these stats from Puma via pumactl by default without requiring any additional in app config, that would also work.
2018-03-12 11:41:39 -05:00
|
|
|
def self.stats
|
2021-06-09 16:55:45 +02:00
|
|
|
Puma::JSONSerialization.generate @get_stats.stats
|
2020-05-10 20:20:19 -05:00
|
|
|
end
|
|
|
|
|
2020-09-25 13:50:57 -05:00
|
|
|
# @!attribute [r] stats_hash
|
2020-09-17 10:15:19 -05:00
|
|
|
# @version 5.0.0
|
2020-05-10 20:20:19 -05:00
|
|
|
def self.stats_hash
|
Expose top level Puma.stats API
Right now to get stats for a puma process the only way is to go through the control server. The puma-stats-logger does this by reading in a state file then querying the control server manually.
https://github.com/hired/puma-stats-logger/blob/7ad7798e9d06ff44e047ac56d0307c4ff9c73751/lib/puma_stats_logger/middleware.rb#L28
Instead, I’m proposing adding a top level `Puma.stats` method that will allow anyone inside of the same process to get access to the stats.
This could be instrumented by a gem to theoretically export these stats to say a Heroku dashboard where we could list out backlog or thread count.
The format of stats is a hash, and will change depending on if the server is in “single” or “clustered” mode.
Clustered:
```
{ "workers": 2, "phase": 0, "booted_workers": 2, "old_workers": 0, "worker_status": [{ "pid": 19832, "index": 0, "phase": 0, "booted": true, "last_checkin": "2018-03-12T16:03:12Z", "last_status": { "backlog":0, "running":5 } },{ "pid": 19833, "index": 1, "phase": 0, "booted": true, "last_checkin": "2018-03-12T16:03:12Z", "last_status": { "backlog":0, "running":5 } }] }
```
Single:
```
{ "backlog": 0, "running": 2 }
```
Alternatively if we could somehow enable another process to get these stats from Puma via pumactl by default without requiring any additional in app config, that would also work.
2018-03-12 11:41:39 -05:00
|
|
|
@get_stats.stats
|
|
|
|
end
|
2019-09-15 10:52:34 +02:00
|
|
|
|
|
|
|
def self.set_thread_name(name)
|
|
|
|
Thread.current.name = "puma #{name}"
|
|
|
|
end
|
2016-09-05 11:29:16 -07:00
|
|
|
end
|