epsagon 0.0.0 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 036b9458b78db168edb2cb90dd4898f812eaa81a3e057abd69fc073fef9552d2
4
- data.tar.gz: 1b2b2dce82f55073377db72400737a1243f8dab08426780d59f6a5faf62a2a13
3
+ metadata.gz: 71154f411911b4ef7b0c19e9b6b5a9c1bc490ac389ee928109d72375d87a2aff
4
+ data.tar.gz: e53b5278f2c8126888528f232e518e8b892b41fd7c026118c825bc19a222383f
5
5
  SHA512:
6
- metadata.gz: 5bbbc9237c61ad7eb0818803eea213ed8b1003210b199c3c29355f1536b6dc4b7e990b628b92b8c015f4fab1c623eb92f07352d6c6cb5b6a00d0aeb12aa0dfc8
7
- data.tar.gz: 81da4b0e55ecd53569564c22cfe1a986dce0835970bf3a522a7bc100e5b5a6c373275c6ac2bccd9d0a4500dddb8c26dca54d402d499116fa90201ba8de5edef5
6
+ metadata.gz: f7ac4b83a72c9a32f4f79cc9c708360bb78eee46598369329a6ee917a759dd1624ef434b6da632500aa33dde01256bf304515fc39002c5be52c300e29ff6759d
7
+ data.tar.gz: 3f4d4c862049148a6714bf12be7c2b5437fc60d5a355b97f50f1f686d4a4585e2812ff9f906ce6d70305d049f8f1d701fb412ee205f9589b0e71ee16db1f7466
data/lib/epsagon.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require 'rubygems'
4
4
  require 'net/http'
5
5
  require 'bundler/setup'
6
- require 'opentelemetry'
6
+ require 'opentelemetry/sdk'
7
7
 
8
8
  require_relative 'instrumentation/sinatra'
9
9
  require_relative 'instrumentation/net_http'
@@ -12,31 +12,67 @@ require_relative 'util'
12
12
 
13
13
  Bundler.require
14
14
 
15
- def metadata_only?
16
- ENV['EPSAGON_METADATA']&.to_s&.downcase != 'false'
17
- end
15
+ # Epsagon tracing main entry point
16
+ module Epsagon
17
+ @@epsagon_config = {
18
+ metadata_only: ENV['EPSAGON_METADATA']&.to_s&.downcase != 'false',
19
+ debug: ENV['EPSAGON_DEBUG']&.to_s&.downcase == 'true',
20
+ token: ENV['EPSAGON_TOKEN'],
21
+ app_name: ENV['EPSAGON_APP_NAME'],
22
+ backend: ENV['EPSAGON_BACKEND'] || 'localhost:55681/v1/trace'
23
+ }
18
24
 
19
- def debug?
20
- ENV['EPSAGON_DEBUG']&.to_s&.downcase == 'true'
21
- end
25
+ module_function
22
26
 
23
- # #config opentelemetry with epsaon extensions:
24
- OpenTelemetry::SDK.configure do |c|
25
- c.use 'EpsagonSinatraInstrumentation'
26
- c.use 'EpsagonNetHTTPInstrumentation'
27
- c.use 'EpsagonFaradayInstrumentation'
28
- if ENV['EPSAGON_BACKEND']
29
- c.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
30
- OpenTelemetry::Exporter::OTLP::Exporter.new(headers: {
31
- epasgon_token: ENV['EPSAGON_TOKEN'],
32
- epasgon_app_name: ENV['EPSAGON_APP_NAME']
33
- },
34
- endpoint: ENV['EPSAGON_BACKEND'],
35
- insecure: false)
36
- )
37
- else
38
- c.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
39
- OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
27
+ def init(**args)
28
+ @@epsagon_config.merge!(args)
29
+ OpenTelemetry::SDK.configure
30
+ end
31
+
32
+ # config opentelemetry with epsaon extensions:
33
+
34
+ def epsagon_confs(configurator)
35
+ configurator.resource = OpenTelemetry::SDK::Resources::Resource.telemetry_sdk.merge(
36
+ OpenTelemetry::SDK::Resources::Resource.create({ 'application' => @@epsagon_config[:app_name] })
40
37
  )
