opencensus-jaeger 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +77 -0
- data/.gitignore +15 -0
- data/.gitmodules +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +36 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +6 -0
- data/CODEOWNERS +13 -0
- data/CODE_OF_CONDUCT.md +43 -0
- data/Gemfile +3 -0
- data/LICENSE +201 -0
- data/README.md +72 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/examples/.byebug_history +97 -0
- data/examples/Gemfile +9 -0
- data/examples/Gemfile.lock +46 -0
- data/examples/config.ru +15 -0
- data/examples/example.rb +25 -0
- data/lib/opencensus-jaeger.rb +4 -0
- data/lib/opencensus/jaeger.rb +12 -0
- data/lib/opencensus/jaeger/version.rb +5 -0
- data/lib/opencensus/logging.rb +24 -0
- data/lib/opencensus/trace/exporters/jaeger_driver.rb +125 -0
- data/lib/opencensus/trace/exporters/jaeger_driver/intermediate_transport.rb +25 -0
- data/lib/opencensus/trace/exporters/jaeger_driver/udp_sender.rb +28 -0
- data/lib/opencensus/trace/exporters/jaeger_driver/udp_transport.rb +43 -0
- data/lib/opencensus/trace/exporters/jaeger_exporter.rb +108 -0
- data/opencensus-jaeger.gemspec +45 -0
- data/scripts/publish.rb +7 -0
- data/scripts/rename_collectors.rb +88 -0
- data/thrift/agent.thrift +27 -0
- data/thrift/gen-rb/jaeger/thrift/agent.rb +117 -0
- data/thrift/gen-rb/jaeger/thrift/agent_constants.rb +13 -0
- data/thrift/gen-rb/jaeger/thrift/agent_types.rb +14 -0
- data/thrift/gen-rb/jaeger/thrift/collector.rb +82 -0
- data/thrift/gen-rb/jaeger/thrift/jaeger_constants.rb +13 -0
- data/thrift/gen-rb/jaeger/thrift/jaeger_types.rb +213 -0
- data/thrift/gen-rb/zipkin/zipkin_collector.rb +80 -0
- data/thrift/gen-rb/zipkin/zipkincore_constants.rb +43 -0
- data/thrift/gen-rb/zipkin/zipkincore_types.rb +223 -0
- data/thrift/jaeger.thrift +86 -0
- data/thrift/zipkincore.thrift +345 -0
- 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
|
data/scripts/publish.rb
ADDED
@@ -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
|
data/thrift/agent.thrift
ADDED
@@ -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
|