Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logging from Classes and Modules doesn't work as expected. #1246

Closed
Joshfindit opened this issue Jan 29, 2017 · 8 comments
Closed

Logging from Classes and Modules doesn't work as expected. #1246

Joshfindit opened this issue Jan 29, 2017 · 8 comments

Comments

@Joshfindit
Copy link

Joshfindit commented Jan 29, 2017

Starting first with a classic application, and splitting the models/libs in to folders that are included/loaded.

When specifying the logger in the main file:

configure do
  logfile = File.new("#{settings.root}/log/#{settings.environment}.log", 'a+')
  logfile.sync = true
  use Rack::CommonLogger, logfile
  set :logger, Logger.new(logfile)
end

Calling logger.debug from a module or class returns NameError: undefined local variable or method `logger' for <Object or Module>

@mwpastore
Copy link
Member

Can you show more code that clarifies what's in your modules and how you're including them in the main application?

@Joshfindit
Copy link
Author

@Joshfindit
Copy link
Author

@mwpastore
Copy link
Member

There's a lot of code here, would it be possible for you to distill it into a smaller test case?

@Joshfindit
Copy link
Author

The essence is this:

  • notesapp_sinatra.rb brings in models with require_relative or load (tried both, and am open to suggestions)
  • Models are not subclassed
  • Calling the logger from notesapp_sinatra.rb works
  • Calling the logger from any model does not work (gives the NameError above)

@mwpastore
Copy link
Member

Rack loggers are really only available in the request scope of the application, and Sinatra's logger helper method is only available within the Sinatra application class where logging was configured.

Sinatra's DSL and method delegation make it look like magic, but you have to remember that there is always a class (Sinatra::Application, or a subclass of Sinatra::Application or Sinatra::Base) behind the scenes holding the methods and behavior that make up a Sinatra application. Consider this simple example:

class Foo
  def one; 1 end
end

class Bar
  def two
    one + one
  end
end

Bar.new.two

Would you expect this to work? No, I hope not, because we haven't told Bar how to access Foo#one. The two classes and their instance methods are completely isolated from one another. This is a core tenant of Ruby and many other object-oriented programming languages. So you shouldn't expect Artefact#return_error_via_log to be able to access Sinatra::Application#logger, either!

You have a few options on how to proceed here. Probably the easiest and most common solution would be to create a separate logger to use in your models and wherever else. You can keep a handle to the logging object in a global or a constant, or use some dependency injection scheme. Then you have the option of either using that logger in your Sinatra application for requests and/or other messages or accepting Sinatra's default behavior.

@Joshfindit
Copy link
Author

Thank you for this comprehensive response.
This actually fills in a lot of other small gaps as I had assumed that Sinatra was the superclass of everything within classic applications.

Are there any straightforward examples that flesh out the different levels of Sinatra's scopes? Having whipped up a number of simple applications without any show-stoppers, it's just a matter of wrapping my head around this. The documentation looks good, but packed.

@mwpastore
Copy link
Member

None that I know of. The documentation is the best resource. Yes, it is packed, but your understanding will deepen each time you read through it as you learn Sinatra.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants