epsagon 0.0.0 → 0.0.5

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.
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: []