README.rdoc in right_support-1.4.1 vs README.rdoc in right_support-2.0.0

- old
+ new

@@ -7,93 +7,109 @@ SystemLogger is a rewrite of the seattle.rb SyslogLogger class that features the following improvements: * Contains several bugfixes vs. SyslogLogger 1.4.0 * Inherits from standard Ruby Logger class for guaranteed compatibility * Can be configured with options about how to handle newlines, ANSI escape codes, etc -It is very similar to SystemLogger, with a few differences (e.g. it is a child class of Logger instead of -merely being duck-type compatible). You use it as follows. +We also provide Log::Mixin, a powerful tool that lets you sprinkle a logger +into any object or class, and supports per-class or per-instance custom +loggers! - @logger = SystemLogger.new('my_cool_app', :split=>true, :color=>false) - @logger.info "Hello world\nThis will appear on separate lines\nand without \e[33;0mbeautiful colors" + class Jet < Aircraft + include RightSupport::Log.Mixin + end -CustomLogger is a Rack middleware that allows a Rack app to use any log sink it wishes. The + #most jets log to the syslog + Jet.logger = RightSupport::Log::SystemLogger.new('black box', + :facility=>'local0') + + #but MY jet + @my_jet.logger = Logger.new(StringIO.new) + +==== Logging for Rack Applications + +RightSupport also provides Rack middleware that allows a Rack app to use any log sink it wishes. The stock Rack logger middleware is inflexible and gives the end user no control over which logger is used -or where the log entries go. +or where the log entries go. Example of usage on Sinatra based application: - require 'right_support/rack/custom_logger' + class MyApp < Sinatra::Base + ... + # Specify which logger will be used as default logger + LOGGER =\ + if ENV['RACK_ENV'].downcase == 'development' + Logger.new(STDOUT) + else + RightSupport::Log::SystemLogger.new("MyApp", {:facility => "local0"}) + end - my_logger = MyAwesomeLogger.new - use RightSupport::Rack::CustomLogger, Logger::INFO, my_logger + # use the RequestLogger via LogSetter to log requests for application + use RightSupport::Rack::LogSetter, {:logger => LOGGER} + use RightSupport::Rack::RequestLogger -=== String Manipulation + # set logger and mix Log::Mixin + RightSupport::Log::Mixin.default_logger = LOGGER + include RightSupport::Log::Mixin + ... + end -StringExtensions contains String#camelize, which is only defined if the -ActiveSupport gem cannot be loaded. It also has some RightScale-specific -methods: -* String#snake_case -* String#to_const -* String#to_const_path +After that all rack requests to MyApp will be logged, and since we mixed Log::Mixin we can use: -Net::StringEncoder applies and removes URL-escape, base64 and other encodings. + logger.info "Hello world\nThis will appear on separate lines\nand without \e[33;0mbeautiful colors" -=== Input Validation +=== Networking Stuff -Validation contains several format-checkers that can be used to validate your -web app's models before saving, check for preconditions in your controllers, -and so forth. +==== HTTP Client -You can use it as a mixin by including the appropriate child module of -RightSupport::Validation. +We provide a very thin wrapper around the rest-client gem that enables simple but +robust rest requests with a timeout, headers, etc. - class AwesomenessGenerator < ActiveRecord::Base - include RightSupport::Validation::OpenSSL +HTTPClient is interface-compatible with the RestClient module, but allows an +optional timeout to be specified as an extra parameter. - before_save do |record| - errors[:foo] = 'Hey, that's not a key!' unless pem_public_key?(record.foo) - end - end + # Create a wrapper object + @client = RightSupport::Net::HTTPClient.new -But you really don't want to do that, do you? Instead, you want to call the module -methods of RightSupport::Validation, which contains all of the same mixin methods, -but does not pollute the dispatch table of your application classes. + # Default timeout is 5 seconds + @client.get('http://localhost') - the_key = STDIN.read - raise ArgumentError unless RightSupport::Validation.ssh_public_key?(the_key) + # Make sure the HTTPClient request fails after 1 second so we can report an error + # and move on! + @client.get('http://localhost', {:headers => {'X-Hello'=>'hi!'}, :timeout => 1)} -=== Client-Side Load Balancer + # HTTPClient transforms String or Hash :query into query string, for example; + @client.get('http://localhost/moo', {:query=>{:a=>{:b=>:c}}} ) + # the url that would be requested is http://localhost/moo?a[b]=c +==== Client-Side Load Balancer + RequestBalancer randomly chooses endpoints for a network request, which lets you perform easy client-side load balancing: include RightSupport::Net urls = ['http://localhost', 'http://otherhost'] RequestBalancer.request(urls, :fatal=>RestClient::ResourceNotFound) do |url| REST.get(url) end -The balancer will keep trying requests until one of them succeeds without throwing -any exceptions. (NB: a nil return value counts as success!!) +The balancer will keep trying requests until one of them succeeds without +throwing any exceptions. (NB: a nil return value counts as success!!) -=== HTTP Client +==== HTTP Request Tracking for Rack -We provide a very thin wrapper around the rest-client gem that enables simple but -robust rest requests with a timeout, headers, etc. +Correlate data flows across your entire architecture with the RequestTracker +middleware, which uses custom HTTP headers to "tag" every Web request with +a UUID, and works with RequestLogger to log "begin" and "end" lines containing +the UUID. -HTTPClient is interface-compatible with the RestClient module, but allows an -optional timeout to be specified as an extra parameter. - - # Create a wrapper object - @client = RightSupport::Net::HTTPClient.new - - # Default timeout is 5 seconds - @client.get('http://localhost') +If your app consumes the UUID and passes it on to HTTP services that it +invokes, the same request UUID will appear in all logs and you can grep for +the "big picture" instead of wasting time paging between logs. - # Make sure the HTTPClient request fails after 1 second so we can report an error - # and move on! - @client.get('http://localhost', {:headers => {'X-Hello'=>'hi!'}, :timeout => 1)} +To use this functionality you need: + use RightSupport::Rack::RequestTracker + === Statistics Gathering Profile your compute-heavy and network activities using a Stats::Activity counter. stats = RightSupport::Stats::Activity.new @@ -105,29 +121,39 @@ stats.finish end puts "Only %.1f lines/sec? You are a slow typist!" % [stats.avg_rate] -=== Configuration +=== Input Validation -RightSupport::Config contains functionality, which provides possibility -to use human-readable yaml configuration files. For example, you have following yaml -file '/tmp/features_config.yml', with content: +Validation contains several format-checkers that can be used to validate your +web app's models before saving, check for preconditions in your controllers, +and so forth. - eat: - khlav kalash: YES! - speak: - klingonese: false - belarusian: true +You can use it as a mixin by including the appropriate child module of +RightSupport::Validation. -Then, if you would add configuration in you class, like: + class AwesomenessGenerator < ActiveRecord::Base + include RightSupport::Validation::OpenSSL - class SweetestClass - CONFIG = RightSupport::Config.features('/tmp/features_config.yml') + before_save do |record| + errors[:foo] = 'Hey, that's not a key!' unless pem_public_key?(record.foo) + end end -* RightSupport::Config.features receives file` path, io or string. +But you really don't want to do that, do you? Instead, you want to call the module +methods of RightSupport::Validation, which contains all of the same mixin methods, +but does not pollute the dispatch table of your application classes. -Now you can call CONFIG['feature_group']['feature'], like: + the_key = STDIN.read + raise ArgumentError unless RightSupport::Validation.ssh_public_key?(the_key) -* SweetestClass::CONFIG['eat']['khlav kalash'] would return 'YES!' -* SweetestClass::CONFIG['speak']['belarusian'] would return true +=== String Manipulation + +StringExtensions contains String#camelize, which is only defined if the +ActiveSupport gem cannot be loaded. It also has some RightScale-specific +methods: +* String#snake_case +* String#to_const +* String#to_const_path + +Net::StringEncoder applies and removes URL-escape, base64 and other encodings.