vidazing_logger 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9106df6123f10567ee61da20d022d23c5f43b97a05b2fa9a78291424b6c7b4ad
4
- data.tar.gz: e7aaa6373349e1b2b1ac628a28daf169c314a8e3e452ae12a7b021f119427d86
3
+ metadata.gz: 205ded9bdff5c8cf0b5c2c5b0818b31581e6b151b85ffd9315f34bb23d765236
4
+ data.tar.gz: f5dc4ccfbdd8edd057e08e6c3fad722466c131b2dec341c406e7f74f2292a1d2
5
5
  SHA512:
6
- metadata.gz: 5c22b59b28fe9258a8453564f8c4db707ae4a3a84c2b120f8d994ecac31285306420365428f647adc478e281ef4c262b3c942182df3b5532ddc5172944e493c3
7
- data.tar.gz: 3bfaf20cd8eead8be172c9839b9c202107510e580ab5ff7510485e04bdc38951785240a60a98400ba1590acceb669c8544840d32c6c05935664beef950f4dddd
6
+ metadata.gz: 1e21a3d6630b82047c0ea877a77d9f34a3b05b4a61fe2458935aec1044359ee3d8850fe6b5b127f943e33501bf1f8875e110564dd028581ed14553f4414c1860
7
+ data.tar.gz: 6394c6456b3cedf5f9a3ed0021bf810a8298ac24bf236711b18da822c585821c8697094defdb397b9fb1b8645fd2b138aae0b0f786ccfb394ca529ca973c7807
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore CHANGED
@@ -1,3 +1,7 @@
1
+ # Application
2
+ logs/
3
+
4
+ # General
1
5
  *.gem
2
6
  *.rbc
3
7
  /.config
@@ -36,6 +40,7 @@ build-iPhoneSimulator/
36
40
  /rdoc/
37
41
 
38
42
  ## Environment normalization:
43
+ bundle/
39
44
  /.bundle/
40
45
  /vendor/bundle
41
46
  /lib/bundler/man/
data/.rubocop.yml ADDED
@@ -0,0 +1,9 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5.1
3
+ Exclude:
4
+ - 'bundle/**/*'
5
+
6
+ Metrics/BlockLength:
7
+ Exclude:
8
+ - '**/*.rake'
9
+ - 'test/**/*.rb'
data/.simplecov ADDED
@@ -0,0 +1,3 @@
1
+ SimpleCov.start do
2
+ add_filter 'bundle/'
3
+ end
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.5.1
5
+ before_install:
6
+ - gem install bundler -v 1.16.4
7
+
8
+ script:
9
+ - bundle exec rake build
10
+ - bundle exec rake doc:build
11
+ - bundle exec rake test
12
+
13
+ after_script:
14
+ - bundle exec rake coveralls:push
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
 
3
5
  gemspec
