opencensus-jaeger 0.2.1

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +77 -0
  3. data/.gitignore +15 -0
  4. data/.gitmodules +3 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +36 -0
  7. data/.travis.yml +7 -0
  8. data/CHANGELOG.md +6 -0
  9. data/CODEOWNERS +13 -0
  10. data/CODE_OF_CONDUCT.md +43 -0
  11. data/Gemfile +3 -0
  12. data/LICENSE +201 -0
  13. data/README.md +72 -0
  14. data/Rakefile +6 -0
  15. data/bin/console +14 -0
  16. data/bin/setup +8 -0
  17. data/examples/.byebug_history +97 -0
  18. data/examples/Gemfile +9 -0
  19. data/examples/Gemfile.lock +46 -0
  20. data/examples/config.ru +15 -0
  21. data/examples/example.rb +25 -0
  22. data/lib/opencensus-jaeger.rb +4 -0
  23. data/lib/opencensus/jaeger.rb +12 -0
  24. data/lib/opencensus/jaeger/version.rb +5 -0
  25. data/lib/opencensus/logging.rb +24 -0
  26. data/lib/opencensus/trace/exporters/jaeger_driver.rb +125 -0
  27. data/lib/opencensus/trace/exporters/jaeger_driver/intermediate_transport.rb +25 -0
  28. data/lib/opencensus/trace/exporters/jaeger_driver/udp_sender.rb +28 -0
  29. data/lib/opencensus/trace/exporters/jaeger_driver/udp_transport.rb +43 -0
  30. data/lib/opencensus/trace/exporters/jaeger_exporter.rb +108 -0
  31. data/opencensus-jaeger.gemspec +45 -0
  32. data/scripts/publish.rb +7 -0
  33. data/scripts/rename_collectors.rb +88 -0
  34. data/thrift/agent.thrift +27 -0
  35. data/thrift/gen-rb/jaeger/thrift/agent.rb +117 -0
  36. data/thrift/gen-rb/jaeger/thrift/agent_constants.rb +13 -0
  37. data/thrift/gen-rb/jaeger/thrift/agent_types.rb +14 -0
  38. data/thrift/gen-rb/jaeger/thrift/collector.rb +82 -0
  39. data/thrift/gen-rb/jaeger/thrift/jaeger_constants.rb +13 -0
  40. data/thrift/gen-rb/jaeger/thrift/jaeger_types.rb +213 -0
  41. data/thrift/gen-rb/zipkin/zipkin_collector.rb +80 -0
  42. data/thrift/gen-rb/zipkin/zipkincore_constants.rb +43 -0
  43. data/thrift/gen-rb/zipkin/zipkincore_types.rb +223 -0
  44. data/thrift/jaeger.thrift +86 -0
  45. data/thrift/zipkincore.thrift +345 -0
  46. metadata +161 -0
