sentry-raven 0.4.1 → 0.4.2

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.

Potentially problematic release.


This version of sentry-raven might be problematic. Click here for more details.

@@ -19,7 +19,7 @@ module Raven
19
19
  class << self
20
20
  # The client object is responsible for delivering formatted data to the Sentry server.
21
21
  # Must respond to #send. See Raven::Client.
22
- attr_accessor :client
22
+ attr_writer :client
23
23
 
24
24
  # A Raven configuration object. Must act like a hash and return sensible
25
25
  # values for all Raven configuration options. See Raven::Configuration.
@@ -40,6 +40,11 @@ module Raven
40
40
  @configuration ||= Configuration.new
41
41
  end
42
42
 
43
+ # The client object is responsible for delivering formatted data to the Sentry server.
44
+ def client
45
+ @client ||= Client.new(configuration)
46
+ end
47
+
43
48
  # Call this method to modify defaults in your initializers.
44
49
  #
45
50
  # @example
@@ -47,7 +52,10 @@ module Raven
47
52
  # config.server = 'http://...'
48
53
  # end
49
54
  def configure(silent = false)
50
- yield(configuration)
55
+ if block_given?
56
+ yield(configuration)
57
+ end
58
+
51
59
  self.client = Client.new(configuration)
52
60
  report_ready unless silent
53
61
  self.client
@@ -59,7 +67,7 @@ module Raven
59
67
  # evt = Raven::Event.new(:message => "An error")
60
68
  # Raven.send(evt)
61
69
  def send(evt)
62
- @client.send(evt) if @client
70
+ client.send(evt)
63
71
  end
64
72
 
65
73
  # Capture and process any exceptions from the given block, or globally if
@@ -100,6 +108,24 @@ module Raven
100
108
  send(evt) if evt
101
109
  end
102
110
 
111
+ # Bind context for any future events
112
+ #
113
+ # @example
114
+ # Raven.context({
115
+ # :tags => {
116
+ # 'key' => 'value',
117
+ # }
118
+ # })
119
+ def context(hash = {})
120
+ Thread.current[:sentry_context] ||= {}
121
+ Thread.current[:sentry_context].merge!(hash)
122
+ self
123
+ end
124
+
125
+ def clear!
126
+ Thread.current[:sentry_context] = nil
127
+ end
128
+
103
129
  # For cross-language compat
104
130
  alias :captureException :capture_exception
105
131
  alias :captureMessage :capture_message
@@ -1,4 +1,3 @@
1
- require 'openssl'
2
1
  require 'multi_json'
3
2
  require 'zlib'
4
3
  require 'base64'
@@ -11,7 +10,7 @@ module Raven
11
10
 
12
11
  class Client
13
12
 
14
- PROTOCOL_VERSION = '2.0'
13
+ PROTOCOL_VERSION = '3.0'
15
14
  USER_AGENT = "raven-ruby/#{Raven::VERSION}"
16
15
  CONTENT_TYPE = 'application/json'
17
16
 
@@ -57,10 +56,6 @@ module Raven
57
56
  end
58
57
  end
59
58
 
60
- def generate_signature(timestamp, data)
61
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha1'), self.configuration.secret_key, "#{timestamp} #{data}")
62
- end
63
-
64
59
  def generate_auth_header(data)
65
60
  now = Time.now.to_i.to_s
66
61
  fields = {
@@ -68,7 +63,7 @@ module Raven
68
63
  'sentry_client' => USER_AGENT,
69
64
  'sentry_timestamp' => now,
70
65
  'sentry_key' => self.configuration.public_key,
71
- 'sentry_signature' => generate_signature(now, data)
66
+ 'sentry_secret' => self.configuration.secret_key,
72
67
  }
73
68
  'Sentry ' + fields.map{|key, value| "#{key}=#{value}"}.join(', ')
74
69
  end
@@ -23,42 +23,57 @@ module Raven
23
23
  PLATFORM = "ruby"
24
24
 
25
25
  attr_reader :id
26
- attr_accessor :project, :message, :timestamp, :level
26
+ attr_accessor :project, :message, :timestamp, :level, :context
27
27
  attr_accessor :logger, :culprit, :server_name, :modules, :extra, :tags
28
28
 
29
29
  def initialize(options={}, &block)
30
30
  @configuration = options[:configuration] || Raven.configuration
31
31
  @interfaces = {}
32
32
 
33
+ @context = Thread.current[:sentry_context] || {}
34
+
33
35
  @id = options[:id] || UUIDTools::UUID.random_create.hexdigest
