代码之家  ›  专栏  ›  技术社区  ›  RubyRedGrapefruit

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

  •  1
  • RubyRedGrapefruit  · 技术社区  · 6 年前

    有人为我开发了一个API应用程序,效果很好。不幸的是,它在任何地方都没有日志,而且根本没有日志。该应用程序使用“rackup”命令运行,位于nginx web服务器后面。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;
        }
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   ian    6 年前

    看看西纳特拉的 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
    

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

    配置块没有名称空间( Sinatra::Namespace 处理以路由作为参数的事情,例如 get before )所以按照惯例,把它贴在文件的顶部。

    希望有帮助。