Coder Social home page Coder Social logo

rails_stdout_logging's Introduction

Rails Stdout Logging

Rails gem to configure your app to log to standard out.

Build Status

Supports:

  • Rails 3
  • Rails 4

Install

In your Gemfile add:

gem 'rails_stdout_logging'

Then run

$ bundle install

You also need the rails_serve_static_assets gem. You can get both of them together by installing the rails_12factor gem.

Why is this needed?

By default Rails writes its logs to a file, which is convenient because you only have one log file to tail. When you start scaling your app to multiple machines or dynos, it becomes much harder to find a single request or failure as they're spread across multiple files. Storing logs on disk can also take down a server if the hard drive fills up. Because of these limitations, every Rails core member we talked to uses a custom logger to replace Rails' default functionality. By using the rails_stdout_logging gem with Heroku, we set the logger for you.

The gem rails_stdout_logging ensures that your logs will be sent to standard out. From there, Heroku sends them to logplex so you can access them from the command line like $ heroku logs --tail, or from enabled addons like papertrail. By using Heroku's logplex, you can treat logs as event streams.

Why didn't I need this before?

Why do you need to include this gem in Rails 4 and not Rails 3? Rails4 is getting rid of the concept of plugins. Before libraries were easily distributed as Gems and in the form of Engines, Rails had a folder vendor/plugins. Any code you put there would be initialized much like a Gem is today. This was a very simple and easy way to share and use libraries, but it wasn't very maintainable. You could use a library, and make a change locally and then deploy which makes your version incompatible from future versions. Even worse there was no concept of versioning aside from source control, so semantic versioning was out of the question. For these reasons and more Rails3 deprecated plugins. With Rails4 plugins have been removed completely. Why does this affect your app on Heroku?

In the past Heroku has used plugins as a safe way to configure your application where code was needed. While we advocate separating config from code, this was the only option if we wanted your apps to work with no changes from you. With Rails3 Heroku will add the asset serving and standardout logging plugins to your app automatically. With Rails4, Heroku needs you to add these libraries to your Gemfile.

It is important to note that unlike Gems, plugins do not have a dependency resolution phase like what happens when you run bundle install. Heroku does not and will not add anything to your Gemfile on compilation.

Set log level

On Heroku you can set your log level by using the LOG_LEVEL environment variable

$ heroku config:set LOG_LEVEL=DEBUG

Valid values include DEBUG, INFO, WARN, ERROR, and FATAL. Alternatively you can set this value in your environment config:

config.log_level = :debug

If both are set LOG_LEVEL will take precedence.

Tests

Since we're playing with stdout we need to capture stdout. If you want to use the non captured version use DEBUG_STDOUT instead. The puts method should still behave as you expect.

We're using appraisal to build multiple gemfiles for different versions of Rails.

You can run all tests by running

$ bundle exec rake appraisal test

Rails 5

We worked with the Rails core team to make Rails 5 work on twelve-factor platforms out of the box.

New Rails 5 Apps

If you are starting a new application with Rails 5, you do not need this gem.

Migrating to Rails 5

You can remove this gem after making sure the following sections are added in your production.rb file:

config/environments/production.rb

# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

if ENV["RAILS_LOG_TO_STDOUT"].present?
  STDOUT.sync = true
  logger           = ActiveSupport::Logger.new(STDOUT)
  logger.formatter = config.log_formatter
  config.logger = ActiveSupport::TaggedLogging.new(logger)
end

Make sure to add both the RAILS_SERVE_STATIC_FILES and RAILS_LOG_TO_STDOUT ENV vars and set them to true. (This is done for you on Heroku)

rails_stdout_logging's People

Contributors

amcoder avatar bf4 avatar carlosantoniodasilva avatar ddollar avatar defp avatar dideler avatar dijonkitchen avatar hone avatar janraasch avatar kch avatar pdsphil avatar pmahoney avatar schneems avatar svc-scm avatar tagliala avatar wuputah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rails_stdout_logging's Issues

