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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE +3 -0
- data/lib/sqreen-kit.rb +3 -0
- data/lib/sqreen.rb +1 -0
- data/lib/sqreen/kit.rb +76 -0
- data/lib/sqreen/kit/configuration.rb +67 -0
- data/lib/sqreen/kit/http_client.rb +160 -0
- data/lib/sqreen/kit/http_client/authentication_error.rb +13 -0
- data/lib/sqreen/kit/http_client/unexpected_status_error.rb +18 -0
- data/lib/sqreen/kit/loggable.rb +14 -0
- data/lib/sqreen/kit/retry_policy.rb +56 -0
- data/lib/sqreen/kit/signals/actor.rb +26 -0
- data/lib/sqreen/kit/signals/auth_signals_client.rb +45 -0
- data/lib/sqreen/kit/signals/batch_collector.rb +177 -0
- data/lib/sqreen/kit/signals/context/http_context.rb +139 -0
- data/lib/sqreen/kit/signals/dto_helper.rb +147 -0
- data/lib/sqreen/kit/signals/metric.rb +16 -0
- data/lib/sqreen/kit/signals/point.rb +16 -0
- data/lib/sqreen/kit/signals/signal.rb +28 -0
- data/lib/sqreen/kit/signals/signal_attributes.rb +104 -0
- data/lib/sqreen/kit/signals/signals_client.rb +33 -0
- data/lib/sqreen/kit/signals/stack_trace.rb +140 -0
- data/lib/sqreen/kit/signals/trace.rb +34 -0
- data/lib/sqreen/kit/string_sanitizer.rb +46 -0
- metadata +82 -0
@@ -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: []
|