Class: Above::MiddleWare::Log

Inherits:
Object
  • Object
show all
Defined in:
lib/above/middleware/log.rb

Overview

Middleware to log replies Apache common log format httpd.apache.org/docs/2.4/logs.html#common via Puma github.com/puma/puma/blob/master/lib/puma/commonlogger.rb

ip - - [time] “request” status size eg ::1 - - [24/Aug/2024:11:20:46 +1000] “gemini://localhost/” 20 143

Constant Summary collapse

FORMAT =
%(%s - - [%s] "%s" %d %d\n)
LOG_TIME_FORMAT =
"%d/%b/%Y:%H:%M:%S %z"

Instance Method Summary collapse

Constructor Details

#initialize(app:) ⇒ Log

Returns a new instance of Log.



18
19
20
21
# File 'lib/above/middleware/log.rb', line 18

def initialize(app:)
  @app = app # who you gonna call
  @logger = nil
end

Instance Method Details

#call(env:) ⇒ Object



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
# File 'lib/above/middleware/log.rb', line 23

def call(env:)
  if @logger.nil?
    config = env[:config]["Above::MiddleWare::Log"]
    # 3 one meg ("mebibyte") files rotated - TODO: chosen via config
    @logger = Logger.new(File.expand_path(config["log_file"]), 3, 1048576)
  end

  status, header, body_arr = @app.call(env:) unless @app.nil?

  # TODO: streaming, multipart

  body = if body_arr.nil? || !body_arr.is_a?(Array) || body_arr.first.nil?
    ""
  else
    body_arr.first
  end
  log(ip: env[:socket].io.remote_address.ip_address,
    request: env[:request],
    status:,
    size: body.size) # body size, not response size

  [status, header, [body]]
rescue
  # catch-all for "CGI" errors in the middleware
  [42, Status::CODE[42], []]
end

#log(ip:, request:, status:, size:) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/above/middleware/log.rb', line 50

def log(ip:, request:, status:, size:)
  began_at = Time.now

  msg = FORMAT % [ip,
    began_at.strftime(LOG_TIME_FORMAT),
    request.to_s,
    status,
    size]

  write(msg)
end

#write(msg) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/above/middleware/log.rb', line 62

def write(msg)
  # Standard library logger (to be removed in 3.4) doesn't support write but it supports << which actually
  # calls to write on the log device without formatting
  if @logger.respond_to?(:write)
    @logger.write(msg)
  else
    @logger << msg
  end
end