logging_elf 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: edd72f1b9a67df249d70aa481c0ddb1eb8e77674
4
+ data.tar.gz: bdb49524283475272dc2fc46b3a039cda6ae802e
5
+ SHA512:
6
+ metadata.gz: 4dfd2ae5addd66e46cdc1d769a93fbe77b098acef96e9e8e64763c8ffc309feb5689a08d9d8fbb7fd159d05f656e98bb1aace67633df7578ae5c2c3565b1cf32
7
+ data.tar.gz: 4aca640abc72f3754bf12182dccc7429833b8be8ab5afb2f0781d6906eb8164bc18b6dc16b2173be1f7da7486abbeec209c421312f61412cdca45df2ce86970a
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 2.0.0
3
+ - 2.1
4
+ - ruby-head
5
+ matrix:
6
+ allow_failures:
7
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in logging_elf.gemspec
4
+ gemspec
5
+
6
+ group 'development' do
7
+ gem 'guard'
8
+ gem 'guard-rspec'
9
+ end
@@ -0,0 +1,10 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^lib/(.+)\.rb$}) do |m|
6
+ ["spec/#{m[1]}_spec.rb", "spec/integrations/entire_flow_spec.rb"]
7
+ end
8
+ watch(%r{^spec/.+_spec\.rb$})
9
+ watch('spec/spec_helper.rb') { "spec" }
10
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Jeff Deville
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,30 @@
1
+ # LoggingElf
2
+ [![Build Status](https://travis-ci.org/promptworks/logging_elf.png?branch=master)](https://travis-ci.org/promptworks/logging_elf)
3
+
4
+ TODO: Write a gem description
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'logging_elf'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install logging_elf
19
+
20
+ ## Usage
21
+
22
+ TODO: Write usage instructions here
23
+
24
+ ## Contributing
25
+
26
+ 1. Fork it ( https://github.com/[my-github-username]/logging_elf/fork )
27
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
28
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
29
+ 4. Push to the branch (`git push origin my-new-feature`)
30
+ 5. Create a new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ task default: [:spec]
5
+
6
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,16 @@
1
+ require 'active_model'
2
+ require 'active_support/core_ext/hash'
3
+ require 'virtus'
4
+ require 'logging'
5
+ require 'gelf'
6
+
7
+ require "logging_elf/version"
8
+ require "logging_elf/config"
9
+ require "logging_elf/gelf_data"
10
+ require "logging_elf/gelf_appender"
11
+ require "logging_elf/tracing_logger"
12
+ require "logging_elf/lograge_formatter"
13
+ require "logging_elf/uncaught_exceptions_middleware"
14
+
15
+ module LoggingElf
16
+ end
@@ -0,0 +1,14 @@
1
+ module LoggingElf
2
+ class << self
3
+ attr_accessor :config
4
+ end
5
+
6
+ def self.configure
7
+ self.config ||= Configuration.new
8
+ yield(config)
9
+ end
10
+
11
+ class Configuration
12
+ attr_accessor :graylog_host, :graylog_port, :trace_hash, :host
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ module Logging::Appenders
2
+ def self.gelf(*args)
3
+ LoggingElf::GelfAppender.new(*args)
4
+ end
5
+ end
6
+
7
+ module LoggingElf
8
+ class GelfAppender < ::Logging::Appender
9
+ attr_accessor :logger
10
+ def initialize(opts = {})
11
+ super "gelf", opts
12
+ @logger = GELF::Logger.new(
13
+ opts[:graylog_host], opts[:graylog_port], "WAN")
14
+ end
15
+
16
+ def write(event)
17
+ return if event.data.is_a?(String) && event.data.blank?
18
+ message = GelfData.from_log_event event
19
+ @logger.notify! message.to_gelf
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,85 @@
1
+ # http://graylog2.org/gelf#specs
2
+ # Some appenders can output to different formats, but this isn't
3
+ # one of them, so it's simplified as a result.
4
+
5
+ module LoggingElf
6
+ class GelfData
7
+ include Virtus.model
8
+ include ActiveModel::Validations
9
+
10
+ attribute :host, String
11
+ attribute :version, String, default: "1.0"
12
+ attribute :short_message, String
13
+ attribute :full_message, String
14
+ # UNIX microsecond timestamp, should be set by client!
15
+ attribute :timestamp, Integer
16
+ attribute :level, Integer
17
+ # Have to set this way even though facility is deprecated
18
+ # because gelf-rb will overwrite it otherwise
19
+ attribute :facility, String
20
+ attr_accessor :additional_fields
21
+ validates :host, :version, :short_message, presence: true
22
+
23
+ def initialize(gelf_data = {})
24
+ super
25
+ self.additional_fields ||= {}
26
+ self.host ||= LoggingElf.config.host if LoggingElf.config
27
+ return if gelf_data.nil?
28
+ add_fields(gelf_data)
29
+ end
30
+
31
+ def to_gelf
32
+ required_gelf_attributes.merge additional_fields
33
+ end
34
+
35
+ def required_gelf_attributes
36
+ attributes
37
+ end
38
+
39
+ def self.from_log_event(log_event)
40
+ gd = GelfData.new(level: log_event.level, facility: log_event.logger)
41
+ case log_event.data
42
+ when String then gd.short_message = log_event.data
43
+ when Hash then add_hash_data(gd, log_event.data)
44
+ when Exception then add_exception_details gd, log_event.data
45
+ end
46
+ set_backtrace_data gd, log_event
47
+ gd
48
+ end
49
+
50
+ def self.add_hash_data(gelf_data, data)
51
+ gelf_data.add_fields(data)
52
+
53
+ unless gelf_data.short_message
54
+ gelf_data.short_message = data[:message] || data["message"]
55
+ if gelf_data.short_message.blank?
56
+ gelf_data.short_message = data.map { |k, v| "#{k}='#{v}'" }.join(" ")
57
+ end
58
+ end
59
+ end
60
+
61
+ def add_fields(params_hash)
62
+ params_hash.each do |key, value|
63
+ if required_gelf_attributes.keys.include? key
64
+ send("#{key}=", value)
65
+ else
66
+ additional_fields["_#{key}".to_sym] = value
67
+ end
68
+ end
69
+ end
70
+
71
+ def self.add_exception_details(gelf_data, error)
72
+ gelf_data.full_message = gelf_data.short_message =
73
+ "<#{error.class.name}> #{error.message}"
74
+ if error.backtrace
75
+ gelf_data.full_message << "\n\t" << error.backtrace.join("\n\t")
76
+ end
77
+ end
78
+
79
+ def self.set_backtrace_data(gelf_data, event)
80
+ gelf_data.add_fields(file: event.file) if event.file
81
+ gelf_data.add_fields(file: event.line) if event.line
82
+ gelf_data.add_fields(file: event.method) if event.method
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,8 @@
1
+ module LoggingElf
2
+ class LogrageFormatter
3
+ def call(data)
4
+ data[:message] = data[:path]
5
+ data
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,80 @@
1
+ module LoggingElf
2
+ class TracingLogger
3
+ extend Forwardable
4
+ def_delegators :@logger, :<<, :<=>, :_dump_configuration, :_meta_eval,
5
+ :add, :add_appenders, :additive, :additive=, :appenders, :appenders=,
6
+ :clear_appenders, :inspect, :level, :level=, :name, :parent, :_setup,
7
+ :remove_appenders, :trace, :trace=, :write, :formatter, :root, :config
8
+
9
+ Logging.init
10
+
11
+ def_delegators :@logger,
12
+ *Logging::LEVELS.map { |name, _| "#{name}?".to_sym }
13
+
14
+ Logging::LEVELS.each do |name, _|
15
+ define_method name.to_sym do |data = nil|
16
+ begin
17
+ # data = yield if block_given?
18
+ return if data.nil?
19
+ data = append_trace_info(data)
20
+ @logger.send(name.to_sym, data)
21
+ rescue => err
22
+ p err
23
+ pp err.backtrace
24
+ end
25
+ end
26
+ end
27
+
28
+ def initialize(logger, &trace_hash)
29
+ @logger = Logging::Logger.new logger if logger.is_a? String
30
+ self.trace_hash = if block_given?
31
+ trace_hash
32
+ elsif LoggingElf.config.trace_hash
33
+ LoggingElf.config.trace_hash
34
+ else
35
+ fail "TracingLogger cannot be created with no" \
36
+ " mechanism for appending trace data"
37
+ end
38
+ end
39
+
40
+ attr_writer :trace_hash
41
+ def trace_hash
42
+ hash = if @trace_hash.respond_to?(:call)
43
+ @trace_hash.call
44
+ else
45
+ @trace_hash
46
+ end
47
+
48
+ hash || {}
49
+ end
50
+
51
+ def exception_data(data)
52
+ {
53
+ error_object: data,
54
+ backtrace: data.backtrace,
55
+ short_message: "Exception: #{data.message}",
56
+ message: data.message,
57
+ is_exception: true
58
+ }
59
+ end
60
+
61
+ def default_data(data)
62
+ {
63
+ short_message: "Unknown thing to log",
64
+ message: data.inspect
65
+ }
66
+ end
67
+
68
+ def append_trace_info(data)
69
+ data = case data
70
+ when Hash then data
71
+ when Exception then exception_data(data)
72
+ when String then { message: data }
73
+ when nil then return
74
+ else
75
+ default_data(data)
76
+ end
77
+ data.merge(trace_hash)
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,26 @@
1
+ module LoggingElf
2
+ class UncaughtExceptionsMiddleware
3
+ attr_accessor :logger
4
+ def initialize(app, args = {})
5
+ self.logger = args[:logger]
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ begin
11
+ response = @app.call env
12
+ rescue => err
13
+ logger.error err
14
+ raise err
15
+ end
16
+ log_rack_exceptions(env)
17
+ response
18
+ end
19
+
20
+ private
21
+
22
+ def log_rack_exceptions(env)
23
+ logger.error env['rack.exception'] if env['rack.exception']
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module LoggingElf
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,30 @@
1
+ # rubocop:disable RegexpLiteral
2
+ # coding: utf-8
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'logging_elf/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "logging_elf"
9
+ spec.version = LoggingElf::VERSION
10
+ spec.authors = ["Jeff Deville"]
11
+ spec.email = ["jeffdeville@gmail.com"]
12
+ spec.summary = "Logging, Tracing, and Gelf Logging for rails"
13
+ spec.description = "Logging, Tracing, and Gelf Logging for rails"
14
+ spec.homepage = ""
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "logging", "~> 1.8"
23
+ spec.add_dependency "virtus", "~> 1.0"
24
+ spec.add_dependency "activemodel"
25
+ spec.add_dependency "gelf"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.6"
28
+ spec.add_development_dependency 'rake'
29
+ spec.add_development_dependency 'rspec', '~> 2.0'
30
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ class FakeGelfNotifier
4
+ attr_accessor :logs
5
+ def initialize
6
+ self.logs = []
7
+ end
8
+
9
+ def notify!(data)
10
+ logs << data
11
+ end
12
+ end
13
+
14
+ describe "Tracing all the way through" do
15
+ let(:notifier) do
16
+ # Lets us look at what was sent to the appenders
17
+ FakeGelfNotifier.new
18
+ end
19
+
20
+ let(:trace_hash) { { browser_id: "browser_id" } }
21
+
22
+ let(:gelf_data_hash) { notifier.logs.last }
23
+
24
+ before do
25
+ LoggingElf.configure do |config|
26
+ config.trace_hash = -> { trace_hash }
27
+ config.host = "host"
28
+ end
29
+
30
+ logger = LoggingElf::TracingLogger.new("test")
31
+ logger.class.name.should eq "LoggingElf::TracingLogger"
32
+ appender = Logging::Appenders.gelf
33
+ appender.logger = notifier
34
+ logger.add_appenders(appender)
35
+ logger.info log_subject
36
+ end
37
+
38
+ shared_examples_for "gelf data output" do
39
+ let(:reconstituted_gelf_data) do
40
+ gelf_data_hash.select { |k, _| k.to_s.start_with?("_") }.each do |k, v|
41
+ gelf_data_hash["#{k.slice(1..-1)}"] = gelf_data_hash.delete k
42
+ end
43
+ LoggingElf::GelfData.new gelf_data_hash
44
+ end
45
+
46
+ specify { expect(reconstituted_gelf_data).to be_valid }
47
+ end
48
+
49
+ describe "logging a string" do
50
+ let(:log_subject) { "string message" }
51
+ it_should_behave_like "gelf data output"
52
+ specify { expect(gelf_data_hash[:short_message]).to eq "string message" }
53
+ specify { expect(gelf_data_hash[:_browser_id]).to eq "browser_id" }
54
+ end
55
+
56
+ describe "logging a hash" do
57
+ let(:log_subject) { { foo: 'bar' } }
58
+ it_should_behave_like "gelf data output"
59
+ end
60
+
61
+ describe "logging an exception" do
62
+ let(:log_subject) { RuntimeError.new "Boom" }
63
+ it_should_behave_like "gelf data output"
64
+ end
65
+
66
+ end
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+ include Logging
3
+ include LoggingElf
4
+
5
+ describe GelfData do
6
+ describe ".valid?" do
7
+ it "should ensure validity of the data object" do
8
+ gd = GelfData.new
9
+ gd.version = nil
10
+ gd.should_not be_valid
11
+ gd.errors.count.should eq 3
12
+
13
+ gd.host = "host"
14
+ gd.should_not be_valid
15
+ gd.errors.count.should eq 2
16
+
17
+ gd.version = "12"
18
+ gd.should_not be_valid
19
+ gd.errors.count.should eq 1
20
+
21
+ gd.short_message = "short message"
22
+ gd.should be_valid
23
+ end
24
+
25
+ it "should pull the host from the LoggingElf.config if not specified" do
26
+ LoggingElf.configure do |config|
27
+ config.host = "host"
28
+ end
29
+ gd = GelfData.new
30
+ gd.host.should == "host"
31
+ end
32
+ end
33
+
34
+ describe "#add_fields" do
35
+ let(:gd) { GelfData.new }
36
+
37
+ it "sets a required attribute" do
38
+ gd.add_fields(host: "localhost")
39
+
40
+ gd.host.should eq "localhost"
41
+ end
42
+
43
+ it "adds non-required fields to the additional_fields hash" do
44
+ gd.add_fields(extra_field: "extra value")
45
+
46
+ gd.additional_fields[:_extra_field].should eq "extra value"
47
+ end
48
+ end
49
+
50
+ describe "initialize" do
51
+ it "should set standard params via constructor" do
52
+ gd = GelfData.new(
53
+ host: "host",
54
+ version: "123",
55
+ short_message: "short_message",
56
+ full_message: "full_message",
57
+ timestamp: 123,
58
+ level: 1
59
+ )
60
+ gd.host.should eq "host"
61
+ gd.version.should eq '123'
62
+ gd.short_message.should eq 'short_message'
63
+ gd.full_message.should eq 'full_message'
64
+ gd.timestamp.should eq 123
65
+ gd.level.should eq 1
66
+ end
67
+ end
68
+
69
+ describe "from_log_event" do
70
+ let(:event) { LogEvent.new("testing", 3, data, trace) }
71
+ let(:trace) { nil }
72
+ subject { GelfData.from_log_event event }
73
+
74
+ shared_examples_for "all gelf data" do
75
+ specify { expect(subject.short_message).to_not be_blank }
76
+ end
77
+
78
+ context "with a hash" do
79
+ let(:data) do
80
+ { extra_field: "extra value", facility: "facility" }.merge(message)
81
+ end
82
+ %w[message short_message].each do |field_name|
83
+ %i[to_s to_sym].each do |field_name_format|
84
+ context "with a #{field_name} #{field_name_format}" do
85
+ let(:message) do
86
+ { field_name.send(field_name_format) => "message" }
87
+ end
88
+ specify do
89
+ subject.additional_fields[:_extra_field].should eq "extra value"
90
+ end
91
+ it_should_behave_like "all gelf data"
92
+ end
93
+ end
94
+ end
95
+
96
+ context "with no discernible message" do
97
+ let(:message) { {} }
98
+ specify do
99
+ expect(subject.short_message).to eq(
100
+ "extra_field='extra value' facility='facility'")
101
+ end
102
+ it_should_behave_like "all gelf data"
103
+ end
104
+ end
105
+
106
+ context "with a string" do
107
+ let(:data) { "I am a string" }
108
+ specify { expect(subject.short_message).to eq data }
109
+ end
110
+
111
+ context "with an exception" do
112
+ let(:data) { { error_object: RuntimeError.new("hi") } }
113
+ it_should_behave_like "all gelf data"
114
+
115
+ context "and a trace" do
116
+ let(:trace) { caller }
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "to_gelf" do
122
+ let(:gd) do
123
+ GelfData.new(
124
+ host: "host",
125
+ short_message: "short_message",
126
+ full_message: "full_message",
127
+ timestamp: 123,
128
+ level: 1,
129
+ line: 12,
130
+ file: "file",
131
+ facility: "facility",
132
+ other_data: "other_data"
133
+ )
134
+ end
135
+
136
+ it "adds a version" do
137
+ gd.to_gelf.keys.should include(:version)
138
+ end
139
+
140
+ it "prepends an underscore to some key names" do
141
+ keys = gd.to_gelf.keys
142
+ keys.should include(:_line, :_file, :_other_data)
143
+ keys.should_not include(:line, :file, :other_data)
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+ include Logging
3
+ include LoggingElf
4
+
5
+ describe LoggingElf::TracingLogger do
6
+ let(:fake_appender) do
7
+ # Lets us look at what was sent to the appenders
8
+ class FakeAppender < ::Logging::Appender
9
+ attr_accessor :logs
10
+ def initialize(name, opts)
11
+ super(name, opts)
12
+ self.logs = []
13
+ end
14
+
15
+ def write(data)
16
+ logs << data
17
+ end
18
+ end
19
+ FakeAppender.new("test", level: 1)
20
+ end
21
+
22
+ let(:trace_hash) do
23
+ {
24
+ browser_id: "browser_id",
25
+ session_id: "session_id",
26
+ request_method: "request.method",
27
+ path: "request.path"
28
+ }
29
+ end
30
+
31
+ let!(:result) do
32
+ subject.info data
33
+ recent_event = fake_appender.logs.last
34
+ recent_event.nil? ? nil : recent_event.data
35
+ end
36
+
37
+ shared_examples_for "log info should include trace data" do
38
+ it "should include the trace hash" do
39
+ result[:browser_id].should eq trace_hash[:browser_id]
40
+ result[:session_id].should eq trace_hash[:session_id]
41
+ result[:request_method].should eq trace_hash[:request_method]
42
+ result[:path].should eq trace_hash[:path]
43
+ end
44
+ end
45
+
46
+ subject do
47
+ logger = TracingLogger.new("test") { trace_hash }
48
+ logger.appenders = fake_appender
49
+ logger
50
+ end
51
+
52
+ context "logging nil" do
53
+ let(:data) { nil }
54
+ specify { expect(result).to be_nil }
55
+ end
56
+
57
+ context "logging a hash" do
58
+ let(:data) do
59
+ {
60
+ field1: "field1",
61
+ field2: "field2"
62
+ }
63
+ end
64
+ it_should_behave_like "log info should include trace data"
65
+ it "should include the original data as well" do
66
+ result[:field1].should eq data[:field1]
67
+ result[:field2].should eq data[:field2]
68
+ end
69
+ end
70
+
71
+ context "logging a string" do
72
+ let(:data) { "I am a Log Event" }
73
+ specify { expect(result[:message]).to eq data }
74
+ it_should_behave_like "log info should include trace data"
75
+ end
76
+
77
+ context "logging an exception" do
78
+ let(:data) { RuntimeError.new "Hi" }
79
+ it_should_behave_like "log info should include trace data"
80
+ specify { result[:is_exception].should be_truthy }
81
+ specify { result[:error_object].should eq data }
82
+ specify { result[:backtrace].should eq data.backtrace }
83
+ specify { result[:message].should eq "Hi" }
84
+ specify { result[:short_message].should eq "Exception: Hi" }
85
+ end
86
+
87
+ context "logging an unknown type" do
88
+ let(:data) { OpenStruct.new(jeff: "was here ") }
89
+ it_should_behave_like "log info should include trace data"
90
+ it "should still log something" do
91
+ result[:message].should eq data.inspect
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe LoggingElf::UncaughtExceptionsMiddleware do
4
+ describe "call" do
5
+ let(:logger) { FakeLogger.new }
6
+ let(:last_msg) { logger.logs.last }
7
+ let(:app) { double }
8
+ let(:env) { { test: "test" } }
9
+ let(:response) { "I am the response" }
10
+ subject do
11
+ LoggingElf::UncaughtExceptionsMiddleware.new app, logger: logger
12
+ end
13
+
14
+ def act
15
+ @returned_response = subject.call env
16
+ end
17
+
18
+ context "no errors occurred" do
19
+ before do
20
+ app.stub(:call).with(env).and_return response
21
+ act
22
+ end
23
+ it 'should not have logged anything' do
24
+ logger.logs.count.should eq 0
25
+ end
26
+ specify { @returned_response.should_not be_nil }
27
+ end
28
+
29
+ context "an uncaught exception is raised" do
30
+ before do
31
+ app.stub(:call).with(env).and_raise(StandardError)
32
+ end
33
+
34
+ it 'should have logged the error' do
35
+ begin
36
+ act
37
+ # rubocop:disable HandleExceptions
38
+ rescue
39
+ # rubocop:enable HandleExceptions
40
+ ensure
41
+ logger.logs.count.should eq 1
42
+ last_msg.should be_a StandardError
43
+ end
44
+ end
45
+
46
+ it 're-raises the exception' do
47
+ expect { act }.to raise_error StandardError
48
+ end
49
+ end
50
+
51
+ context "an error is added to env['rack.exception']" do
52
+ before do
53
+ env['rack.exception'] = "I am a sad sad exception"
54
+ app.stub(:call).with(env).and_return response
55
+ act
56
+ end
57
+ it 'should have logged the error' do
58
+ logger.logs.count.should eq 1
59
+ last_msg.should eq env['rack.exception']
60
+ end
61
+ specify { @returned_response.should_not be_nil }
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,18 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ require 'logging_elf'
4
+ support_files = Dir[File.join(
5
+ File.expand_path("../../spec/support/**/*.rb", __FILE__)
6
+ )]
7
+ support_files.each { |f| require f }
8
+
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+ config.order = :random
14
+
15
+ config.before(:each) do
16
+ LoggingElf.config = nil
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ LoggingElf.configure do |config|
2
+ config.graylog_host = "10.88.90.73"
3
+ config.graylog_port = 12_201
4
+ end
@@ -0,0 +1,15 @@
1
+ class FakeLogger
2
+ attr_accessor :logs
3
+ def initialize
4
+ @logs = []
5
+ end
6
+
7
+ def debug(obj)
8
+ logs << obj
9
+ end
10
+
11
+ alias_method :info, :debug
12
+ alias_method :warn, :debug
13
+ alias_method :error, :debug
14
+ alias_method :fatal, :debug
15
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logging_elf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jeff Deville
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-26 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: '1.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: virtus
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
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: activemodel
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: gelf
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.6'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '2.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ description: Logging, Tracing, and Gelf Logging for rails
112
+ email:
113
+ - jeffdeville@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .rspec
120
+ - .travis.yml
121
+ - Gemfile
122
+ - Guardfile
123
+ - LICENSE.txt
124
+ - README.md
125
+ - Rakefile
126
+ - lib/logging_elf.rb
127
+ - lib/logging_elf/config.rb
128
+ - lib/logging_elf/gelf_appender.rb
129
+ - lib/logging_elf/gelf_data.rb
130
+ - lib/logging_elf/lograge_formatter.rb
131
+ - lib/logging_elf/tracing_logger.rb
132
+ - lib/logging_elf/uncaught_exceptions_middleware.rb
133
+ - lib/logging_elf/version.rb
134
+ - logging_elf.gemspec
135
+ - spec/integrations/entire_flow_spec.rb
136
+ - spec/logging_elf/gelf_data_spec.rb
137
+ - spec/logging_elf/tracing_logger_spec.rb
138
+ - spec/logging_elf/uncaught_exceptions_middleware_spec.rb
139
+ - spec/spec_helper.rb
140
+ - spec/support/config.rb
141
+ - spec/support/fake_logger.rb
142
+ homepage: ''
143
+ licenses:
144
+ - MIT
145
+ metadata: {}
146
+ post_install_message:
147
+ rdoc_options: []
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ requirements: []
161
+ rubyforge_project:
162
+ rubygems_version: 2.0.14
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: Logging, Tracing, and Gelf Logging for rails
166
+ test_files:
167
+ - spec/integrations/entire_flow_spec.rb
168
+ - spec/logging_elf/gelf_data_spec.rb
169
+ - spec/logging_elf/tracing_logger_spec.rb
170
+ - spec/logging_elf/uncaught_exceptions_middleware_spec.rb
171
+ - spec/spec_helper.rb
172
+ - spec/support/config.rb
173
+ - spec/support/fake_logger.rb
174
+ has_rdoc: