stackify-ruby-apm 1.8.0 → 1.9.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: 2a671e23d695c474d3aafa85df6756d98fa51610411f40e2c750a8e2e5ad2bb1
4
- data.tar.gz: c34ada9683508fbf2345434260c616100a5394fc58c22c4ea5eeceb8e7be78fe
3
+ metadata.gz: 6f7fd8fff02ed67e5112d4b59f84063cdebd84862e05f84376bd98c3237c3625
4
+ data.tar.gz: 0b59b1c98df2313f254e0f3f10fbe9291510e9316360d839c1073beee9100ab0
5
5
  SHA512:
6
- metadata.gz: 135db2d570f4d24b94ebd39f70909eb1ca21beb52052eaf25f1788d339039803f229ccdfaea00618386f6656378ae934e79f4a85d4c8eee059ff3941794b9c3f
7
- data.tar.gz: b6d344829e9d14e8736bf3e0807fe2c9995d859a733fd1b79920196bc30df3afeac1c2374ad469e1a4bffe9428f43b258243af5138c61981e627ba14f37928f7
6
+ metadata.gz: f347b093845bedd23269048c352aeac43b9bde434f22d9805e60fba67d08bd0eb1907d052f8f3b522f1b3452faaf4a1c02fb332ae28abd49bdba37e65bd6d714
7
+ data.tar.gz: 71f935e7e9096c5a4e4c1d365b8e45790364f77a4e6045f0af2fe79e5475662eaa93937de6a95a7c5e8b15a55e0b57c947bbe28da7f9c0d081da6cdf8886efa6
@@ -0,0 +1 @@
1
+ require 'stackify_ruby_apm_lambda'
@@ -118,6 +118,10 @@ module StackifyRubyAPM
118
118
  # Stores transaction in queue
119
119
  #
120
120
  def enqueue_transaction(transaction)
121
+ if !@config.queue
122
+ return @trace_logger.post([transaction])
123
+ end
124
+
121
125
  boot_worker unless worker_running?
122
126
  pending_transactions.push(transaction)
123
127
  return unless should_flush_transactions?
@@ -8,7 +8,12 @@ require 'logger'
8
8
  require 'yaml'
9
9
  require 'socket'
10
10
  module StackifyRubyAPM
11
- TRANSPORT = [TRACE_LOG = 'default'.freeze, UNIX_SOCKET = 'agent_socket'.freeze, AGENT_HTTP = 'agent_http'.freeze].freeze
11
+ TRANSPORT = [
12
+ TRACE_LOG = 'default'.freeze,
13
+ UNIX_SOCKET = 'agent_socket'.freeze,
14
+ AGENT_HTTP = 'agent_http'.freeze,
15
+ LOGGING = 'logging'.freeze
16
+ ].freeze
12
17
 
13
18
  # @api private
14
19
  class Config
@@ -62,7 +67,10 @@ module StackifyRubyAPM
62
67
  stackify_properties_file: '/usr/local/stackify/stackify-ruby-apm/stackify.properties',
63
68
  agent_traces_url: '/traces',
64
69
  unix_socket_path: '/usr/local/stackify/stackify.sock',
65
- transport_http_endpoint: 'https://localhost:10601'
70
+ transport_http_endpoint: 'https://localhost:10601',
71
+
72
+ queue: true,
73
+ lambda_handler: ''
66
74
  }.freeze
67
75
 
68
76
  ENV_TO_KEY = {
@@ -87,7 +95,9 @@ module StackifyRubyAPM
87
95
  'STACKIFY_SPAN_FRAMES_MIN_DURATION' => [:int, 'span_frames_min_duration'],
88
96
  'STACKIFY_MAX_QUEUE_SIZE' => [:int, 'max_queue_size'],
89
97
  'STACKIFY_FLUSH_INTERVAL' => 'flush_interval_seconds',
90
- 'STACKIFY_DISABLED_SPIES' => [:list, 'disabled_spies']
98
+ 'STACKIFY_DISABLED_SPIES' => [:list, 'disabled_spies'],
99
+ 'STACKIFY_QUEUE' => [:bool, 'queue'],
100
+ 'STACKIFY_LAMBDA_HANDLER' => 'lambda_handler'
91
101
  }.freeze