38
+ configurator.use 'EpsagonSinatraInstrumentation', { epsagon: @@epsagon_config }
39
+ configurator.use 'EpsagonNetHTTPInstrumentation', { epsagon: @@epsagon_config }
40
+ configurator.use 'EpsagonFaradayInstrumentation', { epsagon: @@epsagon_config }
41
+
42
+ if @@epsagon_config[:debug]
43
+ configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
44
+ OpenTelemetry::Exporter::OTLP::Exporter.new(headers: {
45
+ 'x-epsagon-token' => @@epsagon_config[:token]
46
+ },
47
+ endpoint: @@epsagon_config[:backend],
48
+ insecure: @@epsagon_config[:insecure] || false)
49
+ )
50
+
51
+ configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
52
+ OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
53
+ )
54
+ else
55
+ configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
56
+ exporter: OpenTelemetry::Exporter::OTLP::Exporter.new(headers: {
57
+ 'x-epsagon-token' => @@epsagon_config[:token]
58
+ },
59
+ endpoint: @@epsagon_config[:backend],
60
+ insecure: @@epsagon_config[:insecure] || false)
61
+ )
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ # monkey patch to include epsagon confs
68
+ module OpenTelemetry
69
+ # monkey patch inner SDK module
70
+ module SDK
71
+ def self.configure
72
+ super do |c|
73
+ yield c if block_given?
74
+ Epsagon.epsagon_confs c
75
+ end
76
+ end
41
77
  end
42
78
  end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../util'