@@ -0,0 +1,43 @@
1
+ module OpenCensus
2
+ module Trace
3
+ module Exporters
4
+ module JaegerDriver
5
+ class UDPTransport
6
+ FLAGS = 0
7
+
8
+ def initialize(host, port, logger)
9
+ @socket = UDPSocket.new
10
+ @host = host
11
+ @port = port
12
+ @logger = logger
13
+ @buffer = ::Thrift::MemoryBufferTransport.new
14
+ end
15
+
16
+ def write(str)
17
+ @buffer.write(str)
18
+ end
19
+
20
+ def flush
21
+ data = @buffer.read(@buffer.available)
22
+ send_bytes(data)
23
+ end
24
+
25
+ def open; end
26
+
27
+ def close; end
28
+
29
+ private
30
+
31
+ def send_bytes(bytes)
32
+ @socket.send(bytes, FLAGS, @host, @port)
33
+ @socket.flush
34
+ rescue Errno::ECONNREFUSED
35
+ @logger.warn 'Unable to connect to Jaeger Agent'
36
+ rescue StandardError => e
37
+ @logger.warn "Unable to send spans: #{e.class}-#{e.message}"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,108 @@
1
+ require 'opencensus/trace/exporters/jaeger_driver'
2
+
3
+ module OpenCensus
4
+ module Trace
5
+ module Exporters
6
+ class JaegerExporter
7
+ include ::Logging
8
+ JAEGER_OPENCENSUS_EXPORTER_VERSION_TAG_KEY = 'opencensus.exporter.jaeger.version'.freeze
9
+ TRACER_HOSTNAME_TAG_KEY = 'opencensus.exporter.jaeger.hostname'.freeze
10
+ PROCESS_IP = 'ip'.freeze
11
+ DEFAULT_MAX_LENGTH = 65_000 # Jaeger agent only accepts up to 65_000
12
+
13
+ attr_reader :client, :span_batches
14
+
15
+ def initialize(
16
+ logger: default_logger,
17
+ service_name: 'UNCONFIGURED_SERVICE_NAME',
18
+ host: 'localhost',
19
+ port: 6831,
20
+ tags: {},
21
+ max_packet_length: DEFAULT_MAX_LENGTH,
22
+ protocol_class: ::Thrift::CompactProtocol
23
+ )
24
+ @logger = logger
25
+ @service_name = service_name
26
+ @host = host
27
+ @port = port
28
+
29
+ default_tags = {}
30
+ default_tags[JAEGER_OPENCENSUS_EXPORTER_VERSION_TAG_KEY] = \
31
+ "opencensus-exporter-jaeger-#{OpenCensus::Jaeger::VERSION}"
32
+ default_tags[TRACER_HOSTNAME_TAG_KEY] = Socket.gethostname
33
+ default_tags[PROCESS_IP] = JaegerDriver.ip_v4
34
+ @tags = default_tags.merge(tags)
35
+ @client = JaegerDriver::UDPSender.new(host, port, logger, protocol_class)
36
+ @process = ::Jaeger::Thrift::Process.new(
37
+ 'serviceName': @service_name,
38
+ 'tags': JaegerDriver.build_thrift_tags(@tags)
39
+ )
40
+ @protocol_class = protocol_class
41
+ @max_span_size = max_packet_length - process_size - 8 - 20 # 8 is UDP header , 20 is IP header
42
+ end
43
+
44
+ def export(spans)
45
+ return nil if spans.nil? || spans.empty?
46
+ export_as_batch(spans)
47
+ rescue StandardError => e
48
+ @logger.error("Fail to export spans due to #{e.message}")
49
+ end
50
+
51
+ def export_as_batch(spans)
52
+ @span_batches = encode_within_limit(spans)
53
+ @span_batches.each do |span_batch|
54
+ @client.send_spans(span_batch)
55
+ end
56
+ end
57
+
58
+ def encode_within_limit(spans)
59
+ batches = []
60
+ current_batch = []
61
+ transport.flush
62
+
63
+ spans.each do |span|
64
+ encoded_span = JaegerDriver.encode_span(span)
65
+ if aggregated_span_size(encoded_span) >= @max_span_size && !current_batch.empty?
66
+ batches << encode_batch(current_batch)
67
+ current_batch = []
68
+ transport.flush
69
+ end
70
+ current_batch << encoded_span
71
+ end
72
+
73
+ batches << encode_batch(current_batch) unless current_batch.empty?
74
+ batches
75
+ end
76
+
77
+ def encode_batch(encoded_spans)
78
+ ::Jaeger::Thrift::Batch.new(
79
+ 'process' => @process,
80
+ 'spans' => encoded_spans
81
+ )
82
+ end
83
+
84
+ private
85
+
86
+ def aggregated_span_size(span)
87
+ # https://github.com/apache/thrift/blob/master/lib/rb/lib/thrift/struct.rb#L95
88
+ span.write(protocol)
89
+ transport.size
90
+ end
91
+
92
+ def process_size
93
+ return @process_size if @process_size
94
+ @process.write(protocol)
95
+ @process_size = transport.size
96
+ end
97
+
98
+ def transport
99
+ @transport ||= JaegerDriver::IntermediateTransport.new
100
+ end
101
+
102
+ def protocol
103
+ @protocol ||= @protocol_class.new(transport)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'opencensus/jaeger/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'opencensus-jaeger'
8
+ spec.version = OpenCensus::Jaeger::VERSION
9
+ spec.authors = ["Luong Vo"]
10
+ spec.email = ["vo.tran.thanh.luong@gmail.com"]
11
+
12
+ spec.summary = %q{Jaeger exporter for OpenCensus}
13
+ spec.description = %q{Jaeger exporter for OpenCensus}
14
+ spec.homepage = "https://www.github.com/Thinkei/opencensus-ruby-exporter-jaeger"
15
+ spec.license = "Apache-2.0"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
21
+ #
22
+ spec.metadata["homepage_uri"] = spec.homepage
23
+ spec.metadata["source_code_uri"] = spec.homepage
24
+ spec.metadata["changelog_uri"] = 'https://github.com/Thinkei/opencensus-ruby-exporter-jaeger/blob/master/CHANGELOG.md'
25
+ # else
26
+ # raise "RubyGems 2.0 or newer is required to protect against " \
27
+ # "public gem pushes."
28
+ end
29
+
30
+ # Specify which files should be added to the gem when it is released.
31
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
33
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
+ end
35
+ spec.bindir = "exe"
36
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
+ spec.require_paths = ["lib"]
38
+
39
+ spec.add_dependency "opencensus", "~> 0.4.0"
40
+ spec.add_dependency "thrift", "~> 0.11.0"
41
+
42
+ spec.add_development_dependency "rake", "~> 10.0"
43
+ spec.add_development_dependency "rspec", "~> 3.0"
44
+ spec.add_development_dependency "pry-byebug"
45
+ end
@@ -0,0 +1,7 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'opencensus/jaeger/version'
4
+
5
+ version = OpenCensus::Jaeger::VERSION
6
+
7
+ exec("gem build opencensus-jaeger.gemspec && curl -F package=@opencensus-jaeger-#{version}.gem https://#{ENV['GEMFURY_TOKEN']}@push.fury.io/#{ENV['GEMFURY_PACKAGE']}/")
@@ -0,0 +1,88 @@
1
+ require 'parser/current'
2
+ require 'byebug'
3
+ require 'fileutils'
4
+
5
+ class CollectorRewrite < Parser::Rewriter
6
+ def on_class(node)
7
+ klass = node.children.first
8
+ range = Parser::Source::Range.new(
9
+ klass.loc.expression,
10
+ klass.loc.expression.begin_pos,
11
+ klass.loc.expression.end_pos
12
+ )
13
+ replace(range, klass.children.last.to_s)
14
+
15
+ range = Parser::Source::Range.new(
16
+ node.loc.expression,
17
+ node.loc.expression.begin_pos,
18
+ node.loc.expression.end_pos
19
+ )
20
+
21
+ wrap(range, "module ::EhMonitoring::Collectors\n", "\nend")
22
+ end
23
+ end
24
+
25
+ class CollectorMigration < Parser::Rewriter
26
+ def on_const(node)
27
+ if node.children.last.to_s =~ /.*Collector$/ && node.children[-2].to_s != ~ /Collectors/
28
+ range = Parser::Source::Range.new(
29
+ node.loc.expression,
30
+ node.loc.expression.begin_pos,
31
+ node.loc.expression.end_pos
32
+ )
33
+ replace(range, "EhMonitoring::Collectors::#{node.children.last}")
34
+ end
35
+ end
36
+
37
+ def on_send(node)
38
+ if node.children[1] == :require
39
+ file = node.children.last
40
+ file_link = file.children.first
41
+ if file_link =~ /collector$/ && file_link != ~ /collectors/
42
+ range = Parser::Source::Range.new(
43
+ file.loc.expression,
44
+ file.loc.expression.begin_pos,
45
+ file.loc.expression.end_pos
46
+ )
47
+ files = file_link.split "/"
48
+ replace(range, "\"#{files.insert(files.length - 1, "collectors").join("/")}\"")
49
+ end
50
+ elsif node.children[2]&.type == :const
51
+ on_const(node.children[2])
52
+ end
53
+ end
54
+ end
55
+
56
+ FileUtils.mkdir_p("lib/eh_monitoring/collectors")
57
+ FileUtils.mkdir_p("spec/units/eh_monitoring/collectors")
58
+
59
+ Dir["lib/**/*_collector.rb"].each do |file|
60
+ buffer = Parser::Source::Buffer.new("(Migration)")
61
+ buffer.source = File.read(file)
62
+ ast = Parser::CurrentRuby.new.parse(buffer)
63
+ rewriter = CollectorRewrite.new
64
+ content = rewriter.rewrite(buffer, ast)
65
+ lines = content.split("\n")
66
+ lines.each_with_index do |line, index|
67
+ next if index == 0 || index == lines.length - 1
68
+ lines[index] = " #{line}"
69
+ end
70
+ content = lines.join("\n")
71
+ File.write("lib/eh_monitoring/collectors/#{file.split("/").last}", content)
72
+ File.delete(file)
73
+ end
74
+
75
+ Dir["spec/units/eh_monitoring/*_collector_spec.rb"].each do |file|
76
+ File.write("spec/units/eh_monitoring/collectors/#{file.split("/").last}", File.read(file))
77
+ File.delete(file)
78
+ end
79
+
80
+ file = "spec/units/eh_monitoring/instance_spec.rb"
81
+ Dir["**/*.rb"].each do |file|
82
+ buffer = Parser::Source::Buffer.new("(Migration)")
83
+ buffer.source = File.read(file)
84
+ ast = Parser::CurrentRuby.new.parse(buffer)
85
+ rewriter = CollectorMigration.new
86
+ content = rewriter.rewrite(buffer, ast)
87
+ File.write(file, content)
88
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2016 Uber Technologies, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ include "jaeger.thrift"
16
+ include "zipkincore.thrift"
17
+
18
+ namespace cpp jaegertracing.agent.thrift
19
+ namespace java io.jaegertracing.agent.thrift
20
+ namespace php Jaeger.Thrift.Agent
21
+ namespace netcore Jaeger.Thrift.Agent
22
+ namespace rb Jaeger.Thrift
23
+
24
+ service Agent {
25
+ oneway void emitZipkinBatch(1: list<zipkincore.Span> spans)
26
+ oneway void emitBatch(1: jaeger.Batch batch)
27
+ }
@@ -0,0 +1,117 @@
1
+ #
2
+ # Autogenerated by Thrift Compiler (0.11.0)
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+ require 'thrift'
8
+ require 'jaeger/thrift/agent_types'
9
+
10
+ module Jaeger
11
+ module Thrift
12
+ module Agent
13
+ class Client
14
+ include ::Thrift::Client
15
+
16
+ def emitZipkinBatch(spans)
17
+ send_emitZipkinBatch(spans)
18
+ end
19
+
20
+ def send_emitZipkinBatch(spans)
21
+ send_oneway_message('emitZipkinBatch', EmitZipkinBatch_args, :spans => spans)
22
+ end
23
+
24
+ def emitBatch(batch)
25
+ send_emitBatch(batch)
26
+ end
27
+
28
+ def send_emitBatch(batch)
29
+ send_oneway_message('emitBatch', EmitBatch_args, :batch => batch)
30
+ end
31
+ end
32
+
33
+ class Processor
34
+ include ::Thrift::Processor
35
+
36
+ def process_emitZipkinBatch(seqid, iprot, oprot)
37
+ args = read_args(iprot, EmitZipkinBatch_args)
38
+ @handler.emitZipkinBatch(args.spans)
39
+ return
40
+ end
41
+
42
+ def process_emitBatch(seqid, iprot, oprot)
43
+ args = read_args(iprot, EmitBatch_args)
44
+ @handler.emitBatch(args.batch)
45
+ return
46
+ end
47
+
48
+ end
49
+
50
+ # HELPER FUNCTIONS AND STRUCTURES
51
+
52
+ class EmitZipkinBatch_args
53
+ include ::Thrift::Struct, ::Thrift::Struct_Union
54
+ SPANS = 1
55
+
56
+ FIELDS = {
57
+ SPANS => {:type => ::Thrift::Types::LIST, :name => 'spans', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Zipkin::Span}}
58
+ }
59
+
60
+ def struct_fields; FIELDS; end
61
+
62
+ def validate
63
+ end
64
+
65
+ ::Thrift::Struct.generate_accessors self
66
+ end
67
+
68
+ class EmitZipkinBatch_result
69
+ include ::Thrift::Struct, ::Thrift::Struct_Union
70
+
71
+ FIELDS = {
72
+
73
+ }
74
+
75
+ def struct_fields; FIELDS; end
76
+
77
+ def validate
78
+ end
79
+
80
+ ::Thrift::Struct.generate_accessors self
81
+ end
82
+
83
+ class EmitBatch_args
84
+ include ::Thrift::Struct, ::Thrift::Struct_Union
85
+ BATCH = 1
86
+
87
+ FIELDS = {
88
+ BATCH => {:type => ::Thrift::Types::STRUCT, :name => 'batch', :class => ::Jaeger::Thrift::Batch}
89
+ }
90
+
91
+ def struct_fields; FIELDS; end
92
+
93
+ def validate
94
+ end
95
+
96
+ ::Thrift::Struct.generate_accessors self
97
+ end
98
+
99
+ class EmitBatch_result
100
+ include ::Thrift::Struct, ::Thrift::Struct_Union
101
+
102
+ FIELDS = {
103
+
104
+ }
105
+
106
+ def struct_fields; FIELDS; end
107
+
108
+ def validate
109
+ end
110
+
111
+ ::Thrift::Struct.generate_accessors self
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,13 @@
1
+ #
2
+ # Autogenerated by Thrift Compiler (0.11.0)
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+ require 'thrift'
8
+ require 'jaeger/thrift/agent_types'
9
+
10
+ module Jaeger
11
+ module Thrift
12
+ end
13
+ end