92
102
 
93
103
  def initialize(options = {})
@@ -158,6 +168,9 @@ module StackifyRubyAPM
158
168
  attr_accessor :root_path
159
169
  attr_accessor :http_status
160
170
 
171
+ attr_accessor :queue
172
+ attr_accessor :lambda_handler
173
+
161
174
  attr_reader :client_id
162
175
  attr_reader :device_id
163
176
  attr_reader :apm_disabled_in_rake
@@ -221,11 +234,18 @@ module StackifyRubyAPM
221
234
  new_available_spies - disabled_spies
222
235
  end
223
236
 
237
+ # Default Transport
238
+ #
239
+ # initialize default logger transport
224
240
  def debug_logger
225
- debugger_logpath = log_path == '-' ? $stdout : log_path
226
- logger = StackifyLogger.new(debugger_logpath, debugger_filenum_rotate, debugger_byte_size)
227
- logger.level = log_level
228
- self.logger = logger
241
+ case @transport.downcase
242
+ # For unix socket we don't create a trace log file
243
+ when StackifyRubyAPM::TRACE_LOG
244
+ debugger_logpath = log_path == '-' ? $stdout : log_path
245
+ logger = StackifyLogger.new(debugger_logpath, debugger_filenum_rotate, debugger_byte_size)
246
+ logger.level = log_level
247
+ self.logger = logger
248
+ end
229
249
  end
230
250
 
231
251
  private
@@ -12,12 +12,19 @@ module StackifyRubyAPM
12
12
  class Context
13
13
  include NaivelyHashable
14
14
 
15
- attr_accessor :request, :response
15
+ attr_accessor :request, :response, :aws
16
16
  attr_reader :custom, :tags
17
17
 
18
18
  def initialize
19
19
  @custom = {}
20
20
  @tags = {}
21
21
  end
22
+
23
+ # add aws context to context instance
24
+ #
25
+ # values {arn}
26
+ def add_aws_context ctx
27
+ @aws = ctx
28
+ end
22
29
  end
23
30
  end
@@ -15,6 +15,15 @@ module StackifyRubyAPM
15
15
  def build
16
16
  # get process id
17
17
  pid = $PID || Process.pid
