Skip to content

Commit

Permalink
Merge 1ff4f8d into caec7cb
Browse files Browse the repository at this point in the history
  • Loading branch information
Cawllec committed Jun 22, 2018
2 parents caec7cb + 1ff4f8d commit ccceae1
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 3 deletions.
3 changes: 2 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ source "https://rubygems.org"
group :test, optional: true do
gem 'rake', RUBY_VERSION <= '1.9.3' ? '~> 11.3.0' : '~> 12.3.0'
gem 'rspec'
gem 'rspec-mocks'
gem 'logging'
gem 'rdoc', '~> 5.1.0'
gem 'rspec-mocks'
gem 'pry'
gem 'addressable', '~> 2.3.8'
gem 'delayed_job' if RUBY_VERSION >= '2.2.2'
Expand Down
6 changes: 6 additions & 0 deletions example/rails-42/app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,10 @@ def severity
end
@text = msg
end

def crash_after_log
@test_model = TestModel.new :foo => "Foo"
@test_model.save
raise "Crash"
end
end
2 changes: 2 additions & 0 deletions example/rails-42/app/models/test_model.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class TestModel < ActiveRecord::Base
end
1 change: 1 addition & 0 deletions example/rails-42/config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Rails.application.routes.draw do
root :to => 'application#index'
get "log" => 'application#crash_after_log'

get 'crash' => 'application#crash'
get 'crash_with_callback' => 'application#callback'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CreateTestModels < ActiveRecord::Migration
def change
create_table :test_models do |t|
t.string :foo

t.timestamps null: false
end
end
end
2 changes: 1 addition & 1 deletion lib/bugsnag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def notify(exception, auto_notify=false, &block)

##
# Records a breadcrumb to give context to notifications
def leave_breadcrumb(name, type=nil, metadata={})
def leave_breadcrumb(name, metadata={}, type=Bugsnag::Breadcrumbs::MANUAL_TYPE)
configuration.recorder.add_breadcrumb(Bugsnag::Breadcrumbs::Breadcrumb.new(name, type, metadata))
end

Expand Down
29 changes: 29 additions & 0 deletions lib/bugsnag/breadcrumbs/appender.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require_relative "logger"
require "logging"

module Bugsnag::Breadcrumbs
class Appender < Logging::Appender
def initialize(level = Logger::INFO)
super "Bugsnag", { :level => level }
end

def <<(message)
return if closed?
Bugsnag::Breadcrumbs::Logger.log_breadcrumb(message)
end

def append(event)
return if closed? || !allow(event)

message = event.data.to_s
metadata = {
:method => event.method.to_s,
:file => event.file.to_s,
:line => event.line.to_s
}.delete_if { |_k, v| v == "" }

severity = Bugsnag::Breadcrumbs::Logger.get_severity_name(event.level)
Bugsnag::Breadcrumbs::Logger.log_breadcrumb(message, metadata, severity)
end
end
end
75 changes: 75 additions & 0 deletions lib/bugsnag/breadcrumbs/logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require "logger"
require "bugsnag"

module Bugsnag::Breadcrumbs
class Logger < Logger
SEVERITIES = [
"debug",
"info",
"warn",
"error",
"fatal",
"unknown"
]

def self.get_severity_name(severity)
if (0..5).cover? severity
SEVERITIES[severity]
else
severity
end
end

def self.log_breadcrumb(message, data = nil, severity = "unknown")
metadata = {
:severity => severity,
:message => message
}
if data.is_a? Hash
metadata.merge!(data)
elsif !data.nil?
metadata[:data] = data.to_s
end

Bugsnag.leave_breadcrumb("Log output", metadata, Bugsnag::Breadcrumbs::LOG_TYPE)
end

def initialize(level = Logger::INFO)
@open = true
super nil, level
end

def add(severity, message = nil, progname = nil)
return unless @open

if block_given?
message = yield message
elsif message.nil?
message = progname
end

if severity >= level
Bugsnag::Breadcrumbs::Logger.log_breadcrumb(
message,
{ :progname => progname },
Bugsnag::Breadcrumbs::Logger.get_severity_name(severity))
end
end
alias log add

