0

I am pretty new in Rails. I need to log some info into a file inside a function from a class derived of ActionController::Base. I only need to append to the file once, but I should make sure any concurrent processes/threads do not destroy my lines. I do not need any fancy time/IP, etc formatting in my logs.

I have been trying to figure out how to create a custom log but I get confused as all available examples derive it from ActiveRecord::Base (see for example this answer). I also checked how to atomically write to a file with File#flock, but I am not sure whether this is what I really need.

Any help pointing me to th right direction will be appreciated!

Community
  • 1
  • 1
XAnguera
  • 1,157
  • 1
  • 11
  • 25

1 Answers1

1

I'd recommend using Ruby's Logger class.

require 'logger'

logger = Logger.new('FILE_PATH_TO_LOG_TO')
logger.level = Logger::Info

Then you can use flock to lock the file and then write out to the file with:

logger.info("INFO_TO_WRITE")

This way you should be able to log what you need to, and make sure there's no competing access.

Another reference: http://ruby-doc.org/stdlib-2.3.0/libdoc/logger/rdoc/Logger.html

or: http://guides.rubyonrails.org/v3.2/debugging_rails_applications.html#the-logger

KJS
  • 42
  • 7
  • Thanks @KJS for the answer. I will try that. Just one question: if I use the "logger" class, wouldn't it already ensure me write atomicity? if so, I would not need Flock, right? – XAnguera Jul 29 '16 at 22:45
  • I was looking for something like that, but I was unable to find a clear explanation on if it wrote atomically. From what I saw it looked like you would need something to control it – KJS Jul 30 '16 at 23:37
  • I tried your proposal by placing the logger.new() statement in the initialize method of my class, but it gets called every time a function in the class gets called. I suspect this this heavily non-optimal and I am experimenting now with opening-appending-closing the file myself whenever I need to log something. – XAnguera Jul 31 '16 at 19:29
  • What do you mean? Logger.new() in your init gets hit every time you use any function in the class? That doesn't seem right. Could this have to do with concurrent class instantiations? I would say opening, writing and closing would not be the best method. But without more to go on, do what works. – KJS Aug 01 '16 at 05:24
  • Maybe I should had explicitly said that my class is implementing Rails requests, which by definition create a new instance of the class for each request. – XAnguera Aug 03 '16 at 11:19
  • You could create a singleton method around your logger, and then when the request goes through it just gets the logger context and then you can write out with it from there. – KJS Aug 03 '16 at 21:57