Tôi có một máy chủ web nhỏ mà tôi đã viết với Sinatra. Tôi muốn có thể đăng nhập tin nhắn vào một tệp nhật ký. Tôi đã đọc qua http://www.sinatrarb.com/api/index.html và www.sinatrarb.com/intro.html và tôi thấy rằng Rack có tên Rack :: CommonLogger, nhưng tôi không thể tìm thấy bất kỳ ví dụ nào về cách nó có thể được truy cập và sử dụng để ghi nhật ký. Ứng dụng của tôi rất đơn giản vì vậy tôi đã viết nó như là một DSL cấp cao nhất, nhưng tôi có thể chuyển sang phân lớp nó từ SinatraBase nếu đó là một phần của những gì được yêu cầu.Sử dụng Rack :: CommonLogger in Sinatra
Trả lời
Rack::CommonLogger
sẽ không cung cấp nhật ký cho ứng dụng chính của bạn, nó sẽ chỉ ghi lại yêu cầu như Apache sẽ thực hiện.
Kiểm tra mã của mình: https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb
Tất cả Rack
ứng dụng có gọi phương thức mà có được ấy gọi với HTTP Request env, nếu bạn đánh dấu vào phương pháp gọi của middleware này đây là những gì sẽ xảy ra:
def call(env)
began_at = Time.now
status, header, body = @app.call(env)
header = Utils::HeaderHash.new(header)
log(env, status, header, began_at)
[status, header, body]
end
@app
Trong trường hợp này là ứng dụng chính, phần mềm trung gian chỉ đăng ký thời gian yêu cầu bắt đầu, sau đó lớp trung gian của bạn nhận được [trạng thái, tiêu đề, nội dung] ba và sau đó gọi phương thức nhật ký riêng với các tham số đó , trả lại cùng một gấp ba lần Trang được trả lại ngay từ đầu.
Phương pháp logger
đi như thế:
def log(env, status, header, began_at)
now = Time.now
length = extract_content_length(header)
logger = @logger || env['rack.errors']
logger.write FORMAT % [
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
env["REMOTE_USER"] || "-",
now.strftime("%d/%b/%Y %H:%M:%S"),
env["REQUEST_METHOD"],
env["PATH_INFO"],
env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
env["HTTP_VERSION"],
status.to_s[0..3],
length,
now - began_at ]
end
Như bạn có thể nói, phương pháp log
chỉ lấy một số thông tin từ env yêu cầu, và đăng nhập vào trên một logger được chỉ định vào cuộc gọi constructor, nếu có không dụ logger sau đó nó đi vào rack.errors
logger (có vẻ như có một mặc định)
cách sử dụng nó (trong bạn config.ru
):
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
run YourApp
Nếu bạn muốn có một logger phổ biến ở tất cả các ứng dụng của bạn, bạn có thể tạo một middleware logger đơn giản:
class MyLoggerMiddleware
def initialize(app, logger)
@app, @logger = app, logger
end
def call(env)
env['mylogger'] = @logger
@app.call(env)
end
end
Để sử dụng nó, trên config.ru
của bạn:
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp
Hope this helps.
Tôi đi theo những gì tôi tìm thấy trên blog bài này - trích dưới đây
require 'rubygems'
require 'sinatra'
disable :run
set :env, :production
set :raise_errors, true
set :views, File.dirname(__FILE__) + '/views'
set :public, File.dirname(__FILE__) + '/public'
set :app_file, __FILE__
log = File.new("log/sinatra.log", "a")
STDOUT.reopen(log)
STDERR.reopen(log)
require 'app'
run Sinatra.application
sau đó sử dụng puts
hoặc print
. Nó làm việc cho tôi.
đó làm việc, nhưng tôi thực sự muốn tìm hiểu làm thế nào để sử dụng rack :: CommonLogger để gửi tin nhắn được định dạng với thời gian. –
Trong config.ru
của bạn:
root = ::File.dirname(__FILE__)
logfile = ::File.join(root,'logs','requests.log')
require 'logger'
class ::Logger; alias_method :write, :<<; end
logger = ::Logger.new(logfile,'weekly')
use Rack::CommonLogger, logger
require ::File.join(root,'myapp')
run MySinatraApp.new # Subclassed from Sinatra::Application
tôi thử giải pháp của bạn, và nó hoạt động. tôi tự hỏi tại sao nó phải ở trong config.ru? – Chamnap
một tập tin những điều tôi không 100% trên đó, bạn sẽ nhớ bình luận về những gì/lý do tại sao một số dòng là có xin vui lòng? –
class ErrorLogger
def initialize(file)
@file = ::File.new(file, "a+")
@file.sync = true
end
def puts(msg)
@file.puts
@file.write("-- ERROR -- #{Time.now.strftime("%d %b %Y %H:%M:%S %z")}: ")
@file.puts(msg)
end
end
class App < Sinatra::Base
if production?
error_logger = ErrorLogger.new('log/error.log')
before {
env["rack.errors"] = error_logger
}
end
...
end
Mở lại STDOUT và chuyển hướng nó vào một tập tin không phải là một ý tưởng tốt nếu bạn sử dụng hành khách. Nó gây ra trong trường hợp của tôi rằng Hành khách không bắt đầu. Đọc https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems#stdout-redirection cho vấn đề này.
Đây sẽ là một cách đúng đắn thay vì:
logger = ::File.open('log/sinatra.log', 'a+')
Sinatra::Application.use Rack::CommonLogger, logger
- 1. Sử dụng Rack :: Session :: Pool với Sinatra
- 2. Sinatra/1.4.3 sử dụng rack :: phiên :: cảnh báo Cookie
- 3. Truyền dữ liệu từ ứng dụng Sinatra/Rack
- 4. Cài đặt bảo vệ Sinatra và Rack
- 5. Sinatra ứng dụng sử dụng omniauth được rack :: Bảo vệ :: SessionHijacking trong ie9
- 6. Rack/Sinatra LoadError: không thể tải tập tin như vậy
- 7. Sử dụng `Rack :: Session :: Pool` trên` Rack :: Session :: Cookie`
- 8. sinatra config.ru: khối cấu hình là gì?
- 9. Cách đăng dữ liệu trong Rack :: Thử nghiệm
- 10. Tiêm phụ thuộc trong ứng dụng Sinatra
- 11. Đường ray - Tên miền cookie động sử dụng Rack
- 12. Chạy Sinatra trên cổng 80
- 13. Tránh khai báo phụ thuộc Bundler thừa cho Rack
- 14. Rails/Rack ... Rack :: ReverseProxy Gây Yêu cầu Timeout
- 15. Làm thế nào để sử dụng Sprockets với Sinatra mà không có một tập tin rackup?
- 16. Ít treo ứng dụng Sinatra
- 17. Làm cách nào để chỉ định Tùy chọn danh sách trắng gốc ở Sinatra bằng Rack/Protection
- 18. Khi nào sử dụng node.js so với sinatra vs ray?
- 19. Sử dụng Sidekiq, Capistrano, Sinatra cho triển khai
- 20. Sử dụng nén gzip ở Sinatra với Ruby
- 21. Có bất kỳ ví dụ cơ bản về Rack :: Session :: Cookie sử dụng không?
- 22. Sinatra + Bundler?
- 23. Làm thế nào để bắt đầu một ứng dụng Sinatra sử dụng "chạy"
- 24. API Sinatra và Grape cùng nhau?
- 25. Lỗi khi tải đá quý Active Record bằng ứng dụng Sinatra sử dụng RVM
- 26. Xóa cơ sở dữ liệu.yml khi sử dụng Mongoid in Rails 3.2
- 27. Máy chủ Sinatra đẩy?
- 28. Làm thế nào để chạy nhiều ứng dụng Ruby (Rack) nhỏ trên một máy chủ?
- 29. Sinatra vs. Rails
- 30. Làm cách nào để Sinatra hoạt động qua HTTPS/SSL?
Không phải dòng đầu tiên của cuộc gọi MyLoggerMiddleware # (env) là: env ['rack.errors'] = @logger ? –
Ngoài ra, tôi không muốn đăng nhập mọi yêu cầu, chỉ cảnh báo và thông báo lỗi. Nhưng tôi muốn nó được cấu hình để tôi có thể thiết lập mức độ đăng nhập, như trong "gỡ rối", "thông tin", "cảnh báo", "lỗi", ... BTW - Ứng dụng của tôi không phải là một Rails ứng dụng. Không có tệp config.ru. Đó là một ứng dụng Sinatra đơn giản. Tôi đã hy vọng sử dụng một tiêu chuẩn hiện có, nhưng không thể hiểu được đó là gì. Có lẽ tôi phải lấy CommonLogger bạn cho tôi xem và tự mình làm một mình? –
'config.ru' là tệp cấu hình cho Rack, không phải cho Rails. Cả Sinatra và Rails đều dựa trên Rack, vì vậy bạn có thể sử dụng 'config.ru' trong các ứng dụng Sinatra. – jafrog