4
+
5
+ # AWS SDK plugin for epsagon instrumentation
6
+ class EpsagonAwsPlugin < Seahorse::Client::Plugin
7
+ def add_handlers(handlers, _)
8
+ handlers.add(EpsagonAwsHandler, step: :validate)
9
+ end
10
+ end
11
+
12
+ # Generates Spans for all uses of AWS SDK
13
+ class EpsagonAwsHandler < Seahorse::Client::Handler
14
+ def call(context)
15
+ tracer.in_span('') do |span|
16
+ @handler.call(context).tap do
17
+ span.set_attribute('aws.operation', context[:command])
18
+ span.set_attribute('aws.status_code', context[:status_code])
19
+ span.set_attribute('aws.service', context[:service_name])
20
+ span.set_attribute('aws.account_id', context[:account_id])
21
+ span.set_attribute('aws.status_code', context[:status_code])
22
+ end
23
+ end
24
+ end
25
+
26
+ def tracer
27
+ EpsagonAwsSdkInstrumentation.instance.tracer
28
+ end
29
+ end
30
+
31
+ # AWS SDK epsagon instrumentation
32
+ class EpsagonAwsSdkInstrumentation < OpenTelemetry::Instrumentation::Base
33
+ VERSION = '0.0.0'
34
+ SERVICES = %w[
35
+ ACM
36
+ APIGateway
37
+ AppStream
38
+ ApplicationAutoScaling
39
+ ApplicationDiscoveryService
40
+ Athena
41
+ AutoScaling
42
+ Batch
43
+ Budgets
44
+ CloudDirectory
45
+ CloudFormation
46
+ CloudFront
47
+ CloudHSM
48
+ CloudHSMV2
49
+ CloudSearch
50
+ CloudSearchDomain
51
+ CloudTrail
52
+ CloudWatch
53
+ CloudWatchEvents
54
+ CloudWatchLogs
55
+ CodeBuild
56
+ CodeCommit
57
+ CodeDeploy
58
+ CodePipeline
59
+ CodeStar
60
+ CognitoIdentity
61
+ CognitoIdentityProvider
62
+ CognitoSync
63
+ ConfigService
64
+ CostandUsageReportService
65
+ DAX
66
+ DataPipeline
67
+ DatabaseMigrationService
68
+ DeviceFarm
69
+ DirectConnect
70
+ DirectoryService
71
+ DynamoDB
72
+ DynamoDBStreams
73
+ EC2
74
+ ECR
75
+ ECS
76
+ EFS
77
+ EMR
78
+ ElastiCache
79
+ ElasticBeanstalk
80
+ ElasticLoadBalancing
81
+ ElasticLoadBalancingV2
82
+ ElasticTranscoder
83
+ ElasticsearchService
84
+ EventBridge
85
+ Firehose
86
+ GameLift
87
+ Glacier
88
+ Glue
89
+ Greengrass
90
+ Health
91
+ IAM
92
+ ImportExport
93
+ Inspector
94
+ IoT
95
+ IoTDataPlane
96
+ KMS
97
+ Kinesis
98
+ KinesisAnalytics
99
+ Lambda
100
+ LambdaPreview
101
+ Lex
102
+ LexModelBuildingService
103
+ Lightsail
104
+ MTurk
105
+ MachineLearning
106
+ MarketplaceCommerceAnalytics
107
+ MarketplaceEntitlementService
108
+ MarketplaceMetering
109
+ MigrationHub
110
+ Mobile
111
+ OpsWorks
112
+ OpsWorksCM
113
+ Organizations
114
+ Pinpoint
115
+ Polly
116
+ RDS
117
+ Redshift
118
+ Rekognition
119
+ ResourceGroupsTaggingAPI
120
+ Route53
121
+ Route53Domains
122
+ S3
123
+ SES
124
+ SMS
125
+ SNS
126
+ SQS
127
+ SSM
128
+ STS
129
+ SWF
130
+ ServiceCatalog
131
+ Shield
132
+ SimpleDB
133
+ Snowball
134
+ States
135
+ StorageGateway
136
+ Support
137
+ Textract
138
+ WAF
139
+ WAFRegional
140
+ WorkDocs
141
+ WorkSpaces
142
+ XRay
143
+ ].freeze
144
+
145
+ install do |_|
146
+ ::Seahorse::Client::Base.add_plugin(EpsagonAwsPlugin)
147
+ loaded_constants.each { |klass| klass.add_plugin(EpsagonAwsPlugin) }
148
+ end
149
+
150
+ present do
151
+ defined?(::Seahorse::Client::Base)
152
+ end
153
+
154
+ private
155
+
156
+ def loaded_constants
157
+ # Cross-check services against loaded AWS constants
158
+ # Module#const_get can return a constant from ancestors when there's a miss.
159
+ # If this conincidentally matches another constant, it will attempt to patch
160
+ # the wrong constant, resulting in patch failure.
161
+ available_services = ::Aws.constants & SERVICES.map(&:to_sym)
162
+
163
+ available_services.each_with_object([]) do |service, constants|
164
+ next if ::Aws.autoload?(service)
165
+
166
+ begin
167
+ constants << ::Aws.const_get(service, false).const_get(:Client, false)
168
+ rescue StandardError
169
+ next
170
+ end
171
+ end
172
+ end
173
+ end
@@ -3,7 +3,12 @@
3
3
  require 'faraday'
4
4
  require_relative '../util'
5
5
 
6
+ # Faraday middleware for epsagon instrumentaton
6
7
  class EpsagonFaradayMiddleware < ::Faraday::Middleware
8
+ def config
9
+ EpsagonFaradayInstrumentation.instance.config
10
+ end
11
+
7
12
  HTTP_METHODS_SYMBOL_TO_STRING = {
8
13
  connect: 'CONNECT',
9
14
  delete: 'DELETE',
@@ -27,7 +32,7 @@ class EpsagonFaradayMiddleware < ::Faraday::Middleware
27
32
  'http.request.path' => path
28
33
  }
29
34
 
30
- unless metadata_only?
35
+ unless config[:epsagon][:metadata_only]
31
36
  attributes.merge!(Util.epsagon_query_attributes(env.url.query))