34
36
  @message = options[:message]
35
37
  @timestamp = options[:timestamp] || Time.now.utc
36
- @level = options[:level] || :error
37
- @logger = options[:logger] || 'root'
38
+
39
+ @level = options[:level]
40
+ @logger = options[:logger]
38
41
  @culprit = options[:culprit]
39
- @extra = options[:extra]
40
- @tags = options[:tags]
42
+
43
+ @extra = options[:extra] || {}
44
+ @tags = options[:tags] || {}
41
45
 
42
46
  # Try to resolve the hostname to an FQDN, but fall back to whatever the load name is
43
- hostname = Socket.gethostname
44
- hostname = Socket.gethostbyname(hostname).first rescue hostname
45
- @server_name = options[:server_name] || hostname
47
+ @server_name = options[:server_name] || get_hostname
46
48
 
47
- # Older versions of Rubygems don't support iterating over all specs
48
- if @configuration.send_modules && Gem::Specification.respond_to?(:map)
49
- options[:modules] ||= Hash[Gem::Specification.map {|spec| [spec.name, spec.version.to_s]}]
49
+ if @configuration.send_modules
50
+ options[:modules] ||= get_modules
50
51
  end
51
52
  @modules = options[:modules]
52
53
 
53
54
  block.call(self) if block
54
55
 
56
+ # Merge in context
57
+ @level ||= @context[:level] || :error
58
+ @logger ||= @context[:logger] || 'root'
59
+ @culprit ||= @context[:culprit]
60
+
61
+ @tags.merge!(@context[:tags]) if @context[:tags]
62
+ @extra.merge!(@context[:extra]) if @context[:extra]
63
+
55
64
  # Some type coercion
56
65
  @timestamp = @timestamp.strftime('%Y-%m-%dT%H:%M:%S') if @timestamp.is_a?(Time)
57
66
  @level = LOG_LEVELS[@level.to_s.downcase] if @level.is_a?(String) || @level.is_a?(Symbol)
67
+ end
58
68
 
59
- # Basic sanity checking
60
- raise Error.new('A message is required for all events') unless @message && !@message.empty?
61
- raise Error.new('A timestamp is required for all events') unless @timestamp
69
+ def get_hostname
70
+ hostname = Socket.gethostname
71
+ hostname = Socket.gethostbyname(hostname).first rescue hostname
72
+ end
73
+
74
+ def get_modules
75
+ # Older versions of Rubygems don't support iterating over all specs
76
+ Hash[Gem::Specification.map {|spec| [spec.name, spec.version.to_s]}] if Gem::Specification.respond_to?(:map)
62
77
  end
63
78
 
64
79
  def interface(name, value=nil, &block)
@@ -126,7 +141,7 @@ module Raven
126
141
  frame.in_app = line.in_app
127
142
  if context_lines and frame.abs_path
128
143
  frame.pre_context, frame.context_line, frame.post_context = \
129
- evt.get_context(frame.abs_path, frame.lineno, context_lines)
144
+ evt.get_file_context(frame.abs_path, frame.lineno, context_lines)
130
145
  end
131
146
  end
132
147
  }.select{ |f| f.filename }
@@ -160,7 +175,7 @@ module Raven
160
175
  def self._source_lines(path, from, to)
161
176
  end
162
177
 
163
- def get_context(filename, lineno, context)
178
+ def get_file_context(filename, lineno, context)
164
179
  lines = (2 * context + 1).times.map do |i|
165
180
  Raven::LineCache::getline(filename, lineno - context + i)
166
181
  end
@@ -168,7 +183,7 @@ module Raven
168
183
  end
169
184
 
170
185
  def get_culprit(frames)
171
- lastframe = frames[-1]
186
+ lastframe = frames.reverse.detect { |f| f.in_app } || frames.last
172
187
  "#{lastframe.filename} in #{lastframe.function}" if lastframe
173
188
  end
174
189
 
@@ -31,6 +31,8 @@ module Raven
31
31
  evt = Event.capture_rack_exception(e, env)
32
32
  Raven.send(evt)
33
33
  raise
34
+ ensure
35
+ Raven.context.clear!
34
36
  end
35
37
 
36
38
  error = env['rack.exception'] || env['sinatra.error']
@@ -1,3 +1,3 @@
1
1
  module Raven
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-raven
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-29 00:00:00.000000000 Z
13
+ date: 2013-01-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: faraday