`rails_stdout_logging`, `activerecord-session_store`, `#silence`, and thread-safety.

Hi there,

After upgrading from 0.0.3 to 0.0.4 of rails_stdout_logging we starting noticing that after some point (usually about 30 minutes, but varying) our web dynos would stop logging almost completely. Messages with a severity of :error or higher still appeared in the logs, but nothing else. Our log level is set to :info.

We noticed that #15 started mixing LoggerSilence into the logger. I remember that when we introduced activerecord-session_store we had similar issues with logs (in that case we noticed it in tests - the test output would just stop) because of logger.silence calls. Looking at the code in activerecord-session_store, it is explicitly handling thread safety, whereas activesupport's LoggerSilence looks to be susceptible to thread-safety problems.

For the time being we've locked to 0.0.3, but I thought I'd just document this here in case anyone is playing along at home. It looks like there's an outstanding PR to rails (here) that should solve this once and for all.

Can anyone think of making the changes introduced in #15 opt-out-able?

Thanks!

Gem not updated with the latest code

Ran across an issue trying to set log level via config/environments/production.rb not being respected by the rails_stdout_logging gem. The code in master is setup to allow this, but you've not updated the gem with this change. Can you please do so? ๐Ÿ˜ƒ

Thanks for the great work!

Temporary workaround is to set ENV['LOG_LEVEL'] on heroku.

log ends up in rspec output

after installing 0.0.2, some logs are ending up in my rspec output, when doing controller tests.

let me know if you want more info, or if this is an rspec problem.

How does this interact / conflict with customising rails logging?

For instance, I want to prefix Rails.logger.error messages with "error" so I can find them in papertrail.

I've been trying a number of gems and not really found anything that fits, but it's made me wonder what they're doing to the logging set up here, and if there are load-order issues.

For instance lograge, shog, and concise_logging.

It'd be handy if the readme could give some general advice on this.

Conflict with Rails 4.2.6 and Mongoid 5.1.1

Hi,

I'm using this gem via rails_12factor and there is an issue with the latest Rails 4.2.6 and mongoid (5.1.1, but maybe older)

Here it is a reduced test case
https://github.com/tagliala/mongoid-rails-426/tree/rails_stdout_logging

~/dev/tests/mongoid-rails-426 on rails_stdout_logging $ rake routes
rake aborted!
NoMethodError: undefined method `[]' for nil:NilClass
~/.rvm/gems/ruby-2.3.0/gems/activesupport-4.2.6/lib/active_support/logger_silence.rb:23:in `level'
~/.rvm/gems/ruby-2.3.0/gems/mongoid-5.1.1/lib/mongoid/config.rb:250:in `set_log_levels'
~/.rvm/gems/ruby-2.3.0/gems/mongoid-5.1.1/lib/mongoid/config.rb:132:in `load_configuration'
~/.rvm/gems/ruby-2.3.0/gems/mongoid-5.1.1/lib/mongoid/config.rb:88:in `load!'
~/.rvm/gems/ruby-2.3.0/gems/mongoid-5.1.1/lib/mongoid.rb:99:in `load!'
~/.rvm/gems/ruby-2.3.0/gems/mongoid-5.1.1/lib/mongoid/railtie.rb:59:in `block in <class:Railtie>'
~/.rvm/gems/ruby-2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:30:in `instance_exec'
~/.rvm/gems/ruby-2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:30:in `run'
~/.rvm/gems/ruby-2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:55:in `block in run_initializers'
~/.rvm/gems/ruby-2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:54:in `run_initializers'
~/.rvm/gems/ruby-2.3.0/gems/railties-4.2.6/lib/rails/application.rb:352:in `initialize!'
~/dev/tests/mongoid-rails-426/config/environment.rb:5:in `<top (required)>'
~/.rvm/gems/ruby-2.3.0/gems/railties-4.2.6/lib/rails/application.rb:328:in `require'
~/.rvm/gems/ruby-2.3.0/gems/railties-4.2.6/lib/rails/application.rb:328:in `require_environment!'
~/.rvm/gems/ruby-2.3.0/gems/railties-4.2.6/lib/rails/application.rb:457:in `block in run_tasks_blocks'
~/.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `eval'
~/.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => routes => environment
(See full trace by running task with --trace)

Rails 4.2.5 was fine
https://github.com/tagliala/mongoid-rails-425/tree/rails_stdout_logging

~/dev/tests/mongoid-rails-425 on rails_stdout_logging $ rake routes
You don't have any routes defined!

Please add some routes in config/routes.rb.

For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html.

Rails 4.2.6 with postgresql is also fine

This issue makes applications impossible to deploy on Heroku because rake assets:precompile will fail

Example: https://github.com/diowa/ruby2-rails4-bootstrap-heroku/tree/mongoid

Please try the "Deploy to Heroku" button. You could also try the master branch, which does not use mongoid

Rails logger silence is not available

We've hit an issue in production trying to use the Rails silence method on the logger:

Rails.logger.silence { do_work }

This works fine with the normal Rails logger because it includes the LoggerSilence module, which provides the silence method.

However, the heroku logger provided by this gem does not, which means the silence call ends up being the one available through the Kernel extension that Rails adds (which is deprecated btw), and turns into an ArgumentError:

#<ArgumentError: wrong number of arguments (0 for 1)>.

...gems/activesupport-4.2.1/lib/active_support/core_ext/kernel/reporting.rb:88:in `capture'

