logging-email 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1bec69b79f5915cefb82f3e508cab7ad91a39db5
4
+ data.tar.gz: ab809782f91dfd82dcba5db696d82995f66f0c02
5
+ SHA512:
6
+ metadata.gz: a38bb7864a2b3b7f1cb9a0270a31b141099d13a59d3df015b904611a3a4475141a1226f5d0a3f463558fa85b47554019290ccc98ce24535893db30528037042d
7
+ data.tar.gz: 1d23540f311dc715ab8b3952bc67b37698cf6a50bf38610e1b24ba45c76045efd0b21d45d79e91fbc922403b61cca5f3d7bda5f3199f14927bcfbb23a484442f
@@ -0,0 +1,14 @@
1
+ # git-ls-files --others --exclude-from=.git/info/exclude
2
+ # Lines that start with '#' are comments.
3
+ # For a project mostly in C, the following would be a good set of
4
+ # exclude patterns (uncomment them if you want to use them):
5
+ # *.[oa]
6
+ # *~
7
+ announcement.txt
8
+ coverage/
9
+ doc/
10
+ pkg/
11
+ tmp/
12
+ vendor/
13
+ .rbx
14
+ .rvmrc
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+
3
+ before_install: "gem install bones"
4
+ install: "rake gem:install_dependencies"
5
+
6
+ script: "rake"
7
+
8
+ rvm:
9
+ - 1.9.3
10
+ - 2.0.0
11
+ - 2.1.5
12
+ - 2.2.1
13
+
@@ -0,0 +1,114 @@
1
+ ## Logging Email Appender
2
+ by Tim Pease [![](https://secure.travis-ci.org/TwP/logging-email.png)](https://travis-ci.org/TwP/logging-email)
3
+
4
+ * [Homepage](http://rubygems.org/gems/logging-email)
5
+ * [Github Project](https://github.com/TwP/logging-email)
6
+
7
+ ### Description
8
+
9
+ The Logging email appender provides a way to send log messages via email from
10
+ a Ruby application. This is useful if you wish to be notified of exceptions or
11
+ fatal errors as they arise.
12
+
13
+ The email appender was originally part of the Logging framework proper, but with
14
+ the release of Logging 2.0.0, it has been extracted into its own gem.
15
+
16
+ ### Installation
17
+
18
+ The Logging framework uses the [little-plugger](https://github.com/twp/little-plugger)
19
+ gem based plugin system. All that needs to be done to start using the email
20
+ appender is to install the gem.
21
+
22
+ ```
23
+ gem install logging-email
24
+ ```
25
+
26
+ The plugin system will automatically detect and load the plugin when the Logging
27
+ framework is first initialized.
28
+
29
+ ### Examples
30
+
31
+ The example below configures an email appender and gives it the name "gmail".
32
+ This name will be used later to add the appender to our logger.
33
+
34
+ The appender itself is configured to send email via the Google's Gmail servers.
35
+ This requires a user name and password; we load these from environment
36
+ variables. The Gmail SMTP servers also require `STARTTLS` to be enabled so that
37
+ TLS or SSL encryption can be used for communication.
38
+
39
+ The email appender is configured to buffer log messages. The log messages will
40
+ be sent in a single email when either 20 log messages have been buffered or one
41
+ minute has passed since the first log message was buffered. This helps reduce
42
+ the overall volume of email. The caveat here is that if there is a fatal error
43
+ and the application crashes, these log message **will not** be sent out via
44
+ email; they will be lost.
45
+
46
+ ```ruby
47
+ require 'logging'
48
+ Logging.init # initialize the framework and load plugins
49
+
50
+ Logger.appenders.email 'gmail',
51
+ :from => "server@example.com",
52
+ :to => "developers@example.com",
53
+ :subject => "Application Error [#{%x(uname -n).strip}]",
54
+ :address => "smtp.gmail.com",
55
+ :port => 443,
56
+ :domain => "gmail.com",
57
+ :user_name => ENV["GMAIL_USER"],
58
+ :password => ENV["GMAIL_PASS"],
59
+ :authentication => :plain,
60
+ :enable_starttls_auto => true,
61
+ :auto_flushing => 20, # send an email after 20 messages have been buffered
62
+ :flush_period => 60, # send an email after one minute
63
+ :level => :error # only process log events that are "error" or "fatal"
64
+
65
+ logger = Logging.logger['example_logger']
66
+ logger.level = :info
67
+
68
+ logger.add_appenders \
69
+ Logging.appenders['gmail'], # lookup the gmail email appender
70
+ Logging.appenders.file('example.log')
71
+
72
+ logger.debug "this debug message will not be output by the logger"
73
+ logger.info "just some friendly advice"
74
+ logger.error exception # this `exception` will be emailed
75
+ ```
76
+
77
+ ### Development
78
+
79
+ The `logging-email` source code relies on the Mr Bones project for default rake
80
+ tasks. You will need to install the Mr Bones gem if you want to build or test
81
+ the `logging-email` gem. Conveniently there is a bootstrap script that you can
82
+ run to setup your development environment.
83
+
84
+ ```
85
+ script/bootstrap
86
+ ```
87
+
88
+ This will install the Mr Bones gem and the required Ruby gems for development.
89
+ After this is done you can rake `rake -T` to see the available rake tasks.
90
+
91
+ ### License
92
+
93
+ The MIT License
94
+
95
+ Copyright (c) 2015 Tim Pease
96
+
97
+ Permission is hereby granted, free of charge, to any person obtaining
98
+ a copy of this software and associated documentation files (the
99
+ 'Software'), to deal in the Software without restriction, including
100
+ without limitation the rights to use, copy, modify, merge, publish,
101
+ distribute, sublicense, and/or sell copies of the Software, and to
102
+ permit persons to whom the Software is furnished to do so, subject to
103
+ the following conditions:
104
+
105
+ The above copyright notice and this permission notice shall be
106
+ included in all copies or substantial portions of the Software.
107
+
108
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
109
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
110
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
111
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
112
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
113
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
114
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ begin
2
+ require 'bones'
3
+ rescue LoadError
4
+ abort '### please install the "bones" gem ###'
5
+ end
6
+
7
+ lib = File.expand_path('../lib', __FILE__)
8
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
9
+
10
+ require 'logging/plugins/email'
11
+
12
+ task :default => 'test:run'
13
+ task 'gem:release' => 'test:run'
14
+
15
+ Bones {
16
+ name 'logging-email'
17
+ summary 'An email appender for the Ruby Logging framework'
18
+ authors 'Tim Pease'
19
+ email 'tim.pease@gmail.com'
20
+ url 'http://rubygems.org/gems/logging-email'
21
+ version Logging::Plugins::Email::VERSION
22
+
23
+ use_gmail
24
+
25
+ depend_on 'logging', '~> 2.0'
26
+
27
+ depend_on 'flexmock', '~> 1.0', :development => true
28
+ depend_on 'bones-git', '~> 1.3', :development => true
29
+ }
@@ -0,0 +1,176 @@
1
+ require 'net/smtp'
2
+ require 'time' # get rfc822 time format
3
+
4
+ module Logging
5
+ module Appenders
6
+
7
+ # Accessor / Factory for the Email appender.
8
+ def self.email( *args )
9
+ return ::Logging::Appenders::Email if args.empty?
10
+ ::Logging::Appenders::Email.new(*args)
11
+ end
12
+
13
+ # Provides an appender that can send log messages via email to a list of
14
+ # recipients.
15
+ #
16
+ class Email < ::Logging::Appender
17
+ include Buffering
18
+
19
+ attr_reader :authentication, :to, :port
20
+ attr_accessor :address, :domain, :from, :subject
21
+ attr_accessor :user_name, :password, :enable_starttls_auto
22
+
23
+ # call-seq:
24
+ # Email.new( name, :from => 'me@example.com', :to => 'you@example.com', :subject => 'Whoops!' )
25
+ #
26
+ # Create a new email appender that will buffer messages and then send them
27
+ # out in batches to the listed recipients. See the options below to
28
+ # configure how emails are sent through you mail server of choice. All the
29
+ # buffering options apply to the email appender.
30
+ #
31
+ # The following options are required:
32
+ #
33
+ # :from - The base filename to use when constructing new log
34
+ # filenames.
35
+ # :to - The list of email recipients either as an Array or a comma
36
+ # separated list.
37
+ #
38
+ # The following options are optional:
39
+ #
40
+ # :subject - The subject line for the email.
41
+ # :address - Allows you to use a remote mail server. Just change it
42
+ # from its default "localhost" setting.
43
+ # :port - On the off chance that your mail server doesn't run on
44
+ # port 25, you can change it.
45
+ # :domain - If you need to specify a HELO domain, you can do it here.
46
+ # :user_name - If your mail server requires authentication, set the user
47
+ # name in this setting.
48
+ # :password - If your mail server requires authentication, set the
49
+ # password in this setting.
50
+ # :authentication - If your mail server requires authentication, you need
51
+ # to specify the authentication type here. This is a
52
+ # symbol and one of :plain (will send the password in
53
+ # the clear), :login (will send password Base64
54
+ # encoded) or :cram_md5 (combines a Challenge/Response
55
+ # mechanism to exchange information and a cryptographic
56
+ # Message Digest 5 algorithm to hash important
57
+ # information)
58
+ # :enable_starttls_auto - When set to true, detects if STARTTLS is
59
+ # enabled in your SMTP server and starts to use it.
60
+ #
61
+ # Example:
62
+ #
63
+ # Setup an email appender that will buffer messages for up to 1 minute,
64
+ # and only send messages for ERROR and FATAL messages. This example uses
65
+ # Google's Gmail SMTP server with authentication to send out messages.
66
+ #
67
+ # Logger.appenders.email( 'gmail',
68
+ # :from => "server@example.com",
69
+ # :to => "developers@example.com",
70
+ # :subject => "Application Error [#{%x(uname -n).strip}]",
71
+ #
72
+ # :address => "smtp.gmail.com",
73
+ # :port => 443,
74
+ # :domain => "gmail.com",
75
+ # :user_name => ENV["GMAIL_USER"],
76
+ # :password => ENV["GMAIL_PASS"],
77
+ # :authentication => :plain,
78
+ # :enable_starttls_auto => true,
79
+ #
80
+ # :auto_flushing => 200, # send an email after 200 messages have been buffered
81
+ # :flush_period => 60, # send an email after one minute
82
+ # :level => :error # only process log events that are "error" or "fatal"
83
+ # )
84
+ #
85
+ def initialize( name, opts = {} )
86
+ opts[:header] = false
87
+ super(name, opts)
88
+
89
+ af = opts.fetch(:buffsize, opts.fetch(:buffer_size, 100))
90
+
91
+ configure_buffering({:auto_flushing => af}.merge(opts))
92
+
93
+ # get the SMTP parameters
94
+ self.from = opts.fetch(:from, nil)
95
+ raise ArgumentError, 'Must specify from address' if @from.nil?
96
+
97
+ self.to = opts.fetch(:to, nil)
98
+ raise ArgumentError, 'Must specify recipients' if @to.empty?
99
+
100
+ self.subject = opts.fetch(:subject, "Message from #{$0}")
101
+ self.address = opts.fetch(:server, opts.fetch(:address, 'localhost'))
102
+ self.port = opts.fetch(:port, 25)
103
+ self.domain = opts.fetch(:domain, (ENV['HOSTNAME'] || 'localhost.localdomain'))
104
+ self.user_name = opts.fetch(:acct, opts.fetch(:user_name, nil))
105
+ self.password = opts.fetch(:passwd, opts.fetch(:password, nil))
106
+ self.enable_starttls_auto = opts.fetch(:enable_starttls_auto, false)
107
+ self.authentication = opts.fetch(:authtype, opts.fetch(:authentication, :plain))
108
+ end
109
+
110
+ # Close the email appender. If the layout contains a foot, it will not be
111
+ # sent as an email.
112
+ #
113
+ def close( *args )
114
+ super(false)
115
+ end
116
+
117
+ # If your mail server requires authentication, you need to specify the
118
+ # authentication type here. This is a symbol and one of :plain (will send
119
+ # the password in the clear), :login (will send password Base64 encoded)
120
+ # or :cram_md5 (combines a Challenge/Response mechanism to exchange
121
+ # information and a cryptographic Message Digest 5 algorithm to hash
122
+ # important information)
123
+ #
124
+ def authentication=( val )
125
+ @authentication = val.to_s.to_sym
126
+ end
127
+
128
+ # On the off chance that your mail server doesn't run on port 25, you can
129
+ # change it.
130
+ #
131
+ def port=( val )
132
+ @port = Integer(val)
133
+ end
134
+
135
+ # The list of email recipients. This can either be an Array of recipients
136
+ # or a comma separated list. A single recipient is also valid.
137
+ #
138
+ # email.to = ['mike@example.com', 'tony@example.com']
139
+ # email.to = 'alicia@example.com'
140
+ # email.to = 'bob@example.com, andy@example.com, john@example.com'
141
+ #
142
+ def to=( val )
143
+ @to = val.respond_to?(:split) ? val.split(',') : Array(val)
144
+ end
145
+
146
+
147
+ private
148
+
149
+ # This method is called by the buffering code when messages need to be
150
+ # sent out as an email.
151
+ #
152
+ def canonical_write( str )
153
+ ### build a mail header for RFC 822
154
+ rfc822msg = "From: #{@from}\n"
155
+ rfc822msg << "To: #{@to.join(",")}\n"
156
+ rfc822msg << "Subject: #{@subject}\n"
157
+ rfc822msg << "Date: #{Time.new.rfc822}\n"
158
+ rfc822msg << "Message-Id: <#{"%.8f" % Time.now.to_f}@#{@domain}>\n\n"
159
+
160
+ rfc822msg = rfc822msg.force_encoding(encoding) if encoding and rfc822msg.encoding != encoding
161
+ rfc822msg << str
162
+
163
+ ### send email
164
+ smtp = Net::SMTP.new(@address, @port)
165
+ smtp.enable_starttls_auto if @enable_starttls_auto and smtp.respond_to? :enable_starttls_auto
166
+ smtp.start(@domain, @user_name, @password, @authentication) { |s| s.sendmail(rfc822msg, @from, @to) }
167
+ self
168
+ rescue StandardError, TimeoutError => err
169
+ self.level = :off
170
+ ::Logging.log_internal {'e-mail notifications have been disabled'}
171
+ ::Logging.log_internal_error(err)
172
+ end
173
+
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,15 @@
1
+ module Logging
2
+ module Plugins
3
+ module Email
4
+ extend self
5
+
6
+ VERSION = '0.0.1'.freeze
7
+
8
+ # This method will be called by the Logging framework when it first
9
+ # initializes. Here we require the email appender code.
10
+ def initialize_email
11
+ require File.expand_path('../../appenders/email', __FILE__)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env sh
2
+
3
+ gem list -i bones >/dev/null 2>&1
4
+ rc=$?
5
+ if [[ $rc != 0 ]]; then
6
+ gem install bones
7
+ fi
8
+
9
+ gem list -i rdoc >/dev/null 2>&1
10
+ rc=$?
11
+ if [[ $rc != 0 ]]; then
12
+ gem install rdoc
13
+ fi
14
+
15
+ rake gem:install_dependencies
@@ -0,0 +1,170 @@
1
+ require 'flexmock'
2
+ require 'logging'
3
+ require Logging.path(%w[test setup])
4
+
5
+ # initialize the Logging framework plugins
6
+ Logging.initialize_plugins
7
+
8
+ module TestLogging
9
+ module TestAppenders
10
+
11
+ class TestEmail < Test::Unit::TestCase
12
+ include FlexMock::TestCase
13
+ include LoggingTestCase
14
+
15
+ def setup
16
+ super
17
+
18
+ flexmock(Net::SMTP).new_instances do |m|
19
+ m.should_receive(:start).at_least.once.with(
20
+ 'test.logging', 'test', 'test', :plain, Proc).and_yield(m)
21
+ m.should_receive(:sendmail).at_least.once.with(String, 'me', ['you'])
22
+ end
23
+
24
+ @appender = Logging.appenders.email('email',
25
+ :from => 'me', :to => 'you',
26
+ :buffer_size => '3', :immediate_at => 'error, fatal',
27
+ :domain => 'test.logging', :user_name => 'test', :password => 'test'
28
+ )
29
+ @levels = Logging::LEVELS
30
+ end
31
+
32
+ def test_initialize
33
+ assert_raise(ArgumentError, 'Must specify from address') {
34
+ Logging.appenders.email('email')
35
+ }
36
+ assert_raise(ArgumentError, 'Must specify to address') {
37
+ Logging.appenders.email('email', :from => 'me')
38
+ }
39
+ assert_nothing_raised {
40
+ Logging.appenders.email('email', :from => 'me', :to => 'you')
41
+ }
42
+
43
+ appender = Logging.appenders.email('email', :from => 'me', :to => 'you')
44
+
45
+ assert_equal(100, appender.auto_flushing)
46
+ assert_equal([], appender.instance_variable_get(:@immediate))
47
+ assert_equal('localhost', appender.address)
48
+ assert_equal(25, appender.port)
49
+
50
+ domain = ENV['HOSTNAME'] || 'localhost.localdomain'
51
+ assert_equal(domain, appender.domain)
52
+ assert_equal(nil, appender.user_name)
53
+ assert_equal(:plain, appender.authentication)
54
+ assert_equal("Message from #{$0}", appender.subject)
55
+
56
+ appender = Logging.appenders.email('email',
57
+ :from => 'lbrinn@gmail.com', :to => 'everyone',
58
+ :buffsize => '1000', :immediate_at => 'error, fatal',
59
+ :address => 'smtp.google.com', :port => '443',
60
+ :domain => 'google.com', :user_name => 'lbrinn',
61
+ :password => '1234', :authentication => 'plain', :enable_starttls_auto => true,
62
+ :subject => "I'm rich and you're not"
63
+ )
64
+
65
+ assert_equal('lbrinn@gmail.com', appender.instance_variable_get(:@from))
66
+ assert_equal(['everyone'], appender.instance_variable_get(:@to))
67
+ assert_equal(1000, appender.auto_flushing)
68
+ assert_equal('1234', appender.password)
69
+ assert_equal([nil, nil, nil, true, true],
70
+ appender.instance_variable_get(:@immediate))
71
+ assert_equal('smtp.google.com', appender.address)
72
+ assert_equal(443, appender.port)
73
+ assert_equal('google.com', appender.domain)
74
+ assert_equal('lbrinn', appender.user_name)
75
+ assert_equal(:plain, appender.authentication)
76
+ assert(appender.enable_starttls_auto)
77
+ assert_equal("I'm rich and you're not", appender.subject)
78
+
79
+ appender = Logging.appenders.email('email',
80
+ :from => 'me', :to => 'you', :auto_flushing => 42
81
+ )
82
+ assert_equal(42, appender.auto_flushing)
83
+ end
84
+
85
+ def test_append
86
+ # with auto_flushing enabled, mail will be sent each time a log event
87
+ # occurs
88
+ @appender.auto_flushing = true
89
+ event = Logging::LogEvent.new('TestLogger', @levels['warn'],
90
+ [1, 2, 3, 4], false)
91
+ @appender.append event
92
+ assert_not_equal(@levels.length, @appender.level)
93
+ assert_equal(0, @appender.buffer.length)
94
+
95
+ # increase the buffer size and log a few events
96
+ @appender.auto_flushing = 3
97
+ @appender.append event
98
+ @appender.append event
99
+ assert_equal(2, @appender.buffer.length)
100
+
101
+ @appender.append event
102
+ assert_not_equal(@levels.length, @appender.level)
103
+ assert_equal(0, @appender.buffer.length)
104
+
105
+ # error and fatal messages should be send immediately (no buffering)
106
+ error = Logging::LogEvent.new('ErrLogger', @levels['error'],
107
+ 'error message', false)
108
+ fatal = Logging::LogEvent.new('FatalLogger', @levels['fatal'],
109
+ 'fatal message', false)
110
+
111
+ @appender.append event
112
+ @appender.append fatal
113
+ assert_not_equal(@levels.length, @appender.level)
114
+ assert_equal(0, @appender.buffer.length)
115
+
116
+ @appender.append error
117
+ assert_not_equal(@levels.length, @appender.level)
118
+ assert_equal(0, @appender.buffer.length)
119
+
120
+ @appender.append event
121
+ assert_equal(1, @appender.buffer.length)
122
+ end
123
+
124
+ def test_concat
125
+ # with auto_flushing enabled, mail will be sent each time a log event
126
+ # occurs
127
+ @appender.auto_flushing = true
128
+ @appender << 'test message'
129
+ assert_not_equal(@levels.length, @appender.level)
130
+ assert_equal(0, @appender.buffer.length)
131
+
132
+ # increase the buffer size and log a few events
133
+ @appender.auto_flushing = 3
134
+ @appender << 'another test message'
135
+ @appender << 'a second test message'
136
+ assert_equal(2, @appender.buffer.length)
137
+
138
+ @appender << 'a third test message'
139
+ assert_not_equal(@levels.length, @appender.level)
140
+ assert_equal(0, @appender.buffer.length)
141
+ end
142
+
143
+ def test_flush
144
+ event = Logging::LogEvent.new('TestLogger', @levels['info'],
145
+ [1, 2, 3, 4], false)
146
+ @appender.append event
147
+ @appender << 'test message'
148
+ assert_equal(2, @appender.buffer.length)
149
+
150
+ @appender.flush
151
+ assert_not_equal(@levels.length, @appender.level)
152
+ assert_equal(0, @appender.buffer.length)
153
+ end
154
+
155
+ def test_close
156
+ event = Logging::LogEvent.new('TestLogger', @levels['info'],
157
+ [1, 2, 3, 4], false)
158
+ @appender.append event
159
+ @appender << 'test message'
160
+ assert_equal(2, @appender.buffer.length)
161
+
162
+ @appender.close
163
+ assert_not_equal(@levels.length, @appender.level)
164
+ assert_equal(0, @appender.buffer.length)
165
+ assert(@appender.closed?)
166
+ end
167
+
168
+ end
169
+ end
170
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logging-email
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tim Pease
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logging
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: flexmock
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bones-git
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bones
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.8.3
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 3.8.3
69
+ description: |-
70
+ The Logging email appender provides a way to send log messages via email from
71
+ a Ruby application. This is useful if you wish to be notified of exceptions or
72
+ fatal errors as they arise.
73
+
74
+ The email appender was originally part of the Logging framework proper, but with
75
+ the release of Logging 2.0.0, it has been extracted into its own gem.
76
+ email: tim.pease@gmail.com
77
+ executables: []
78
+ extensions: []
79
+ extra_rdoc_files: []
80
+ files:
81
+ - ".gitignore"
82
+ - ".travis.yml"
83
+ - README.md
84
+ - Rakefile
85
+ - lib/logging/appenders/email.rb
86
+ - lib/logging/plugins/email.rb
87
+ - script/bootstrap
88
+ - test/test_email.rb
89
+ homepage: http://rubygems.org/gems/logging-email
90
+ licenses: []
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options:
94
+ - "--main"
95
+ - README.md
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project: logging-email
110
+ rubygems_version: 2.2.2
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: An email appender for the Ruby Logging framework
114
+ test_files:
115
+ - test/test_email.rb