我的 Sinatra API 应用程序需要 class 声明吗?

Does my Sinatra API application need a class declaration?

有人为我开发了一个 API 应用程序,效果很好。不幸的是,它不会在任何地方记录并且根本没有日志。该应用程序使用 "rackup" 命令运行,并位于 nginx 网络服务器后面。 Sinatra 错误未记录到 nginx 日志中。

app.rb 文件看起来像这样:

require './libs'
require 'sinatra'
require 'sinatra/namespace'

set :bind, '::1'

before do
  content_type :json
  headers 'Access-Control-Allow-Origin' => '*',  'Access-Control-Allow-Methods' => ['OPTIONS', 'GET', 'POST']
end

namespace '/api/v1' do
  namespace '/getit/:thingtoget' do
    helpers do
      def myhelper1
        <stuff>
      end
      def myhelper1
        <stuff>
      end
   end

   before do
     myhelper1
     myhelper2
   end

   get '/info' do
     WidgetDomain::get_info(@va1, @var2).to_json
   end

   <more API paths here>

 end

现在一切正常。但是现在我想介绍日志记录。所以我查看了 Sinatra 自述文件,它说我可以像这样启用日志记录:

class MyApp < Sinatra::Base
  configure :production, :development do
    enable :logging
  end
end

我要把它放在 namespace 上面吗?如果我声明一个这样的应用程序,我的命名空间内容是否需要以某种方式位于该应用程序代码中?我完全不了解它是如何工作的。

它几乎看起来像是在尝试 登录 nginx 日志,但错误行如下所示:

2018/12/30 19:53:15 [error] 6615#0: *21522 connect() failed (111: Connection refused) while connecting to upstream, client: <someip>, server: api.example.com, request: "GET /api/v1/getit/thingtoget1/stuff/var1/var2/var3 HTTP/1.1", upstream: "http://[::1]:9292/api/v1/getit/thingtoget/stuff/var1/var2/var3", host: "api.example.com", referrer: "an HTML page from the nginx server"

这几乎就像是在尝试连接回服务器以检索消息或其他内容。但是如果日志记录与我在 nginx 配置中声明服务器的方式有关,这里是:

server {
    listen 443;
    listen [::]:443;
    server_name api.myapp.com;

    ssl on;
    ssl_certificate /etc/nginx/ssl/myapp_com.pem;
    ssl_certificate_key /etc/nginx/ssl/star_myapp_com.key;

    location / {
      proxy_pass http://localhost:9292;
    }

}

看看 Sinatra 的 README 在日志记录部分,但我倾向于在 Sinatra 应用程序之外设置一个记录器,以防其他位被固定或多个应用程序一起使用,我可以使用所有人都使用相同的记录器。最简单的方法是一个全局变量(他们可以接受的少数几个地方之一,但这不是唯一的方法):

require 'mono_logger' # because it's thread safe
require 'pathname'    # because paths aren't strings :)

log_path = Pathname(__dir__).join("logs/app.log")
$logger = MonoLogger.new(log_path)
$logger.level = MonoLogger::INFO

然后在路线或任何地方:

get '/' do
  $logger.info "here"

在我的终端中:

$ cat logs/app.log 
I, [2019-01-07T13:03:52.989415 #64378]  INFO -- : here

至于配置块,您不必担心将它们放在 class 声明中,除非您使用的是模块化应用程序(请参阅 README 中的模块化与经典样式)并且您的是classic 风格。

配置块没有命名空间(Sinatra::Namespace 处理将路由作为参数的事情,例如 getbefore)所以请遵循约定并将其粘贴在靠近顶部的位置文件。

希望对您有所帮助。