32
37
  attributes.merge!({
33
38
  'http.request.path_params' => path_params,
@@ -59,7 +64,7 @@ class EpsagonFaradayMiddleware < ::Faraday::Middleware
59
64
  def trace_response(span, response)
60
65
  span.set_attribute('http.status_code', response.status)
61
66
 
62
- unless metadata_only?
67
+ unless config[:epsagon][:metadata_only]
63
68
  span.set_attribute('http.response.headers', response.headers.to_json)
64
69
  span.set_attribute('http.response.body', response.body)
65
70
  end
@@ -69,6 +74,7 @@ class EpsagonFaradayMiddleware < ::Faraday::Middleware
69
74
  end
70
75
  end
71
76
 
77
+ # Patch faraday to include middleware
72
78
  module EpsagonFaradayPatch
73
79
  def adapter(*args)
74
80
  use(:epsagon_open_telemetry) unless @handlers.any? do |handler|
@@ -79,12 +85,15 @@ module EpsagonFaradayPatch
79
85
  end
80
86
  end
81
87
 
88
+ # Faraday epsagon instrumentaton
82
89
  class EpsagonFaradayInstrumentation < OpenTelemetry::Instrumentation::Base
90
+ VERSION = '0.0.0'
91
+
83
92
  install do |_config|
84
93
  ::Faraday::Middleware.register_middleware(
85
94
  epsagon_open_telemetry: EpsagonFaradayMiddleware
86
95
  )
87
- ::Faraday::RackBuilder.prepend(EpsagonFaradayPatch)
96
+ ::Faraday::RackBuilder.include(EpsagonFaradayPatch)
88
97
  end
89
98
 
90
99
  present do
@@ -4,10 +4,15 @@ require 'opentelemetry'
4
4
 
5
5
  require_relative '../util'
6
6
 
7
+ # Net::HTTP patch for epsagon instrumentaton
7
8
  module EpsagonNetHTTPExtension
8
9
  HTTP_METHODS_TO_SPAN_NAMES = Hash.new { |h, k| h[k] = "HTTP #{k}" }
9
10
  USE_SSL_TO_SCHEME = { false => 'http', true => 'https' }.freeze
10
11
 
12
+ def config
13
+ EpsagonNetHTTPInstrumentation.instance.config
14
+ end
15
+
11
16
  def request(req, body = nil, &block)
12
17
  # Do not trace recursive call for starting the connection
13
18
  return super(req, body, &block) unless started?
@@ -22,7 +27,7 @@ module EpsagonNetHTTPExtension
22
27
  'http.request.path' => path
23
28
  })
24
29
 
25
- unless metadata_only?
30
+ unless config[:epsagon][:metadata_only]
26
31
  headers = Hash[req.each_header.to_a]