18
+ # get hostname and remove extra unwanted characters
19
+ begin
20
+ hostname = (@config.hostname || `hostname`).strip
21
+ rescue StandardError
22
+ # use socket to get hostname if `hostname` throws exception
23
+ require 'socket'
24
+ hostname = Socket.gethostname
25
+ end
26
+
18
27
  hash = {
19
28
  CATEGORY: 'Ruby',
20
29
  APPLICATION_PATH: '/',
@@ -26,7 +35,7 @@ module StackifyRubyAPM
26
35
  THREAD_ID: Thread.current.object_id,
27
36
  TRACE_SOURCE: 'RUBY',
28
37
  TRACE_TARGET: 'RETRACE',
29
- HOST_NAME: (@config.hostname || `hostname`).strip,
38
+ HOST_NAME: hostname,
30
39
  OS_TYPE: StackifyRubyAPM::Util.host_os,
31
40
  PROCESS_ID: pid,
32
41
  TRACE_VERSION: '2.0',
@@ -36,6 +45,7 @@ module StackifyRubyAPM
36
45
  hash[:STATUS] = @transaction.context.response.status_code if @transaction.context && @transaction.context.response && @transaction.context.response.status_code
37
46
  hash[:URL] = @transaction.context.request.url[:full] if @transaction.context && @transaction.context.request && @transaction.context.request.url[:full]
38
47
  hash[:RUM] = true if @config.rum_enabled.is_a?(TrueClass)
48
+ hash[:AWS_LAMBDA_ARN] = @transaction.context.aws[:arn] if @transaction.context && @transaction.context.aws && @transaction.context.aws[:arn]
39
49
  hash
40
50
  end
41
51
  # rubocop:enable Metrics/CyclomaticComplexity
@@ -0,0 +1,53 @@
1
+ require 'base64'
2
+ require 'stringio'
3
+ require 'zlib'
4
+ require 'stackify_apm/root_info'
5
+ require 'stackify_apm/serializers'
6
+
7
+
8
+ module StackifyRubyAPM
9
+ # This class will handle the writing of messages through a logfile.
10
+ # @api private
11
+ class AWSLoggerClient
12
+ include Log
13
+ COMPRESS_DEFAULT_LEVEL = 6
14
+
15
+ def initialize(config)
16
+ @config = config
17
+ @transaction_serializers = Serializers::Transactions.new(@config)
18
+ @logger = Logger.new(STDOUT)
19
+ @logger.level = :debug
20
+ @logger.formatter = proc do |severity, datetime, progname, msg|
21
+ "STACKIFY-TRACE: #{msg}\n"
22
+ end
23
+ end
24
+
25
+ # This method will build an Array of Transactions in a json format.
26
+ # It will accept Array of transactions.
27
+ def post(transactions = [])
28
+ # convert transactions to json
29
+ json_traces = []
30
+ transactions.each do |transaction|
31
+ # convert transaction to json
32
+ json_transaction = @transaction_serializers.build_json(@config, transaction).to_json
33
+
34
+ # add to json traces array
35
+ json_traces.push(json_transaction)
36
+ end
37
+
38
+ return unless ENV['STACKIFY_RUBY_ENV'] != 'rspec'
39
+
40
+ json_traces.each do |json_trace|
41
+ str = StringIO.new mode='w'
42
+ gz = Zlib::GzipWriter.new str, 6
43
+ gz.write json_trace.to_s
44
+ gz.close
45
+ compressed = Base64.strict_encode64 str.string
46
+ @logger.debug compressed
47
+ end
48
+ debug '[LogClient] post() Successfully write to logfile.' if ENV['STACKIFY_TRANSPORT_LOG_LEVEL'] == '0'
49
+ rescue StandardError => e
50
+ debug "[LogClient] post() exception: #{e.inspect}"
51
+ end
52
+ end
53
+ end
@@ -14,6 +14,8 @@ module StackifyRubyAPM
14
14
  StackifyRubyAPM::UnixSocketClient.new(config)
15
15
  when StackifyRubyAPM::AGENT_HTTP
16
16
  StackifyRubyAPM::AgentHTTPClient.new(config)
17
+ when StackifyRubyAPM::LOGGING
18
+ StackifyRubyAPM::AWSLoggerClient.new(config)
17
19
  else
18
20
  StackifyRubyAPM::LogClient.new(config)
19
21
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Sets the version of the APM
4
4
  module StackifyRubyAPM
5
- VERSION = '1.8.0'.freeze
5
+ VERSION = '1.9.5'.freeze
6
6
  end
@@ -33,6 +33,7 @@ require 'stackify_apm/transport/agent_base'
33
33
  require 'stackify_apm/transport/log_client'
34
34
  require 'stackify_apm/transport/unix_socket_client'
35
35
  require 'stackify_apm/transport/agent_http_client'
36
+ require 'stackify_apm/transport/aws_lambda_logging'
36
37
 
37
38
  require 'google/protobuf'
38
39
  require 'proto/stackify_trace'
@@ -0,0 +1,62 @@
1
+ require 'stackify_ruby_apm'
2
+
3
+ module AWS
4
+ def self.instrument
5
+ config = {
6
+ transport: 'logging',
7
+ queue: false,
8
+ }
9
+ StackifyRubyAPM.start config
10
+ end
11
+
12
+ def self.handler(event:, context:, &block)
13
+ begin
14
+ ctx = StackifyRubyAPM::Context.new
15
+ ctx.add_aws_context({:arn => context.invoked_function_arn})
16
+ transaction = StackifyRubyAPM.transaction context.function_name, 'TASK', context: ctx
17
+ ret = block.call
18
+ rescue StackifyRubyAPM::InternalError
19
+ raise # Don't report StackifyRubyAPM errors
20
+ rescue StandardError => e
21
+ StackifyRubyAPM.report e
22
+ raise e
23
+ ensure
24
+ transaction.submit()
25
+ end
26
+ ret
27
+ end
28
+
29
+ # STACKIFY LAMBDA HANDLER
30
+ #
31
+ # @return original function execution
32
+ def self.stackify_handler(event:, context:)
33
+ begin
34
+ if !StackifyRubyAPM.running?
35
+ config = {
36
+ transport: 'logging',
37
+ queue: false,
38
+ }
39
+ StackifyRubyAPM.start config
40
+ end
41
+
42
+ ctx = StackifyRubyAPM::Context.new
43
+ ctx.add_aws_context({:arn => context.invoked_function_arn})
44
+ transaction = StackifyRubyAPM.transaction context.function_name, 'TASK', context: ctx
45
+
46
+ lambda_handler = StackifyRubyAPM.agent.config.lambda_handler.split('.')
47
+ function_file = lambda_handler[0]
48
+ function_name = lambda_handler[-1]
49
+
50
+ require "./#{function_file}"
51
+
52
+ send(function_name, event: event, context: context)
53
+ rescue StackifyRubyAPM::InternalError
54
+ raise # Don't report StackifyRubyAPM errors
55
+ rescue StandardError => e
56
+ StackifyRubyAPM.report e
57
+ raise e
58
+ ensure
59
+ transaction.submit()
60
+ end
61
+ end
62
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackify-ruby-apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stackify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-20 00:00:00.000000000 Z
11
+ date: 2020-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -143,18 +143,13 @@ executables: []
143
143
  extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
- - ".gemignore"
147
- - ".gitignore"
148
- - ".rspec"
149
- - ".rubocop.yml"
150
- - ".ruby-version"
151
146
  - Gemfile
152
147
  - Gemfile.lock
153
148
  - LICENSE.md
154
149
  - README.md
155
150
  - Rakefile
156
- - docker-compose.yml
157
151
  - lib/proto/stackify_trace.rb
152
+ - lib/stackify-ruby-apm-lambda.rb
158
153
  - lib/stackify-ruby-apm.rb
159
154
  - lib/stackify_apm/agent.rb
160
155
  - lib/stackify_apm/config.rb
@@ -218,6 +213,7 @@ files:
218
213
  - lib/stackify_apm/transaction.rb
219
214
  - lib/stackify_apm/transport/agent_base.rb
220
215
  - lib/stackify_apm/transport/agent_http_client.rb
216
+ - lib/stackify_apm/transport/aws_lambda_logging.rb
221
217
  - lib/stackify_apm/transport/log_client.rb
222
218
  - lib/stackify_apm/transport/unix_socket_client.rb
223
219
  - lib/stackify_apm/transport_selector.rb
@@ -230,6 +226,7 @@ files:
230
226
  - lib/stackify_apm/version.rb
231
227
  - lib/stackify_apm/worker.rb
232
228
  - lib/stackify_ruby_apm.rb
229
+ - lib/stackify_ruby_apm_lambda.rb
233
230
  - stackify-ruby-apm.gemspec
234
231
  homepage: http://www.stackify.com
235
232
  licenses:
data/.gemignore DELETED
@@ -1,8 +0,0 @@
1
- test
2
- spec
3
- features
4
- docs
5
- docker
6
- docker-compose.xml
7
- deploy-*.sh
8
- run-*.sh
data/.gitignore DELETED
@@ -1,76 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
12
-
13
- # Ignore bundler config.
14
- /.bundle
15
-
16
- # Ignore all logfiles and tempfiles.
17
- /log/*
18
- /tmp/*
19
- !/log/.keep
20
- !/tmp/.keep
21
-
22
- # Ignore bundler config.
23
- /.bundle
24
-
25
- # Deps
26
- node_modules
27
-
28
- # IDE
29
- .idea
30
-
31
- # VS Code
32
- .vscode
33
- .vs
34
-
35
- # Unnecessary since this will be a plugin
36
- package-lock.json
37
-
38
- # Folder config file
39
- Desktop.ini
40
-
41
- # Windows shortcuts
42
- *.lnk
43
-
44
- ### OSX ###
45
- /**/.DS_Store
46
- /.DS_Store
47
- .AppleDouble
48
- .LSOverride
49
-
50
- # Thumbnails
51
- ._*
52
-
53
- # Files that might appear on external disk
54
- .Spotlight-V100
55
- .Trashes
56
-
57
- ### Linux ###
58
- *~
59
-
60
- # Windows image file caches
61
- Thumbs.db
62
- ehthumbs.db
63
-
64
- # Ignore .byebug_history, .rspec, brakeman.html
65
- .byebug_history
66
- .rspec
67
- brakeman.html
68
-
69
-
70
- # Gem
71
- *.gem
72
-
73
- #bin
74
- bin
75
- bin/*
76
-
data/.rubocop.yml DELETED
@@ -1,38 +0,0 @@
1
- AllCops:
2
- RubyInterpreters:
3
- - ruby
4
- - macruby
5
- - rake
6
- - jruby
7
- - rbx
8
-
9
- Exclude:
10
- - 'node_modules/**/*'
11
- - 'vendor/**/*'
12
- - '.git/**/*'
13
- - 'spec/**/*'
14
-
15
- Naming/FileName:
16
- Exclude:
17
- - 'lib/stackify-ruby-apm.rb'
18
-
19
- Metrics/LineLength:
20
- Max: 1000
21
-
22
- Metrics/BlockLength:
23
- Max: 1000
24
-
25
- Metrics/MethodLength:
26
- Enabled: false
27
-
28
- Metrics/ClassLength:
29
- Max: 1000
30
-
31
- Style/RedundantFreeze:
32
- Enabled: false
33
-
34
- Style/SafeNavigation:
35
- Enabled: false
36
-
37
- Metrics/AbcSize:
38
- Enabled: false
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.0.0-p648
data/docker-compose.yml DELETED
@@ -1,46 +0,0 @@
1
- version: "3"
2
- services:
3
-
4
- dbpostgresql:
5
- image: postgres
6
- volumes:
7
- - postgresdata:/var/lib/postgresql/data
8
- ports:
9
- - 5433:5432
10
- environment:
11
- POSTGRES_DB: PostgresTestDB
12
- POSTGRES_USER: bob
13
- POSTGRES_PASSWORD: password
14
- container_name: sinatra_activerecord_postgres_test
15
-
16
- dbmysql:
17
- image: mysql:5.7
18
- volumes:
19
- - mysqldata:/var/lib/mysql
20
- ports:
21
- - 3305:3306
22
- environment:
23
- - MYSQL_ROOT_PASSWORD=secret
24
- - MYSQL_USER=bob
25
- - MYSQL_PASSWORD=password
26
- - MYSQL_DATABASE=MysqlTestDB
27
- container_name: sinatra_activerecord_mysql_test
28
-
29
- dbmongo:
30
- image: mongo:3.6
31
- volumes:
32
- - mongodata:/data/db
33
- - mongodata_config:/data/configdb
34
- ports:
35
- - 27018:27017
36
- container_name: sinatra_activerecord_mongo_test
37
-
38
- volumes:
39
- postgresdata:
40
- driver: local
41
- mysqldata:
42
- driver: local
43
- mongodata:
44
- driver: local
45
- mongodata_config:
46
- driver: local