For now I've fixed this locally by including the LoggerSilence into the logger's singleton class when activating the stdout logging (since it needs to be included to have everything properly set up), and I'm wondering if this is something we can fix up in the gem itself, either by doing the same include:

logger.singleton_class.include(LoggerSilence) if defined?(LoggerSilence)

Or by having a specific logger class for the gem, like:

  class StdoutLogger < ::Logger
    include ::LoggerSilence if defined?(::LoggerSilence)
  end

I think I prefer the second approach. Thoughts?

Migrating to Rails 5 notice does not include STDOUT.sync = true

Hi there, we recently switched to rails 5 and had some problems with stuff not showing up in our logs on heroku. Is there a specific reason why

STDOUT.sync = true

is not part of the Migrating to Rails 5-section on the README?

On the docs (https://devcenter.heroku.com/articles/logging#writing-to-your-log) it says

To take advantage of the real-time logging, you may need to disable any log buffering your application may be carrying out.

and it was part of this gem: https://github.com/heroku/rails_stdout_logging/blob/master/lib/rails_stdout_logging/rails.rb#L18.

Is there a specific reason for leaving it out on the README and this is not needed when using rails v5?

rails 4 support?

this gem is mentioned in the rails_12factor docs in the "rails 4 section" but init.rb doesn't seem to do anything with rails v4

STDOUT logging loses severity levels when passed through Logplex

Firstly, I realise this repo is old and deprecated, I just couldn't find a better place to raise this issue. Please point me somewhere else or tell me it's too unrelated if necessary.

One of the problems with Rails logging into Logplex via STDOUT is that the log levels are flattened, at best identifiable by text tags in the message. This is understandable, as simple IO streams just don't have the ability to tag different lines with different severities (they don't even have the concept of "lines" really)

Specifically, on the Heroku platform, all STDOUT is fed to Logplex as priority 190 (syslog facility/severity: local7/information). This reduces the effectiveness of using Logplex's syslog drains in addons like Papertrail, which otherwise have the ability to filter messages by incoming severity.

Papertrail's interface, showing a syslog severity filter being able to identify lines tagged by Heroku Postgres

I'm listing this as an issue with the concept of an STDOUT logger because it feels like it should be (conceptually) possible to use syslog as an input to Logplex in the same way as e.g. Heroku Postgres appears to do in the screenshot above (it's definitely logging at different severities). A class like stdlib's Syslog::Logger feels like it should in theory be able to integrate with Logplex in the same way that Postgres already does, unless there's something about the dyno architecture that makes that impossible.

I realise that in practice this isn't possible to configure on Heroku at the moment, but am I even right in theory?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.