From b03797d88a08aa8c05697f41aee181fe7fd4e057 Mon Sep 17 00:00:00 2001 From: Christian Becker Date: Mon, 5 Dec 2016 21:58:24 +0100 Subject: [PATCH] # This is a combination of 7 commits. # This is the 1st commit message: Added core logging functionality (#312) Added core configuration functionality (#340) # This is the commit message #2: Add convenience Methods for logging Messages (#312) # This is the commit message #3: Replace warn with logger (#312) # This is the commit message #4: Add logger messages for shadowed exceptions (#312) # This is the commit message #5: Enhaced Documentation for LogLevel (#312) # This is the commit message #6: Fixed some Logger related issues (#312) # This is the commit message #7: Added local DEFAULTS configuration (#312,#340) --- README.md | 29 +++++++++++ lib/feedjira.rb | 3 ++ lib/feedjira/config.rb | 27 ++++++++++ lib/feedjira/core_ext/time.rb | 3 +- lib/feedjira/date_time_utilities.rb | 8 +-- .../date_time_pattern_parser.rb | 3 +- lib/feedjira/feed.rb | 7 ++- lib/feedjira/feed_entry_utilities.rb | 5 +- lib/feedjira/logger.rb | 51 +++++++++++++++++++ 9 files changed, 127 insertions(+), 9 deletions(-) create mode 100644 lib/feedjira/config.rb create mode 100644 lib/feedjira/logger.rb diff --git a/README.md b/README.md index a203dc1a..47652a8c 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,32 @@ feeds as quickly as possible. Version 1.0 was recently released and with it an [f]: http://feedjira.com There you'll find documentation, examples, announcements and more. + +## Usage + +### Configuration + +Feedjira Configuration Options could be set either by calling them directly via + +```ruby +Feedjira::Config.logger = Logger.new('foo.log') +``` + +or using a block + +```ruby +Feedjira.configure do |config| + config.logger = Logger.new('foo.log') +end +``` + +#### Logger + +Per default Feedjira will log all messages to STDOUT. If you are using Feedjira in your own app you could pass your logger instance to Feedjira to use a single logger for the whole application. +Feedjira will always use 'Feedjira' as ProgName so you can identify specific Feedjira log entries. + +The [level](http://ruby-doc.org/stdlib-2.1.0/libdoc/logger/rdoc/Logger.html) of logger can be set as follows + +```ruby +Feedjira::Config.logger.level = Logger::DEBUG +``` diff --git a/lib/feedjira.rb b/lib/feedjira.rb index 6da266c2..39197f03 100644 --- a/lib/feedjira.rb +++ b/lib/feedjira.rb @@ -3,7 +3,9 @@ require 'faraday_middleware' require 'sax-machine' require 'loofah' +require 'logger' +require 'feedjira/config' require 'feedjira/core_ext' require 'feedjira/date_time_utilities/date_time_pattern_parser' require 'feedjira/date_time_utilities/date_time_language_parser' @@ -12,6 +14,7 @@ require 'feedjira/feed_entry_utilities' require 'feedjira/feed_utilities' require 'feedjira/feed' +require 'feedjira/logger' require 'feedjira/parser' require 'feedjira/parser/rss_entry' require 'feedjira/parser/rss' diff --git a/lib/feedjira/config.rb b/lib/feedjira/config.rb new file mode 100644 index 00000000..71a635c8 --- /dev/null +++ b/lib/feedjira/config.rb @@ -0,0 +1,27 @@ +module Feedjira + # Set configuration options by block + # Feedjira.configure do |config| + # config.logger = my_logger_instance + # end + + def self.configure + yield Config + end + + module Config + DEFAULTS = { + logger_io: STDOUT, + logger_level: Logger::WARN + }.freeze + + class << self + def logger=(logger) + Feedjira.logger = logger + end + + def logger + Feedjira.logger + end + end + end +end diff --git a/lib/feedjira/core_ext/time.rb b/lib/feedjira/core_ext/time.rb index c68d9659..62051dd8 100644 --- a/lib/feedjira/core_ext/time.rb +++ b/lib/feedjira/core_ext/time.rb @@ -18,7 +18,8 @@ def self.parse_safely(dt) elsif dt.respond_to? :to_s parse_string_safely dt.to_s end - rescue StandardError + rescue StandardError => e + Feedjira::Logger.exception(e) { "Failed to parse time #{dt}" } nil end diff --git a/lib/feedjira/date_time_utilities.rb b/lib/feedjira/date_time_utilities.rb index 311a3c81..0845bf5e 100644 --- a/lib/feedjira/date_time_utilities.rb +++ b/lib/feedjira/date_time_utilities.rb @@ -11,14 +11,16 @@ module DateTimeUtilities # Parse the given string starting with the most common parser (default ruby) # and going over all other available parsers def parse_datetime(string) - DATE_PARSERS.find do |parser| + res = DATE_PARSERS.find do |parser| begin return parser.parse(string).feed_utils_to_gm_time - rescue + rescue StandardError => e + Feedjira::Logger.exception(e) { "Failed to parse date #{string}" } nil end end - warn "Failed to parse date #{string.inspect}" + Feedjira::Logger.warn { "Failed to parse date #{string}" } if res.nil? + res end end end diff --git a/lib/feedjira/date_time_utilities/date_time_pattern_parser.rb b/lib/feedjira/date_time_utilities/date_time_pattern_parser.rb index 7de8ad63..3525cc3f 100644 --- a/lib/feedjira/date_time_utilities/date_time_pattern_parser.rb +++ b/lib/feedjira/date_time_utilities/date_time_pattern_parser.rb @@ -12,7 +12,8 @@ def self.parse(string) begin datetime = DateTime.strptime(prepare(string), p) return datetime - rescue + rescue StandardError => e + Feedjira::Logger.exception(e) { "Failed to parse date #{string}" } nil end end diff --git a/lib/feedjira/feed.rb b/lib/feedjira/feed.rb index 0dc21081..3a05245d 100644 --- a/lib/feedjira/feed.rb +++ b/lib/feedjira/feed.rb @@ -86,8 +86,11 @@ def self.connection(url) end def self.parse_last_modified(response) - DateTime.parse(response.headers['last-modified']).to_time - rescue + lm = response.headers['last-modified'] + DateTime.parse(lm).to_time + rescue StandardError => e + Feedjira::Logger.warn { "Failed to parse last modified '#{lm}'" } + Feedjira::Logger.exception(e) nil end private_class_method :parse_last_modified diff --git a/lib/feedjira/feed_entry_utilities.rb b/lib/feedjira/feed_entry_utilities.rb index 38e2aca4..f2159d95 100644 --- a/lib/feedjira/feed_entry_utilities.rb +++ b/lib/feedjira/feed_entry_utilities.rb @@ -9,8 +9,9 @@ def published def parse_datetime(string) DateTime.parse(string).feed_utils_to_gm_time - rescue - warn "Failed to parse date #{string.inspect}" + rescue StandardError => e + Feedjira::Logger.warn { "Failed to parse date #{string.inspect}" } + Feedjira::Logger.exception(e) nil end diff --git a/lib/feedjira/logger.rb b/lib/feedjira/logger.rb new file mode 100644 index 00000000..872cc494 --- /dev/null +++ b/lib/feedjira/logger.rb @@ -0,0 +1,51 @@ +module Feedjira + class << self + attr_writer :logger + + # Provides a global logger instance for Feedjira + # If no logger is set by the user, a logger using STDOUT is provided + def logger + return @logger unless @logger.nil? + @logger = ::Logger.new(Feedjira::Config::DEFAULTS[:logger_io]) + @logger.level = Feedjira::Config::DEFAULTS[:logger_level] + @logger + end + end + + # Provide some convenience methods for logging + # So the Progname mustn't be passed on every call + # @example + # Feedjira::Logger.info { "My Info Message" } + module Logger + class << self + def debug + Feedjira.logger.debug('Feedjira') { yield } + end + + def info + Feedjira.logger.info('Feedjira') { yield } + end + + def warn + Feedjira.logger.warn('Feedjira') { yield } + end + + def error + Feedjira.logger.error('Feedjira') { yield } + end + + def fatal + Feedjira.logger.fatal('Feedjira') { yield } + end + + # Log exceptions with message and backtrace in a common way + # Exceptions will only be logged when severity level 'debug' is set + def exception(e) + Feedjira.logger.debug('Feedjira') do + msg = block_given? ? "#{yield}\n" : '' + msg + "Message: #{e.message}\n#{e.backtrace.join("\n ")}" + end + end + end + end +end