Class: Clogger
- Inherits:
-
Object
- Object
- Clogger
- Defined in:
- lib/clogger.rb,
lib/clogger/pure.rb,
lib/clogger/format.rb,
ext/clogger_ext/clogger.c
Overview
Not at all optimized for performance, this was written based on the original C extension code so it’s not very Ruby-ish…
Defined Under Namespace
Modules: Format
Constant Summary collapse
- OP_LITERAL =
:stopdoc:
0
- OP_REQUEST =
1
- OP_RESPONSE =
2
- OP_SPECIAL =
3
- OP_EVAL =
4
- OP_TIME_LOCAL =
5
- OP_TIME_UTC =
6
- OP_REQUEST_TIME =
7
- OP_TIME =
8
- OP_COOKIE =
9
- ALIASES =
support nginx variables that are less customizable than our own
{ '$request_time' => '$request_time{3}', '$msec' => '$time{3}', '$usec' => '$time{6}', '$http_content_length' => '$content_length', '$http_content_type' => '$content_type', }
- SPECIAL_VARS =
{ :body_bytes_sent => 0, :status => 1, :request => 2, # REQUEST_METHOD PATH_INFO?QUERY_STRING HTTP_VERSION :request_length => 3, # env['rack.input'].size :response_length => 4, # like body_bytes_sent, except "-" instead of "0" :ip => 5, # HTTP_X_FORWARDED_FOR || REMOTE_ADDR || - :pid => 6, # getpid() :request_uri => 7, :time_iso8601 => 8, :time_local => 9, :time_utc => 10, }
Instance Attribute Summary collapse
-
#body ⇒ Object
:nodoc:.
-
#body_bytes_sent ⇒ Object
writeonly
Sets the attribute body_bytes_sent.
-
#env ⇒ Object
Returns the value of attribute env.
-
#headers ⇒ Object
Returns the value of attribute headers.
-
#start ⇒ Object
writeonly
Sets the attribute start.
-
#status ⇒ Object
Returns the value of attribute status.
Instance Method Summary collapse
-
#call(env) ⇒ Array
calls the wrapped Rack application with
env
, returns the [status, headers, body ] tuplet required by Rack. -
#close ⇒ Object
Delegates the body#close call to the underlying
body
object. -
#each {|part| ... } ⇒ Object
Delegates the body#each call to the underlying
body
object while tracking the number of bytes yielded. -
#fileno ⇒ Object
:nodoc:.
-
#new(app, : logger) ⇒ Object
constructor
Creates a new Clogger object that wraps
app
. -
#initialize_copy(orig) ⇒ Object
:nodoc:.
-
#reentrant? ⇒ Boolean
:nodoc:.
-
#respond_to?(*args) ⇒ Object
used to delegate
:to_path
checks for Rack webservers that optimize static file serving. -
#to_path ⇒ Object
used to proxy
:to_path
method calls to the wrapped response body. -
#wrap_body? ⇒ Boolean
:nodoc:.
Constructor Details
#new(app, : logger) ⇒ Object
Creates a new Clogger object that wraps app
. :logger
may be any object that responds to the “<<” method with a string argument. Instead of :logger
, :path
may be specified to be a :path of a File that will be opened in append mode.
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 |
# File 'ext/clogger_ext/clogger.c', line 768 def initialize(app, opts = {}) # trigger autoload to avoid thread-safety issues later on Rack::Utils::HeaderHash @app = app @logger = opts[:logger] path = opts[:path] path && @logger and raise ArgumentError, ":logger and :path are independent" path and @logger = File.open(path, "ab") @logger.sync = true if @logger.respond_to?(:sync=) @fmt_ops = compile_format(opts[:format] || Format::Common, opts) @wrap_body = need_wrap_body?(@fmt_ops) @reentrant = opts[:reentrant] @need_resp = need_response_headers?(@fmt_ops) @body_bytes_sent = 0 end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(*args, &block) ⇒ Object (private)
150 151 152 |
# File 'lib/clogger.rb', line 150 def method_missing(*args, &block) body.__send__(*args, &block) end |
Instance Attribute Details
#body ⇒ Object
:nodoc:
1051 1052 1053 |
# File 'ext/clogger_ext/clogger.c', line 1051 def body @body end |
#body_bytes_sent=(value) ⇒ Object (writeonly)
Sets the attribute body_bytes_sent
9 10 11 |
# File 'lib/clogger/pure.rb', line 9 def body_bytes_sent=(value) @body_bytes_sent = value end |
#env ⇒ Object
Returns the value of attribute env.
8 9 10 |
# File 'lib/clogger/pure.rb', line 8 def env @env end |
#headers ⇒ Object
Returns the value of attribute headers.
8 9 10 |
# File 'lib/clogger/pure.rb', line 8 def headers @headers end |
#start=(value) ⇒ Object (writeonly)
Sets the attribute start
9 10 11 |
# File 'lib/clogger/pure.rb', line 9 def start=(value) @start = value end |
#status ⇒ Object
Returns the value of attribute status.
8 9 10 |
# File 'lib/clogger/pure.rb', line 8 def status @status end |
Instance Method Details
#call(env) ⇒ Array
calls the wrapped Rack application with env
, returns the
- status, headers, body
-
tuplet required by Rack.
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 |
# File 'ext/clogger_ext/clogger.c', line 919 def call(env) start = mono_now resp = @app.call(env) unless resp.instance_of?(Array) && resp.size == 3 log(env, 500, {}, start) raise TypeError, "app response not a 3 element Array: #{resp.inspect}" end status, headers, body = resp headers = Rack::Utils::HeaderHash.new(headers) if @need_resp if @wrap_body @reentrant = env['rack.multithread'] if @reentrant.nil? wbody = @reentrant ? self.dup : self wbody.start = start wbody.env = env wbody.status = status wbody.headers = headers wbody.body = body return [ status, headers, wbody ] end log(env, status, headers, start) [ status, headers, body ] end |
#close ⇒ Object
Delegates the body#close call to the underlying body
object. This is only used when Clogger is wrapping the body
of a Rack response and should be automatically called by the web server.
863 864 865 866 867 |
# File 'ext/clogger_ext/clogger.c', line 863 def close @body.close if @body.respond_to?(:close) ensure log(@env, @status, @headers) end |
#each {|part| ... } ⇒ Object
Delegates the body#each call to the underlying body
object while tracking the number of bytes yielded. This will log the request.
844 845 846 847 848 849 850 851 |
# File 'ext/clogger_ext/clogger.c', line 844 def each @body_bytes_sent = 0 @body.each do |part| @body_bytes_sent += part.bytesize yield part end self end |
#fileno ⇒ Object
:nodoc:
870 871 872 |
# File 'ext/clogger_ext/clogger.c', line 870 def fileno @logger.respond_to?(:fileno) ? @logger.fileno : nil end |
#initialize_copy(orig) ⇒ Object
:nodoc:
971 972 973 974 975 976 977 978 979 980 981 |
# File 'ext/clogger_ext/clogger.c', line 971
static VALUE clogger_init_copy(VALUE clone, VALUE orig)
{
struct clogger *a = clogger_get(orig);
struct clogger *b = clogger_get(clone);
memcpy(b, a, sizeof(struct clogger));
init_buffers(b);
duplicate_buffers(b->fmt_ops);
return clone;
}
|
#reentrant? ⇒ Boolean
:nodoc:
302 303 304 |
# File 'ext/clogger_ext/clogger.c', line 302 def reentrant? @reentrant end |
#respond_to?(: to_path) ⇒ Boolean #respond_to?(: close) ⇒ true
used to delegate :to_path
checks for Rack webservers that optimize static file serving
998 999 1000 |
# File 'ext/clogger_ext/clogger.c', line 998 def respond_to?(method, include_all=false) :close == method.to_sym || @body.respond_to?(method, include_all) end |
#to_path ⇒ Object
used to proxy :to_path
method calls to the wrapped response body.
1023 1024 1025 1026 1027 |
# File 'ext/clogger_ext/clogger.c', line 1023 def to_path rv = @body.to_path @body_bytes_sent = File.size(rv) rv end |
#wrap_body? ⇒ Boolean
:nodoc:
308 309 310 |
# File 'ext/clogger_ext/clogger.c', line 308 def wrap_body? @wrap_body end |