data/README.md CHANGED
@@ -1,10 +1,15 @@
1
- # logger-gem
1
+ # logger-gem [![Gem Version](https://badge.fury.io/rb/vidazing_logger.svg)](https://badge.fury.io/rb/vidazing_logger)
2
+
3
+ [![Build Status](https://travis-ci.org/VidaZing/logger_gem.svg?branch=master)](https://travis-ci.org/VidaZing/logger_gem)
4
+ [![Inline docs](http://inch-ci.org/github/VidaZing/logger_gem.svg?branch=master)](http://inch-ci.org/github/VidaZing/logger_gem)
5
+ [![Coverage Status](https://coveralls.io/repos/github/VidaZing/logger_gem/badge.svg?branch=master)](https://coveralls.io/github/VidaZing/logger_gem?branch=master)
6
+
2
7
  VidaZing logging strategy using [TwP/logging](https://github.com/TwP/logging).
3
8
 
4
9
  Writes to rolling log files and the corresponding IO pipe.
5
10
 
6
- * <span style="color:red">Red</span> timestamps: `logs/error.log` + stderr.
7
- * <span style="color:blue">Blue</span> timestamps: `logs/build.log` + stdout.
11
+ * <img src="http://medyk.org/colors/ff8787.png" style="border: 1px solid black" width="20" height="20" /> timestamps for: `logs/error.log` + stderr.
12
+ * <img src="http://medyk.org/colors/87d7ff.png" style="border: 1px solid black" width="20" height="20" /> timestamps for: `logs/build.log` + stdout.
8
13
 
9
14
  1. [**Installation**](#installation)
10
15
  2. [**Usage**](#usage)
@@ -14,7 +19,7 @@ Writes to rolling log files and the corresponding IO pipe.
14
19
  1. In your `Gemfile`, add the `vidazing_logger` gem:
15
20
 
16
21
  ```ruby
17
- gem 'vidazing_logger', '~> 0.1'
22
+ gem 'vidazing_logger', '~> 0.2'
18
23
  ```
19
24
 
20
25
  2. In your `shell`, run:
@@ -39,7 +44,20 @@ See `rake -T`
39
44
  ```ruby
40
45
  require 'vidazing_logger'
41
46
 
42
- logger = VidazingLogger.logger("OPTIONAL_LOGGER_NAME")
47
+ # Easy
48
+ optional_name = "DearDiary"
49
+ optional_log_dir = 'logs'
50
+ logger = VidazingLogger.logger(optional_name, optional_log_dir)
51
+
52
+ # Customized. See VidazingLogger::Logger#build
53
+ LoggerBuilder.build(name: @name) do |builder|
54
+ builder
55
+ .add_stdout
56
+ .add_build_log(log_dir: @log_dir)
57
+ .add_stderr
58
+ .add_error_log(log_dir: @log_dir)
59
+ end
60
+
43
61
  ```
44
62
 
45
63
  ### Binary
data/Rakefile CHANGED
@@ -1,63 +1,82 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rainbow/refinement'
2
4
  using Rainbow
3
5
  require 'rake/testtask'
6
+ require 'coveralls/rake/task'
4
7
 
5
- $LOAD_PATH.push File.expand_path("../lib", __FILE__)
6
- require "vidazing_logger/version"
8
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
9
+ require 'vidazing_logger/version'
7
10
  VERSION = VidazingLogger::VERSION
8
11
 
9
- GEM_NAME = "vidazing_logger"
12
+ GEM_NAME = 'vidazing_logger'
10
13
 
11
14
  # IMPORTANT: Color can't be used for `system` commands.
12
15
  GEM_NAME_VERSION = "#{GEM_NAME}-#{VERSION}"
13
16
  GEM_ARTIFACT = "#{GEM_NAME_VERSION}.gem"
14
17
 
15
- desc "Remove #{GEM_ARTIFACT} && Gemfile.lock"
18
+ desc "Remove #{GEM_ARTIFACT} && Gemfile.lock".blue
16
19
  task :clean do
17
20
  puts "Removing #{GEM_ARTIFACT} && Gemfile.lock".blue
18
- system "rm -f *.gem Gemfile.lock"
21
+ system 'rm -f *.gem Gemfile.lock'
19
22
  end
20
23
 
21
- desc "Build #{GEM_NAME_VERSION}"
22
- task :build => :clean do
24
+ desc "Build #{GEM_NAME_VERSION}".blue
25
+ task build: :clean do
23
26
  puts "Building #{GEM_NAME_VERSION}".blue
24
27
  system "gem build #{GEM_NAME}.gemspec"
25
28
  end
26
29
 
27
- desc "Publish #{GEM_ARTIFACT}"
30
+ task default: ['build']
31
+
32
+ desc "Publish #{GEM_ARTIFACT}".blue
28
33
  task :publish do
29
34
  puts "Publishing #{GEM_NAME_VERSION}".blue
30
35
  system "gem push #{GEM_NAME_VERSION}.gem"
31
36
  end
32
37
 
33
- desc "Installs #{GEM_ARTIFACT}"
34
- task :install => :build do
38
+ desc "Installs #{GEM_ARTIFACT}".blue
39
+ task install: :build do
35
40
  puts "Installing #{GEM_ARTIFACT}".blue
36
41
  system "gem install #{GEM_NAME}"
37
42
  end
38
43
 
39
- desc "Uninstalls #{GEM_ARTIFACT}"
44
+ desc "Uninstalls #{GEM_ARTIFACT}".blue
40
45
  task :uninstall do
41
46
  puts "UNINSTALLING #{GEM_ARTIFACT}".inverse.blue
42
47
  system "gem uninstall -xq #{GEM_NAME}"
43
48
  end
44
49
 
50
+ namespace :dev do
51
+ desc 'Analyze code quality (rubocop, flog, flay)'
52
+ task :quality do
53
+ puts 'Analyzing format with rubocop'.blue
54
+ system 'bundle exec rubocop'
55
+
56
+ puts 'Checking code quality. Lower is better'.blue
57
+ system 'bundle exec flog lib/'
58
+
59
+ puts 'Checking code duplication. Prime to refactor'.blue
60
+ system 'bundle exec flay lib/'
61
+ end
62
+ end
63
+
45
64
  namespace :doc do
46
65
  desc "Build documentation into 'doc/'"
47
66
  task :build do
48
67
  puts "Building documentation into 'doc/':".blue
49
- system "yard"
68
+ system 'yard'
50
69
  end
51
70
 
52
- desc "Find undocumented code"
71
+ desc 'Find undocumented code'
53
72
  task :coverage do
54
- puts "Documentation coverage:".blue
55
- system "yard stats --list-undoc"
73
+ puts 'Documentation coverage:'.blue
74
+ system 'yard stats --list-undoc'
56
75
  end
57
76
 
58
- desc "See local documentation at http://localhost:8808"
77
+ desc 'See local documentation at http://localhost:8808'
59
78
  task :serve do
60
- system "yard server --reload"
79
+ system 'yard server --reload'
61
80
  end
62
81
  end
63
82
 
@@ -67,44 +86,59 @@ Rake::TestTask.new do |t|
67
86
  t.verbose = true
68
87
  end
69
88
 
70
- namespace :loop do
89
+ namespace :loop do # rubocop:disable Metrics/BlockLength
71
90
  def looper?
72
91
  puts "Checking for 'fswatch' to monitor files".blue
73
92
 
74
- has_fswatch = ! `which fswatch`.empty?
93
+ has_fswatch = !`which fswatch`.empty?
94
+
95
+ unless has_fswatch
96
+ abort('fswatch is NOT installed. Visit https://github.com/emcrisostomo/fswatch'.bright.red)
97
+ end
75
98
 
76
- abort('fswatch is NOT installed. Visit https://github.com/emcrisostomo/fswatch'.bright.red) unless has_fswatch
77
99
  puts('fswatch is installed.'.bright.green) if has_fswatch
78
100
  end
79
101
 
80
102
  def looping(cmd)
81
- fswatch_cmd = "fswatch -0 -e .git/ -e *.gem -e logs -e .yardoc -l 1 ."
103
+ exclude = '-e Gemfile.lock -e .git/ -e *.gem -e logs -e .yardoc -e bundle/'
104
+ fswatch_cmd = "fswatch -0 #{exclude} -l 1 ."
105
+
82
106
  xargs_cmd = "xargs -0 -I {} sh -c \"echo 'File: {}' && %s\""
107
+
83
108
  looping_cmd = "#{fswatch_cmd} | #{xargs_cmd}"
109
+ system format(looping_cmd.to_s, cmd)
110
+ end
111
+
112
+ IGNORED_MESSAGE = 'Ignores .git/, Gemfile.lock, logs/, .yardoc/, bundle/, '\
113
+ 'and gems created. Watches every 1 seconds'
84
114
 
85
- system "#{looping_cmd}" % cmd
115
+ desc 'Repeatedly see dev:quality on file changes'
116
+ task :"dev:quality" do
117
+ looper?
118
+ puts "Analyzing dev:quality on file changes. #{IGNORED_MESSAGE}".blue
119
+ looping('rake dev:quality')
86
120
  end
87
121
 
88
- IGNORED_MESSAGE = "Ignores .git/, logs/, .yardoc/, and gems created. Watches every 1 seconds"
122
+ desc 'Repeatedly show documentation coverage on file changes'
123
+ task :"doc:coverage" do
124
+ looper?
125
+ puts "Showing undocumented code on file changes. #{IGNORED_MESSAGE}".blue
126
+ looping('rake doc:coverage')
127
+ end
89
128
 
90
- desc "Repeatedly installs the gem on file changes"
129
+ desc 'Repeatedly installs the gem on file changes'
91
130
  task :install do
92
131
  looper?
93
132
  puts "Rebuilding on file changes. #{IGNORED_MESSAGE}".blue
94
- looping("rake uninstall install")
133
+ looping('rake uninstall install')
95
134
  end
96
135
 
97
- desc "Repeatedly runs tests on file changes"
136
+ desc 'Repeatedly runs tests on file changes'
98
137
  task :test do
99
138
  looper?
100
139
  puts "Running tests on file changes. #{IGNORED_MESSAGE}".blue
101
- looping("rake test")
102
- end
103
-
104
- desc "Repeatedly show documentation coverage on file changes"
105
- task :"doc:coverage" do
106
- looper?
107
- puts "Showing undocumented code on file changes. #{IGNORED_MESSAGE}".blue
108
- looping("rake doc:coverage")
140
+ looping('rake test')
109
141
  end
110
142
  end
143
+
144
+ Coveralls::RakeTask.new
data/bin/vidazing_logger CHANGED
@@ -1,44 +1,57 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'vidazing_logger'
4
5
 
5
6
  require 'optparse'
6
7
  require 'ostruct'
7
8
 
9
+ # Handles command line options for the vidazing_logger binary.
10
+ # See `vidazing_logger --help`
11
+ #
12
+ # @since 0.1.0
8
13
  class VidazingOptions
9
- LEVEL_ALIASES = { 'd' => 'debug', 'i' => 'info', 'w' => 'warn', 'e' => 'error', 'f' => 'fatal' }
14
+ attr_reader :level, :clean
10
15
 
11
- def self.parse(args)
12
- options = OpenStruct.new
13
- options.level = 'info'
14
- options.clean = false
16
+ def initialize
17
+ @level = 'info'
18
+ @clean = false
19
+ @options_parser = create_options_parser
20
+ end
21
+
22
+ def create_options_parser # rubocop:disable Metrics/MethodLength
23
+ OptionParser.new do |opts|
24
+ opts.banner = 'Usage: vidazing_logger [options] "Message"'
15
25
 
16
- options_parser = OptionParser.new do |opts|
17
- opts.banner = "Usage: vidazing_logger [options] \"Message\""
26
+ opts.separator ''
27
+ opts.separator 'Specific options:'
18
28
 
19
- opts.separator ""
20
- opts.separator "Specific options:"
29
+ level_aliases = { 'd' => 'debug', 'i' => 'info', 'w' => 'warn',
30
+ 'e' => 'error', 'f' => 'fatal' }.freeze
31
+ level_list = level_aliases.flatten.join(',')
21
32
 
22
- level_list = LEVEL_ALIASES.flatten.join(',')
23
- opts.on("-l", "--level LEVEL", LEVEL_ALIASES.values, LEVEL_ALIASES, "Select log level",
24
- " (#{level_list})") do |level|
25
- options.level = level
33
+ opts.on('-l', '--level LEVEL', level_aliases.values, level_aliases,
34
+ 'Select log level', " (#{level_list})") do |level|
35
+
36
+ @level = level
26
37
  end
27
38
 
28
- opts.on_tail("-c", "--clean", "Remove the logs/ directory") do
29
- options.clean = true
39
+ opts.on_tail('-c', '--clean', 'Remove the logs/ directory') do
40
+ @clean = true
30
41
  end
31
42
  end
43
+ end
32
44
 
33
- options_parser.parse!(args)
34
- options
45
+ def parse(args)
46
+ @options_parser.parse!(args)
35
47
  end
36
48
  end
37
49
 
38
- options = VidazingOptions.parse(ARGV)
50
+ vidazing_options = VidazingOptions.new
51
+ vidazing_options.parse(ARGV)
39
52
 
40
- if options.clean
41
- puts "Cleaning the logs/ directory"
53
+ if vidazing_options.clean
54
+ puts 'Cleaning the logs/ directory'
42
55
  VidazingLogger.clean
43
56
  end
44
57
 
@@ -46,5 +59,5 @@ unless ARGV.empty?
46
59
  message = ARGV.join(' ')
47
60
 
48
61
  log = VidazingLogger.logger
49
- log.public_send(options.level, message)
62
+ log.public_send(vidazing_options.level, message)
50
63
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logging'
4
+
5
+ module VidazingLogger
6
+ # An +Appender+ appenders log events to a logging destination.
7
+ # All appenders use the same layout. So we store the +color_scheme+
8
+ # instead.
9
+ #
10
+ # @api private
11
+ # @since 0.2.0
12
+ class Appender
13
+ attr_reader :filter_levels, :name, :color_scheme
14
+
15
+ def initialize(name:, filter_levels:, color_scheme:)
16
+ @filter_levels = filter_levels
17
+ @color_scheme = color_scheme
18
+ @name = name
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vidazing_logger/appenders/log'
4
+ require 'vidazing_logger/color_scheme'
5
+ require 'vidazing_logger/filters/levels'
6
+
7
+ module VidazingLogger
8
+ module Appenders
9
+ # Appender writing to 'logs/build.log'
10
+ #
11
+ # @api private
12
+ # @since 0.2.0
13
+ class BuildLog < Log
14
+ def initialize(log_dir:)
15
+ super \
16
+ name: 'build',
17
+ log_dir: log_dir,
18
+ color_scheme: ColorScheme.normal,
19
+ filter_levels: Filters::Levels.normal
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vidazing_logger/appenders/log'
4
+ require 'vidazing_logger/color_scheme'
5
+ require 'vidazing_logger/filters/levels'
6
+
7
+ module VidazingLogger
8
+ module Appenders
9
+ # Appender writing to 'logs/error.log'
10
+ #
11
+ # @api private
12
+ # @since 0.2.0
13
+ class ErrorLog < Log
14
+ def initialize(log_dir:)
15
+ super \
16
+ name: 'error',
17
+ log_dir: log_dir,
18
+ color_scheme: ColorScheme.error,
19
+ filter_levels: Filters::Levels.error
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vidazing_logger/appender'
4
+
5
+ module VidazingLogger
6
+ module Appenders
7
+ # Appender writing to log files
8
+ #
9
+ # @api private
10
+ # @since 0.2.0
11
+ class Log < Appender
12
+ attr_reader :log_dir, :name
13
+
14
+ def log_path
15
+ "#{@log_dir}/#{@name}"
16
+ end
17
+
18
+ def initialize(log_dir:, name:, color_scheme:, filter_levels:)
19
+ @log_dir = log_dir
20
+ @name = "#{name}.log"
21
+
22
+ super \
23
+ name: log_path,
24
+ color_scheme: color_scheme,
25
+ filter_levels: filter_levels
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vidazing_logger/layout_pattern'
4
+
5
+ require 'logging'
6
+
7
+ module VidazingLogger
8
+ module Appenders
9
+ # Uses an +appender+
10
+ #
11
+ # @api private
12
+ # @since 0.2.0
13
+ class LoggingGemAdapter
14
+ attr_reader :vidazing_appender, :logging_appender
15
+
16
+ def initialize(type:, vidazing_appender:)
17
+ @vidazing_appender = vidazing_appender
18
+
19
+ logging_filter = create_logging_filter
20
+ logging_layout = create_logging_layout
21
+
22
+ logging_appender_options = create_logging_appender_options \
23
+ filter: logging_filter,
24
+ layout: logging_layout
25
+
26
+ @logging_appender = create_logging_appender \
27
+ type: type,
28
+ name: vidazing_appender.name,
29
+ options: logging_appender_options
30
+ end
31
+
32
+ private
33
+
34
+ def create_logging_appender_options(filter:, layout:)
35
+ [
36
+ filters: filter,
37
+ layout: layout,
38
+ # These are specific to Appenders::Type.rolling_file
39
+ # But the underlying logging library uses opts.fetch
40
+ # So these will be ignored for other appenders types
41
+ age: 'daily',
42
+ keep: 7
43
+ ]
44
+ end
45
+
46
+ def create_logging_appender(type:, name:, options:)
47
+ abort('options are empty!') if options.empty?
48
+ abort("Invalid Type '#{type}'") unless Type.valid_type?(type: type)
49
+
50
+ options.unshift(name)
51
+
52
+ Logging.appenders.public_send(type, *options)
53
+ Logging.appenders[name]
54
+ end
55
+
56
+ def create_logging_filter # rubocop:disable Metrics/MethodLength
57
+ # Logging::Filters::Level takes *levels as its argument.
58
+ # This means we can't store the method arguments ahead of time
59
+ # in an array and directly pass those.
60
+ #
61
+ # Instead, to isolate the Logging gem reference, we hack
62
+ level0, level1, level2, level3, level4 =
63
+ *@vidazing_appender.filter_levels
64
+
65
+ if level1.nil?
66
+ Logging::Filters::Level.new(level0)
67
+ elsif level2.nil?
68
+ Logging::Filters::Level.new(level0, level1)
69
+ elsif level3.nil?
70
+ Logging::Filters::Level.new(level0, level1, level2)
71
+ elsif level4.nil?
72
+ Logging::Filters::Level.new(level0, level1, level2, level3)
73
+ else
74
+ Logging::Filters::Level.new(:all)
75
+ end
76
+ end
77
+
78
+ def create_logging_color_scheme
79
+ color_scheme = @vidazing_appender.color_scheme
80
+ name = color_scheme.name
81
+
82
+ # Logging holds the color scheme reference
83
+ Logging.color_scheme(name, color_scheme.scheme)
84
+
85
+ name
86
+ end
87
+
88
+ def create_logging_layout
89
+ color_scheme_name = create_logging_color_scheme
90
+ layout = LayoutPattern.colored(color_scheme_name).layout
91
+
92
+ Logging.layouts.pattern layout
93
+ end
94
+
95
+ class << self
96
+ def stdout(vidazing_appender:)
97
+ LoggingGemAdapter.new(type: Type::ID_STDOUT,
98
+ vidazing_appender: vidazing_appender)
99
+ end
100
+
101
+ def stderr(vidazing_appender:)
102
+ LoggingGemAdapter.new(type: Type::ID_STDERR,
103
+ vidazing_appender: vidazing_appender)
104
+ end
105
+
106
+ def rolling_file(vidazing_appender:)
107
+ LoggingGemAdapter.new(type: Type::ID_ROLLING_FILE,
108
+ vidazing_appender: vidazing_appender)
109
+ end
110
+ end
111
+ end
112
+
113
+ # Determines what kind of logging will occur
114
+ #
115
+ # @see Type::ID_ROLLING_FILE, Type::ID_STDOUT, Type::ID_STDERR
116
+ # @api private
117
+ module Type
118
+ ID_ROLLING_FILE = 'rolling_file'
119
+ ID_STDOUT = 'stdout'
120
+ ID_STDERR = 'stderr'
121
+
122
+ TYPES = [ID_ROLLING_FILE, ID_STDERR, ID_STDOUT].freeze
123
+
124
+ class << self
125
+ def valid_type?(type:)
126
+ is_valid = false
127
+
128
+ begin
129
+ is_valid = Logging.appenders.respond_to?(type)
130
+ rescue StandardError
131
+ abort("Logging.appenders.#{type} is not a public_method." \
132
+ 'See https://github.com/TwP/logging/')
133
+ end
134
+
135
+ is_valid && TYPES.include?(type)
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end