def <<(message)
return unless @open
Bugsnag::Breadcrumbs::Logger.log_breadcrumb(message)
end

def close
@open = false
true
end

def reopen
@open = true
true
end
end
end
64 changes: 64 additions & 0 deletions spec/appender_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# encoding: utf-8

# Necessary to avoid monkey patching thread methods
ENV["LOGGING_INHERIT_CONTEXT"] = "false"

require 'spec_helper'
require 'logger'
require 'logging'
require 'bugsnag/breadcrumbs/appender'

describe Bugsnag::Breadcrumbs::Appender do

before do
@appender = Bugsnag::Breadcrumbs::Appender.new
end

it "writes breadcrumbs" do
expect(Bugsnag).to receive(:leave_breadcrumb).with(
"Log output",
{
:severity => "unknown",
:message => "message"
},
"log"
)
@appender << "message"
end

it "write breadcrumbs from a logevent" do
expect(Bugsnag).to receive(:leave_breadcrumb).with(
"Log output",
{
:message => ["message1", "message2"].to_s,
:severity => "info",
},
"log"
)
logevent = Logging::LogEvent.new("testLogger", Logger::INFO, ["message1", "message2"], false)
@appender.append logevent
end

it "adds trace metadata if available" do
expect(Bugsnag).to receive(:leave_breadcrumb) do |name, metadata, severity|
expect(name).to eq("Log output")
expect(metadata).to include(:message, :severity, :method, :file, :line)
expect(metadata).to include(:message => ["message1", "message2"].to_s, :severity => "info")
expect(severity).to eq("log")
end
logevent = Logging::LogEvent.new("testLogger", Logger::INFO, ["message1", "message2"], true)
@appender.append logevent
end

it "doesn't write if closed" do
expect(Bugsnag).to_not receive(:leave_breadcrumb)
@appender.close
@appender << "message"
logevent = Logging::LogEvent.new("testLogger", Logger::INFO, ["message1", "message2"], false)
@appender.append logevent
end

it "is an appender and a bugsnag appender" do
expect(@appender.class.ancestors).to include(Bugsnag::Breadcrumbs::Appender, Logging::Appender)
end
end
61 changes: 61 additions & 0 deletions spec/logger_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# encoding: utf-8

require 'spec_helper'
require 'logger'
require 'bugsnag/breadcrumbs/logger'

describe Bugsnag::Breadcrumbs::Logger do

before do
@logger = Bugsnag::Breadcrumbs::Logger.new
end

it "writes by default" do
expect(Bugsnag).to receive(:leave_breadcrumb).with(
"Log output",
{
:severity => "unknown",
:message => "message"
},
"log"
)
@logger << "message"
end

it "doesn't write when closed" do
expect(Bugsnag).to_not receive(:leave_breadcrumb)
@logger.close
@logger << "message"
end

it "writes after being re-opened" do
expect(Bugsnag).to receive(:leave_breadcrumb).with(
"Log output",
{
:severity => "unknown",
:message => "message"
},
"log"
)
@logger.close
@logger.reopen
@logger << "message"
end

it "allows a progname and severity" do
expect(Bugsnag).to receive(:leave_breadcrumb).with(
"Log output",
{
:progname => "logTests",
:severity => "info",
:message => "message"
},
"log"
)
@logger.info("logTests") { "message" }
end

it "is a logger and a bugsnag logger" do
expect(@logger.class.ancestors).to include(Bugsnag::Breadcrumbs::Logger, Logger)
end
end
2 changes: 1 addition & 1 deletion spec/report_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def gloops
end

it "attaches added breadcrumbs" do
Bugsnag.leave_breadcrumb("Test", Bugsnag::Breadcrumbs::MANUAL_TYPE, {:foo => "foo", :bar => "bar"})
Bugsnag.leave_breadcrumb("Test", {:foo => "foo", :bar => "bar"}, Bugsnag::Breadcrumbs::MANUAL_TYPE)
Bugsnag.notify(BugsnagTestException.new("It crashed"))
expect(Bugsnag).to have_sent_notification{ |payload, headers|
breadcrumb = get_breadcrumb_from_payload(payload)
Expand Down

0 comments on commit ccceae1

Please sign in to comment.