sqreen-kit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []