opencensus-jaeger 0.2.1

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