27
32
  attributes.merge!({
28
33
  'http.request.path_params' => path_params,
@@ -53,7 +58,7 @@ module EpsagonNetHTTPExtension
53
58
  status_code = response.code.to_i
54
59
 
55
60
  span.set_attribute('http.status_code', status_code)
56
- unless metadata_only?
61
+ unless config[:epsagon][:metadata_only]
57
62
  span.set_attribute('http.response.headers', Hash[response.each_header.to_a].to_json)
58
63
  span.set_attribute('http.response.body', response.body)
59
64
  end
@@ -63,11 +68,14 @@ module EpsagonNetHTTPExtension
63
68
  end
64
69
 
65
70
  def tracer
66
- EpsagonSinatraInstrumentation.instance.tracer
71
+ EpsagonNetHTTPInstrumentation.instance.tracer
67
72
  end
68
73
  end
69
74
 
75
+ # Net::HTTP epsagon instrumentaton
70
76
  class EpsagonNetHTTPInstrumentation < OpenTelemetry::Instrumentation::Base
77
+ VERSION = '0.0.0'
78
+
71
79
  install do |_|
72
80
  ::Net::HTTP.prepend(EpsagonNetHTTPExtension)
73
81
  end
@@ -5,11 +5,16 @@ require 'opentelemetry'
5
5
 
6
6
  require_relative '../util'
7
7
 
8
+ # Sinatra middleware for epsagon instrumentation
8
9
  class EpsagonTracerMiddleware
9
10
  def initialize(app)
10
11
  @app = app
11
12
  end
12
13
 
14
+ def config
15
+ EpsagonSinatraInstrumentation.instance.config
16
+ end
17
+
13
18
  def call(env)
14
19
  request = Rack::Request.new(env)
15
20
  path, path_params = request.path.split(';')
@@ -27,7 +32,7 @@ class EpsagonTracerMiddleware
27
32
  'http.request.headers' => request_headers
28
33
  }
29
34
 
30
- unless metadata_only?
35
+ unless config[:epsagon][:metadata_only]
31
36
  request.body.rewind
32
37
  request_body = request.body.read
33
38
  request.body.rewind
@@ -68,7 +73,7 @@ class EpsagonTracerMiddleware
68
73
  def trace_response(http_span, framework_span, env, resp)
69
74
  status, headers, response_body = resp
70
75
 
71
- unless metadata_only?
76
+ unless config[:epsagon][:metadata_only]
72
77
  http_span.set_attribute('http.response.headers', JSON.generate(headers))
73
78
  http_span.set_attribute('http.response.body', response_body.join)
74
79
  end
@@ -79,6 +84,7 @@ class EpsagonTracerMiddleware
79
84
  end
80
85
  end
81
86
 
87
+ # Sinatra extension for epsagon instrumentation
82
88
  module EpsagonTracerExtension
83
89
  # Sinatra hook after extension is registered
84
90
  def self.registered(app)
@@ -100,7 +106,10 @@ module EpsagonTracerExtension
100
106
  end
101
107
  end
102
108
 
109
+ # Sinatra epsagon instrumentation
103
110
  class EpsagonSinatraInstrumentation < OpenTelemetry::Instrumentation::Base
111
+ VERSION = '0.0.0'
112
+
104
113
  install do |_|
105
114
  ::Sinatra::Base.register EpsagonTracerExtension
106
115
  end
data/lib/util.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'cgi'
4
4
 
5
+ # Utilities for epsagon opentelemetry solution
5
6
  module Util
6
7
  def self.epsagon_query_attributes(query_string)
7
8
  if query_string&.include? '='
metadata CHANGED
@@ -1,28 +1,33 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epsagon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
- - Assaf Paneth
7
+ - Epsagon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-06 00:00:00.000000000 Z
11
+ date: 2021-04-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Epsagon for ruby
14
- email: assaf.paneth@gmail.com
13
+ description: 'Epsagon provides tracing to Ruby applications for the collection of
14
+ distributed tracing and performance metrics to simplify complex architectures, eliminate
15
+ manual work, visualize and correlate data to identify and fix problems fast.
16
+
17
+ '
18
+ email: info@epsagon.com
15
19
  executables: []
16
20
  extensions: []
17
21
  extra_rdoc_files: []
18
22
  files:
19
23
  - lib/epsagon.rb
20
24
  - lib/epsagon_opentelemetry.rb
25
+ - lib/instrumentation/aws_sdk.rb
21
26
  - lib/instrumentation/faraday.rb
22
27
  - lib/instrumentation/net_http.rb
23
28
  - lib/instrumentation/sinatra.rb
24
29
  - lib/util.rb
25
- homepage: https://rubygems.org/gems/epsagon
30
+ homepage: https://github.com/epsagon/epsagon-ruby
26
31
  licenses:
27
32
  - MIT
28
33
  metadata: {}
@@ -34,7 +39,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
34
39
  requirements:
35
40
  - - ">="
36
41
  - !ruby/object:Gem::Version
37
- version: '0'
42
+ version: 2.0.0
38
43
  required_rubygems_version: !ruby/object:Gem::Requirement
39
44
  requirements:
40
45
  - - ">="
@@ -44,5 +49,6 @@ requirements: []
44
49
  rubygems_version: 3.1.4
45
50
  signing_key:
46
51
  specification_version: 4
47
- summary: Epsagon for ruby
52
+ summary: Epsagon provides tracing to Ruby applications for the collection of distributed
53
+ tracing and performance metrics.
48
54
  test_files: []