splunk-tracer 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,10 @@
1
+ module SplunkTracing
2
+ module Transport
3
+ # Base Transport type
4
+ class Base
5
+ def report(_report)
6
+ nil
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ require 'splunktracing/transport/base'
2
+
3
+ module SplunkTracing
4
+ module Transport
5
+ class Callback < Base
6
+ def initialize(callback:)
7
+ @callback = callback
8
+ end
9
+
10
+ def report(report)
11
+ @callback.call(report)
12
+ nil
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,144 @@
1
+ require 'net/http'
2
+ require 'openssl'
3
+ require 'zlib'
4
+ require 'splunktracing/transport/base'
5
+
6
+ module SplunkTracing
7
+ module Transport
8
+ # HTTPJSON is a transport that sends reports via HTTP in JSON format.
9
+ # It is thread-safe.
10
+ class HTTPJSON < Base
11
+ SPLUNK_HEC_HOST = 'localhost'.freeze
12
+ SPLUNK_HEC_PORT = 8088
13
+
14
+ ENCRYPTION_TLS = 'tls'.freeze
15
+ ENCRYPTION_NONE = 'none'.freeze
16
+
17
+ REPORTS_API_ENDPOINT = '/services/collector'.freeze
18
+ HEADER_ACCESS_TOKEN = 'Authorization'.freeze
19
+
20
+ ##
21
+ # Initialize the transport
22
+ #
23
+ # @param host [String] host of the domain to the endpoint to push data
24
+ # @param port [Numeric] port on which to connect
25
+ # @param verbose [Numeric] verbosity level. Right now 0-3 are supported
26
+ # @param encryption [ENCRYPTION_TLS, ENCRYPTION_NONE] kind of encryption to use
27
+ # @param access_token [String] access token for SplunkTracing server
28
+ # @param ssl_verify_peer [Boolean]
29
+ # @param open_timeout [Integer]
30
+ # @param read_timeout [Integer]
31
+ # @param continue_timeout [Integer]
32
+ # @param keep_alive_timeout [Integer]
33
+ # @param logger [Logger]
34
+ #
35
+ def initialize(
36
+ host: SPLUNK_HEC_HOST,
37
+ port: SPLUNK_HEC_PORT,
38
+ verbose: 0,
39
+ encryption: ENCRYPTION_TLS,
40
+ access_token:,
41
+ ssl_verify_peer: false,
42
+ open_timeout: 20,
43
+ read_timeout: 20,
44
+ continue_timeout: nil,
45
+ keep_alive_timeout: 2,
46
+ logger: nil
47
+ )
48
+ @host = host
49
+ @port = port
50
+ @verbose = verbose
51
+ @encryption = encryption
52
+ @ssl_verify_peer = ssl_verify_peer
53
+ @open_timeout = open_timeout.to_i
54
+ @read_timeout = read_timeout.to_i
55
+ @continue_timeout = continue_timeout
56
+ @keep_alive_timeout = keep_alive_timeout.to_i
57
+
58
+ raise Tracer::ConfigurationError, 'access_token must be a string' unless access_token.is_a?(String)
59
+ raise Tracer::ConfigurationError, 'access_token cannot be blank' if access_token.empty?
60
+ @access_token = access_token
61
+ @logger = logger || SplunkTracing.logger
62
+ end
63
+
64
+ ##
65
+ # Queue a report for sending
66
+ #
67
+ def report(report)
68
+ @logger.info report if @verbose >= 3
69
+
70
+ req = build_request(report)
71
+ res = connection.request(req)
72
+
73
+ @logger.info res.to_s if @verbose >= 3
74
+
75
+ nil
76
+ end
77
+
78
+ private
79
+
80
+ ##
81
+ # @param [String] report_string
82
+ # @return [Net::HTTP::Post]
83
+ #
84
+ def build_request(report)
85
+ gzip = Zlib::GzipWriter.new(StringIO.new)
86
+ gzip << convert_report_data(report)
87
+ req = Net::HTTP::Post.new(REPORTS_API_ENDPOINT)
88
+ req[HEADER_ACCESS_TOKEN] = 'Splunk ' + @access_token
89
+ req['Content-Type'] = 'application/json'
90
+ req['Content-Encoding'] = 'gzip'
91
+ req['Connection'] = 'keep-alive'
92
+ req.body = gzip.close.string
93
+ req
94
+ end
95
+
96
+ ##
97
+ # @param [Hash] report
98
+ # @return [String] report_string
99
+ #
100
+ def convert_report_data(report)
101
+ report_obj_array = Array.new
102
+ runtime_hash = report[:runtime]
103
+
104
+ if report[:span_records].any?
105
+ report[:span_records].each do |span|
106
+ span_hash = {:time => span[:timestamp], :sourcetype => "splunktracing:span" }
107
+ span_contents = span.merge(runtime_hash)
108
+ log_array = span_contents.delete(:log_records)
109
+ runtime_attrs = span_contents.delete(:attrs)
110
+ span_contents[:tags].merge(runtime_attrs)
111
+ span_hash["event"] = span_contents
112
+ report_obj_array.push(span_hash.to_json)
113
+ if log_array && log_array.any?
114
+ span_contents.delete(:timestamp)
115
+ span_contents.delete(:duration)
116
+ log_array.each do |log|
117
+ log_hash = {:time => log[:timestamp_micros]/1000000.0, :sourcetype => "splunktracing:log" , :event => log.merge(span_contents)}
118
+ report_obj_array.push(log_hash.to_json)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ report_string = report_obj_array.join("\n")
124
+ report_string
125
+ end
126
+
127
+ ##
128
+ # @return [Net::HTTP]
129
+ #
130
+ def connection
131
+ unless @connection
132
+ @connection = ::Net::HTTP.new(@host, @port)
133
+ @connection.use_ssl = @encryption == ENCRYPTION_TLS
134
+ @connection.verify_mode = ::OpenSSL::SSL::VERIFY_NONE unless @ssl_verify_peer
135
+ @connection.open_timeout = @open_timeout
136
+ @connection.read_timeout = @read_timeout
137
+ @connection.continue_timeout = @continue_timeout
138
+ @connection.keep_alive_timeout = @keep_alive_timeout
139
+ end
140
+ @connection
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,9 @@
1
+ require 'splunktracing/transport/base'
2
+
3
+ module SplunkTracing
4
+ module Transport
5
+ # Empty transport, primarily for unit testing purposes
6
+ class Nil < Base
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module SplunkTracing
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,5 @@
1
+ lib = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'splunktracing/version'
4
+
5
+ print SplunkTracing::VERSION
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'splunktracing/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'splunk-tracer'
8
+ spec.version = SplunkTracing::VERSION
9
+ spec.authors = ['splunk']
10
+ spec.email = ['support@splunk.com']
11
+
12
+ spec.summary = 'Splunk OpenTracing Ruby bindings'
13
+ spec.homepage = 'https://github.com/splnkit/splunk-tracer-ruby'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ['lib']
18
+
19
+ spec.metadata = {
20
+ "changelog_uri" => "https://github.com/splnkit/splunk-tracer-ruby/blob/master/CHANGELOG.md",
21
+ }
22
+
23
+ spec.add_dependency 'concurrent-ruby', '~> 1.0'
24
+ spec.add_dependency 'opentracing', '~> 0.4.1'
25
+ spec.add_development_dependency 'rake', '~> 11.3'
26
+ spec.add_development_dependency 'rack', '~> 2.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.0'
28
+ spec.add_development_dependency 'bump', '~> 0.5'
29
+ spec.add_development_dependency 'simplecov', '~> 0.16'
30
+ spec.add_development_dependency 'timecop', '~> 0.8.0'
31
+ end
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: splunk-tracer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - splunk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-10-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: concurrent-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: opentracing
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.4.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '11.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '11.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bump
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.5'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.16'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.16'
111
+ - !ruby/object:Gem::Dependency
112
+ name: timecop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.8.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.8.0
125
+ description:
126
+ email:
127
+ - support@splunk.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".circleci/config.yml"
133
+ - ".gitignore"
134
+ - ".rspec"
135
+ - ".rubocop.yml"
136
+ - CHANGELOG.md
137
+ - Gemfile
138
+ - Gemfile.lock
139
+ - LICENSE.txt
140
+ - Makefile
141
+ - README.md
142
+ - Rakefile
143
+ - benchmark.rb
144
+ - benchmark/bench.rb
145
+ - benchmark/threading/thread_test.rb
146
+ - bin/console
147
+ - bin/setup
148
+ - circle.yml
149
+ - example.rb
150
+ - examples/fork_children/main.rb
151
+ - examples/rack/hello.rb
152
+ - examples/rack/inject_extract.rb
153
+ - lib/splunktracing.rb
154
+ - lib/splunktracing/global_tracer.rb
155
+ - lib/splunktracing/reporter.rb
156
+ - lib/splunktracing/scope.rb
157
+ - lib/splunktracing/scope_manager.rb
158
+ - lib/splunktracing/span.rb
159
+ - lib/splunktracing/span_context.rb
160
+ - lib/splunktracing/tracer.rb
161
+ - lib/splunktracing/transport/base.rb
162
+ - lib/splunktracing/transport/callback.rb
163
+ - lib/splunktracing/transport/http_json.rb
164
+ - lib/splunktracing/transport/nil.rb
165
+ - lib/splunktracing/version.rb
166
+ - scripts/version.rb
167
+ - splunktracing.gemspec
168
+ homepage: https://github.com/splnkit/splunk-tracer-ruby
169
+ licenses:
170
+ - MIT
171
+ metadata:
172
+ changelog_uri: https://github.com/splnkit/splunk-tracer-ruby/blob/master/CHANGELOG.md
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ required_rubygems_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ requirements: []
188
+ rubyforge_project:
189
+ rubygems_version: 2.6.13
190
+ signing_key:
191
+ specification_version: 4
192
+ summary: Splunk OpenTracing Ruby bindings
193
+ test_files: []