sqreen-kit 0.1.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.
@@ -0,0 +1,16 @@
1
+ require 'sqreen/kit/signals/dto_helper'
2
+ require 'sqreen/kit/signals/signal'
3
+
4
+ # reference: https://github.com/sqreen/SignalsSchemas/blob/master/schemas/signals.cue
5
+
6
+ module Sqreen
7
+ module Kit
8
+ module Signals
9
+ class Metric < Signal
10
+ def type
11
+ 'metric'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'sqreen/kit/signals/dto_helper'
2
+ require 'sqreen/kit/signals/signal'
3
+
4
+ # reference: https://github.com/sqreen/SignalsSchemas/blob/master/schemas/signals.cue
5
+
6
+ module Sqreen
7
+ module Kit
8
+ module Signals
9
+ class Point < Signal
10
+ def type
11
+ 'point'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ require 'sqreen/kit/signals/dto_helper'
2
+ require 'sqreen/kit/signals/signal_attributes'
3
+
4
+ # reference: https://github.com/sqreen/SignalsSchemas/blob/master/schemas/signals.cue
5
+
6
+ module Sqreen
7
+ module Kit
8
+ module Signals
9
+ # Not to be used directly. See Metric and Point
10
+ class Signal
11
+ include SignalAttributes
12
+
13
+ add_mandatory_attrs :signal_name, :payload
14
+
15
+ # mandatory
16
+ # @return [String]
17
+ attr_accessor :signal_name
18
+
19
+ # @return [String]
20
+ attr_accessor :payload_schema
21
+
22
+ # mandatory
23
+ # @return [Object]
24
+ attr_accessor :payload
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,104 @@
1
+ require 'sqreen/kit/signals/dto_helper'
2
+ require 'sqreen/kit/signals/stack_trace'
3
+ require 'sqreen/kit/signals/actor'
4
+
5
+ # reference: https://github.com/sqreen/SignalsSchemas/blob/master/schemas/signals.cue
6
+
7
+ module Sqreen
8
+ module Kit
9
+ module Signals
10
+ module SignalAttributes
11
+ include DtoHelper
12
+
13
+ # @param [Time]
14
+ # @return [String]
15
+ attr_accessor_time :time
16
+
17
+ def type
18
+ raise NotImplementedError
19
+ end
20
+
21
+ # @return [Actor]
22
+ attr_accessor :actor
23
+
24
+ # @return [String]
25
+ attr_accessor :context_schema
26
+
27
+ # @return [Object] specified by context schema
28
+ attr_accessor :context
29
+
30
+ # @return [Location]
31
+ attr_accessor :location
32
+
33
+ # @return [LocationInfra]
34
+ attr_accessor :location_infra
35
+
36
+ # @return [String]
37
+ attr_accessor :source
38
+
39
+ # @return [Hash{String=>Object}]
40
+ attr_accessor :trigger
41
+
42
+ def to_h
43
+ {
44
+ type: type,
45
+ }.merge(super())
46
+ end
47
+ end
48
+
49
+ class Location
50
+ include DtoHelper
51
+
52
+ # @param [Array<String>]
53
+ attr_writer :stack_trace
54
+
55
+ # @param [Exception] e
56
+ attr_writer :exception
57
+
58
+ def stack_trace
59
+ if @exception
60
+ Sqreen::Kit::StackTrace.parse(@exception)
61
+ elsif @stack_trace
62
+ Sqreen::Kit::StackTrace.parse_backtrace(@stack_trace)
63
+ else
64
+ raise 'Neither exception not stack_trace set'
65
+ end
66
+ end
67
+ end
68
+
69
+ class LocationInfra
70
+ include DtoHelper
71
+
72
+ add_mandatory_attrs :agent_version, :os_type, :hostname, :runtime_version
73
+
74
+ # mandatory
75
+ # @return [String]
76
+ attr_accessor :agent_version
77
+
78
+ # mandatory
79
+ # @return [String]
80
+ attr_accessor :os_type
81
+
82
+ # mandatory
83
+ # @return [String]
84
+ attr_accessor :hostname
85
+
86
+ # @return [String]
87
+ attr_accessor :runtime_type
88
+
89
+ # mandatory
90
+ # @return [String]
91
+ attr_accessor :runtime_version
92
+
93
+ # @return [String]
94
+ attr_accessor :libsqreen_version
95
+
96
+ def to_h
97
+ {
98
+ agent_type: 'ruby',
99
+ }.merge(super())
100
+ end
101
+ end
102
+ end # module Signals
103
+ end
104
+ end
@@ -0,0 +1,33 @@
1
+ require 'sqreen/kit/http_client'
2
+
3
+ module Sqreen
4
+ module Kit
5
+ module Signals
6
+ class SignalsClient
7
+ STATIC_HEADERS = { 'Content-type' => 'application/json' }.freeze
8
+
9
+ # @param http_client [Sqreen::Kit:HttpClient]
10
+ def initialize(http_client)
11
+ @http_client = http_client
12
+ end
13
+
14
+ # @param [Array] signals_and_traces
15
+ # @param headers [Hash{String=>String}]
16
+ def report_batch(signals_and_traces, headers)
17
+ data = '[' + signals_and_traces.map(&:to_json).join(',') + ']'
18
+ @http_client.post('batches', data, STATIC_HEADERS.merge(headers))
19
+ end
20
+
21
+ def report_signal(signal, headers)
22
+ data = signal.to_json
23
+ @http_client.post('signals', data, STATIC_HEADERS.merge(headers))
24
+ end
25
+
26
+ def report_trace(trace, headers)
27
+ data = trace.to_json
28
+ @http_client.post('traces', data, STATIC_HEADERS.merge(headers))
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,140 @@
1
+ # Includes code from Airbrake Technologies, Inc., under the MIT licence
2
+ # see https://github.com/airbrake/airbrake-ruby/blob/c172657dcd4eeaf62ea23f0f7d6111be2373ea59/LICENSE.md
3
+
4
+ require 'sqreen/kit/loggable'
5
+
6
+ module Sqreen
7
+ module Kit
8
+ module StackTrace
9
+ end
10
+ end
11
+ end
12
+
13
+ class << Sqreen::Kit::StackTrace
14
+ module Patterns
15
+ # @return [Regexp] the pattern that matches standard Ruby stack frames,
16
+ # such as ./spec/notice_spec.rb:43:in `block (3 levels) in <top (required)>'
17
+ RUBY = %r{\A
18
+ (?<file>.+) # Matches './spec/notice_spec.rb'
19
+ :
20
+ (?<line>\d+) # Matches '43'
21
+ :in\s
22
+ `(?<function>.*)' # Matches "`block (3 levels) in <top (required)>'"
23
+ \z}x
24
+
25
+ # @return [Regexp] the pattern that matches JRuby Java stack frames, such
26
+ # as org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
27
+ JAVA = %r{\A
28
+ (?<function>.+) # Matches 'org.jruby.ast.NewlineNode.interpret'
29
+ \(
30
+ (?<file>
31
+ (?:uri:classloader:/.+(?=:)) # Matches '/META-INF/jruby.home/protocol.rb'
32
+ |
33
+ (?:uri_3a_classloader_3a_.+(?=:)) # Matches 'uri_3a_classloader_3a_/gems/...'
34
+ |
35
+ [^:]+ # Matches 'NewlineNode.java'
36
+ )
37
+ :?
38
+ (?<line>\d+)? # Matches '105'
39
+ \)
40
+ \z}x
41
+
42
+ # @return [Regexp] the pattern that tries to assume what a generic stack
43
+ # frame might look like, when exception's backtrace is set manually.
44
+ GENERIC = %r{\A
45
+ (?:from\s)?
46
+ (?<file>.+) # Matches '/foo/bar/baz.ext'
47
+ :
48
+ (?<line>\d+)? # Matches '43' or nothing
49
+ (?:
50
+ in\s`(?<function>.+)' # Matches "in `func'"
51
+ |
52
+ :in\s(?<function>.+) # Matches ":in func"
53
+ )? # ... or nothing
54
+ \z}x
55
+ end
56
+
57
+ include Sqreen::Kit::Loggable
58
+
59
+ # Parses an exception's backtrace.
60
+ #
61
+ # @param exception [Exception] The exception, which contains a backtrace to
62
+ # parse
63
+ # @return [Array<Hash{Symbol=>String,Integer}>] the parsed backtrace
64
+ def parse(exception)
65
+ return [] if exception.backtrace.nil? || exception.backtrace.none?
66
+ do_parse(exception)
67
+ end
68
+
69
+ def parse_backtrace(backtrace)
70
+ # assume normal ruby backtrace
71
+ backtrace.map do |stackframe|
72
+ stack_frame(Patterns::RUBY, stackframe)
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def do_parse(exception)
79
+ regexp = best_regexp_for(exception)
80
+
81
+ exception.backtrace.map do |stackframe|
82
+ stack_frame(regexp, stackframe)
83
+ end
84
+ end
85
+
86
+ def best_regexp_for(exception)
87
+ if java_exception?(exception)
88
+ Patterns::JAVA
89
+ else
90
+ Patterns::RUBY
91
+ end
92
+ end
93
+
94
+ # Checks whether the given exception was generated by JRuby's VM.
95
+ #
96
+ # @param [Exception] exception
97
+ # @return [Boolean]
98
+ def java_exception?(exception)
99
+ if defined?(Java::JavaLang::Throwable) &&
100
+ exception.is_a?(Java::JavaLang::Throwable)
101
+ return true
102
+ end
103
+
104
+ return false unless exception.respond_to?(:backtrace)
105
+
106
+ (Patterns::JAVA =~ exception.backtrace.first) != nil
107
+ end
108
+
109
+ def stack_frame(regexp, stackframe)
110
+ if (match = match_frame(regexp, stackframe))
111
+ return {
112
+ in_app: sqreen_code?(match[:file]),
113
+ abs_path: match[:file],
114
+ function: match[:function],
115
+ lineno: (Integer(match[:line]) if match[:line]),
116
+ }
117
+ end
118
+
119
+ logger.error(
120
+ "can't parse '#{stackframe}' (please file an issue so we can fix " \
121
+ 'it: https://github.com/sqreen/ruby-sdk/issues/new)',
122
+ )
123
+ {
124
+ in_app: false,
125
+ function: stackframe,
126
+ }
127
+ end
128
+
129
+ def sqreen_code?(abs_path)
130
+ # Ruby uses / on Windows too
131
+ abs_path.include?('/lib/sqreen/')
132
+ end
133
+
134
+ def match_frame(regexp, stackframe)
135
+ match = regexp.match(stackframe)
136
+ return match if match
137
+
138
+ Patterns::GENERIC.match(stackframe)
139
+ end
140
+ end
@@ -0,0 +1,34 @@
1
+ require 'sqreen/kit/signals/dto_helper'
2
+ require 'sqreen/kit/signals/signal'
3
+ require 'sqreen/kit/signals/signal_attributes'
4
+
5
+ # reference: https://github.com/sqreen/SignalsSchemas/blob/master/schemas/trace.cue
6
+
7
+ module Sqreen
8
+ module Kit
9
+ module Signals
10
+ class Trace
11
+ include SignalAttributes
12
+
13
+ def self.attributes_for_to_h_self
14
+ [] # we handle data ourselves
15
+ end
16
+
17
+ add_mandatory_attrs :data
18
+
19
+ # @return [Array<Signal>]
20
+ attr_accessor :data
21
+
22
+ def type
23
+ 'trace'
24
+ end
25
+
26
+ def to_h
27
+ super.merge({
28
+ data: data.map(&:to_h),
29
+ })
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,46 @@
1
+ module Sqreen
2
+ module Kit
3
+ module StringSanitizer
4
+ class << self
5
+ def sanitize(obj)
6
+ case obj
7
+ when String
8
+ sanitize_string(obj)
9
+ when Array
10
+ obj.map { |e| sanitize(e) }
11
+ when Hash
12
+ obj.each_with_object({}) { |(k, v), h| h[sanitize(k)] = sanitize(v) }
13
+ else
14
+ obj
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def sanitize_string_new(s)
21
+ return s if s.encoding == Encoding::UTF_8 && s.valid_encoding?
22
+
23
+ s.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
24
+ end
25
+
26
+ def sanitize_string_old(s)
27
+ return s if s.encoding == Encoding::UTF_8 && s.valid_encoding?
28
+
29
+ s.encode('utf-16be', invalid: :replace, undef: :replace)
30
+ .encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
31
+ end
32
+
33
+ repl_ok = "\x80".dup.force_encoding(Encoding::UTF_8)
34
+ .encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
35
+ .valid_encoding?
36
+ if repl_ok
37
+ alias_method :sanitize_string, :sanitize_string_new
38
+ else
39
+ # for Ruby < 2
40
+ alias_method :sanitize_string, :sanitize_string_old
41
+ end
42
+ public :sanitize_string
43
+ end
44
+ end
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sqreen-kit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Loic Nageleisen
8
+ - Gustavo Lopes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2020-06-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sqreen-backport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 0.1.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 0.1.0
28
+ description:
29
+ email:
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - CHANGELOG.md
35
+ - LICENSE
36
+ - lib/sqreen-kit.rb
37
+ - lib/sqreen.rb
38
+ - lib/sqreen/kit.rb
39
+ - lib/sqreen/kit/configuration.rb
40
+ - lib/sqreen/kit/http_client.rb
41
+ - lib/sqreen/kit/http_client/authentication_error.rb
42
+ - lib/sqreen/kit/http_client/unexpected_status_error.rb
43
+ - lib/sqreen/kit/loggable.rb
44
+ - lib/sqreen/kit/retry_policy.rb
45
+ - lib/sqreen/kit/signals/actor.rb
46
+ - lib/sqreen/kit/signals/auth_signals_client.rb
47
+ - lib/sqreen/kit/signals/batch_collector.rb
48
+ - lib/sqreen/kit/signals/context/http_context.rb
49
+ - lib/sqreen/kit/signals/dto_helper.rb
50
+ - lib/sqreen/kit/signals/metric.rb
51
+ - lib/sqreen/kit/signals/point.rb
52
+ - lib/sqreen/kit/signals/signal.rb
53
+ - lib/sqreen/kit/signals/signal_attributes.rb
54
+ - lib/sqreen/kit/signals/signals_client.rb
55
+ - lib/sqreen/kit/signals/stack_trace.rb
56
+ - lib/sqreen/kit/signals/trace.rb
57
+ - lib/sqreen/kit/string_sanitizer.rb
58
+ homepage: https://sqreen.com
59
+ licenses:
60
+ - Sqreen
61
+ metadata:
62
+ source_code_uri: https://github.com/sqreen/ruby-sdk
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 1.9.3
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubygems_version: 3.0.3
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Sqreen development kit for Ruby
82
+ test_files: []