airfoil 0.1.2
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 +7 -0
- data/README.md +65 -0
- data/lib/airfoil/cloudwatch_formatter.rb +9 -0
- data/lib/airfoil/logger_patch.rb +15 -0
- data/lib/airfoil/middleware/base.rb +9 -0
- data/lib/airfoil/middleware/database.rb +17 -0
- data/lib/airfoil/middleware/datadog.rb +23 -0
- data/lib/airfoil/middleware/function_name.rb +35 -0
- data/lib/airfoil/middleware/log_event.rb +71 -0
- data/lib/airfoil/middleware/logger_tagging.rb +19 -0
- data/lib/airfoil/middleware/sentry_catcher.rb +40 -0
- data/lib/airfoil/middleware/sentry_monitoring.rb +42 -0
- data/lib/airfoil/middleware/set_request_id.rb +13 -0
- data/lib/airfoil/middleware/step_function.rb +37 -0
- data/lib/airfoil/railtie.rb +33 -0
- data/lib/airfoil/version.rb +5 -0
- data/lib/airfoil.rb +40 -0
- metadata +170 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cafc414d07d58d199bc9058066119516cf27810402bac47c7c7cb253ebee85a3
|
4
|
+
data.tar.gz: c694dd87b5a2f228b03701580c33c0063751a077c3d23c410e230d6702b8937a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 685294eccb81796e1b4338ff99cbd849d8997fde13cc2437e0839b8134bfcb9b99ecf630bd462c6fa7aa3a03a102e689ad54b1147849e868c96e5aa74758f3d9
|
7
|
+
data.tar.gz: b0a8f3e5314f1006b8fb5dc85b2955ead9b7f089798e44afab0f96801bc3dfe67d4579669f09f48620d274af09dac919059a8c77323a7b4240571c45ea98d990
|
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Airfoil
|
2
|
+
_Enough structure to get our Lambda handlers in the air._
|
3
|
+
|
4
|
+
Airfoil is curated middleware stack that abstracts away common infrastructure
|
5
|
+
needed for Lambda handler functions.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'airfoil'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install airfoil
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
You can instantiate a new handler with an Airfoil stack like so:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require_relative "config/environment"
|
29
|
+
|
30
|
+
STACK = Airfoil.create_stack do |b|
|
31
|
+
# Custom middleware and handlers go here
|
32
|
+
b.use Airfoil::Middleware::FunctionName, DbReset, "db-reset"
|
33
|
+
b.use Airfoil::Middleware::FunctionName, UpdateUpcomingRenewals, "update-upcoming-renewals"
|
34
|
+
end
|
35
|
+
|
36
|
+
def handler(event:, context:)
|
37
|
+
STACK.call({event: event, context: context})
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Airfoil also includes a stack of middleware that you can add to or customize to
|
42
|
+
suit your specific needs. Your own middleware can inherit from the base class and
|
43
|
+
implement their own behavior like so:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
class MyResolverMiddleware < Airfoil::Middleware::Base
|
47
|
+
def call(env)
|
48
|
+
ApplicationResolver.handle(env[:event], env[:context])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
Existing middleware include:
|
54
|
+
|
55
|
+
- `FunctionName` - dispatch any calls made to a specific Lambda function (by name) to a specified handler class
|
56
|
+
- `LogEvent` - log AWS events in a pretty format
|
57
|
+
- `SentryCatcher` - catch exceptions and report them to Sentry, including context
|
58
|
+
- `SentryMonitoring` - instrument your function code for Sentry's performance monitoring
|
59
|
+
- `SetRequestId` - set the `AWS_REQUEST_ID` environment variable for your function code
|
60
|
+
|
61
|
+
## Development
|
62
|
+
|
63
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
64
|
+
|
65
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# The built-in Middleware gem logger truncates the event so instead
|
2
|
+
# we have our own logging middleware to print the event and context.
|
3
|
+
# Here, we reopen the class and ignoring the partial event to cut down on log chatter.
|
4
|
+
class ::Middleware::Logger
|
5
|
+
def way_in_message name, env
|
6
|
+
" %s has been called with: %s" % [name, env[:context].function_name]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Default to omitting middleware logging
|
10
|
+
def write msg
|
11
|
+
if ENV["MIDDLEWARE_LOGGING_ENABLED"] == "true"
|
12
|
+
@write_to.add(::Logger::INFO, msg.slice(0, 255).strip!, @middleware_name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "airfoil/middleware/base"
|
2
|
+
|
3
|
+
module Airfoil
|
4
|
+
module Middleware
|
5
|
+
class Database < Airfoil::Middleware::Base
|
6
|
+
def call(env)
|
7
|
+
# TODO: This explicitly makes a connection, which we may want to re-evaluate at some point
|
8
|
+
ActiveRecord::Base.connection_pool.with_connection do |conn|
|
9
|
+
conn.enable_query_cache!
|
10
|
+
@app.call(env)
|
11
|
+
ensure
|
12
|
+
conn.disable_query_cache!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "datadog/lambda"
|
2
|
+
require "datadog/tracing"
|
3
|
+
require "airfoil/middleware/base"
|
4
|
+
|
5
|
+
module Airfoil
|
6
|
+
module Middleware
|
7
|
+
class Datadog < Base
|
8
|
+
# See the Airfoil railtie for config loaded at Rails load-time
|
9
|
+
# Note: Rails loads prior to Airfoil because of the inclusion of `require_relative "config/environment"`
|
10
|
+
# in the engine lambda handler
|
11
|
+
def call(env)
|
12
|
+
event, context = env.values_at(:event, :context)
|
13
|
+
|
14
|
+
::Datadog::Lambda.wrap(event, context) do
|
15
|
+
@app.call(env)
|
16
|
+
rescue => err
|
17
|
+
::Datadog::Tracing.active_span&.set_error(err)
|
18
|
+
raise err
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "airfoil/middleware/base"
|
2
|
+
|
3
|
+
module Airfoil
|
4
|
+
module Middleware
|
5
|
+
class FunctionName < Middleware::Base
|
6
|
+
def initialize(app, handler_class, *function_names_to_match)
|
7
|
+
super(app)
|
8
|
+
@handler_class = handler_class
|
9
|
+
@function_names_to_match = function_names_to_match
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
context = env[:context]
|
14
|
+
|
15
|
+
if handles? context
|
16
|
+
@handler_class.handle(env[:event], context)
|
17
|
+
else
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def handles?(context)
|
25
|
+
@function_names_to_match.include?(canonicalize_function_name(context.function_name))
|
26
|
+
end
|
27
|
+
|
28
|
+
# Strip off the function suffix if present to allow for terraform/terratest to invoke lambdas with unique names that route to the same function
|
29
|
+
# e.g. finalize-submission-testrun89YD36 => finalize-submission
|
30
|
+
def canonicalize_function_name(function_name)
|
31
|
+
function_name.sub(/-testrun[a-zA-Z0-9]*$/, "")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "dry-monads"
|
2
|
+
require "active_support"
|
3
|
+
require "active_support/core_ext/hash/except"
|
4
|
+
require "airfoil/middleware/base"
|
5
|
+
|
6
|
+
module Airfoil
|
7
|
+
module Middleware
|
8
|
+
class LogEvent < Base
|
9
|
+
include Dry::Monads[:maybe]
|
10
|
+
|
11
|
+
def initialize(app, logger)
|
12
|
+
super(app)
|
13
|
+
@logger = logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
event = env[:event]
|
18
|
+
|
19
|
+
logged_data = {
|
20
|
+
"identity" => log_identity(event),
|
21
|
+
"event" => log_event(event)
|
22
|
+
}.to_json
|
23
|
+
|
24
|
+
@logger.info(logged_data)
|
25
|
+
result = @app.call(env)
|
26
|
+
# Log the full result instead of the truncated version the middleware outputs
|
27
|
+
@logger.info({result: result}.to_json)
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Clear unwanted properties from our log output
|
34
|
+
def clean_event(event)
|
35
|
+
unwanted_fields = %w[identity]
|
36
|
+
event.except(*unwanted_fields)
|
37
|
+
end
|
38
|
+
|
39
|
+
def log_event(event)
|
40
|
+
return event if event.is_a?(String)
|
41
|
+
|
42
|
+
# Remove the full identity from our event output
|
43
|
+
if event.is_a?(Array)
|
44
|
+
event.map { |e| clean_event(e) }
|
45
|
+
else
|
46
|
+
clean_event(event)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def log_identity(event)
|
51
|
+
identity = case event
|
52
|
+
in [e, *rest]
|
53
|
+
e.dig("identity")
|
54
|
+
in Hash
|
55
|
+
event.dig("identity")
|
56
|
+
else
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
Maybe(identity).bind { |i|
|
61
|
+
Some({
|
62
|
+
groups: i.dig("groups"),
|
63
|
+
source_ip: i.dig("sourceIp"),
|
64
|
+
sub: i.dig("sub"),
|
65
|
+
auth_time: i.dig("claims", "auth_time")
|
66
|
+
})
|
67
|
+
}.value_or(nil)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "airfoil/middleware/base"
|
2
|
+
|
3
|
+
module Airfoil
|
4
|
+
module Middleware
|
5
|
+
class LoggerTagging < Base
|
6
|
+
def initialize(app, logger)
|
7
|
+
super(app)
|
8
|
+
@logger = logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
context = env[:context]
|
13
|
+
@logger.tagged(ENV["_X_AMZN_TRACE_ID"], context.aws_request_id) do
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "sentry-ruby"
|
2
|
+
require "airfoil/middleware/base"
|
3
|
+
|
4
|
+
module Airfoil
|
5
|
+
module Middleware
|
6
|
+
class SentryCatcher < Base
|
7
|
+
def initialize(app, logger)
|
8
|
+
super(app)
|
9
|
+
@logger = logger
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
@app.call(env)
|
14
|
+
rescue => err
|
15
|
+
Sentry.with_scope do |scope|
|
16
|
+
context = env[:context]
|
17
|
+
event = env[:event]
|
18
|
+
|
19
|
+
scope.set_extras(
|
20
|
+
function_name: context.function_name,
|
21
|
+
function_version: context.function_version,
|
22
|
+
invoked_function_arn: context.invoked_function_arn,
|
23
|
+
memory_limit_in_mb: context.memory_limit_in_mb,
|
24
|
+
aws_request_id: context.aws_request_id,
|
25
|
+
log_group_name: context.log_group_name,
|
26
|
+
log_stream_name: context.log_stream_name,
|
27
|
+
identity: context.identity,
|
28
|
+
event: event
|
29
|
+
)
|
30
|
+
|
31
|
+
Sentry.capture_exception(err)
|
32
|
+
@logger.error(err)
|
33
|
+
raise err
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class RequestError < StandardError; end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "sentry-ruby"
|
2
|
+
require "airfoil/middleware/base"
|
3
|
+
|
4
|
+
module Airfoil
|
5
|
+
module Middleware
|
6
|
+
class SentryMonitoring < Base
|
7
|
+
def call(env)
|
8
|
+
event, context = env.values_at(:event, :context)
|
9
|
+
sentry_trace_id = get_first_instance(event, "sentry_trace_id")
|
10
|
+
identity = get_first_instance(event, "identity")
|
11
|
+
|
12
|
+
options = {name: context.function_name, op: "handler"}
|
13
|
+
options[:transaction] = Sentry::Transaction.from_sentry_trace(sentry_trace_id, **options) if sentry_trace_id.present?
|
14
|
+
|
15
|
+
Sentry.set_user(username: identity.dig("username"), ip_address: identity.dig("source_ip", 0)) if identity.present?
|
16
|
+
transaction = Sentry.start_transaction(**options)
|
17
|
+
# Add transaction to the global scope so it is accessible throughout the app
|
18
|
+
Sentry.get_current_hub&.configure_scope do |scope|
|
19
|
+
scope.set_span(transaction)
|
20
|
+
end
|
21
|
+
|
22
|
+
result = @app.call(env)
|
23
|
+
transaction.finish if transaction.present?
|
24
|
+
|
25
|
+
result
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def get_first_instance(event, key)
|
31
|
+
case event
|
32
|
+
in [e, *rest]
|
33
|
+
e.dig(key)
|
34
|
+
in Hash
|
35
|
+
event.dig(key)
|
36
|
+
else
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "airfoil/middleware/base"
|
2
|
+
|
3
|
+
module Airfoil
|
4
|
+
module Middleware
|
5
|
+
class SetRequestId < Base
|
6
|
+
def call(env)
|
7
|
+
context = env[:context]
|
8
|
+
ENV["AWS_REQUEST_ID"] = context.aws_request_id if context.present?
|
9
|
+
@app.call(env)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative "function_name"
|
2
|
+
|
3
|
+
module Airfoil
|
4
|
+
module Middleware
|
5
|
+
class StepFunction < FunctionName
|
6
|
+
def initialize(app, handler_class, *function_names_to_match, retried_exceptions: [])
|
7
|
+
super(app, handler_class, *function_names_to_match)
|
8
|
+
@retried_exceptions = retried_exceptions.map(&:to_s)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
context = env[:context]
|
13
|
+
|
14
|
+
ignore_exceptions(context) do
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def ignore_exceptions(context)
|
20
|
+
disable_exceptions
|
21
|
+
result = yield
|
22
|
+
enable_exceptions
|
23
|
+
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
def disable_exceptions
|
28
|
+
@before = Sentry.configuration.excluded_exceptions
|
29
|
+
Sentry.configuration.excluded_exceptions += @retried_exceptions
|
30
|
+
end
|
31
|
+
|
32
|
+
def enable_exceptions
|
33
|
+
Sentry.configuration.excluded_exceptions = @before
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "airfoil/cloudwatch_formatter"
|
2
|
+
require "datadog/lambda"
|
3
|
+
|
4
|
+
module Airfoil
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
# Format logs for consistent parsing by Cloudwatch
|
7
|
+
config.log_formatter = Airfoil::CloudwatchFormatter.new
|
8
|
+
config.datadog_enabled = ENV.fetch("DATADOG_ENABLED", Rails.env.production?).to_s == "true"
|
9
|
+
|
10
|
+
initializer "airfoil.datadog" do
|
11
|
+
if Rails.configuration.datadog_enabled
|
12
|
+
require "ddtrace/auto_instrument"
|
13
|
+
|
14
|
+
::Datadog::Lambda.configure_apm do |c|
|
15
|
+
c.env = ENV.fetch("SENTRY_ENVIRONMENT", Rails.env).dasherize
|
16
|
+
# downscasing first ensures we don't attempt to snake case things that don't already have dashes
|
17
|
+
c.service = ENV.fetch("AWS_LAMBDA_FUNCTION_NAME", "brokersuite").downcase.underscore
|
18
|
+
|
19
|
+
# Set trace rate via DD_TRACE_SAMPLE_RATE
|
20
|
+
c.tracing.enabled = true
|
21
|
+
c.tracing.instrument :aws
|
22
|
+
c.tracing.instrument :faraday
|
23
|
+
c.tracing.instrument :rest_client
|
24
|
+
c.tracing.instrument :httpclient
|
25
|
+
c.tracing.instrument :http
|
26
|
+
c.tracing.instrument :rails
|
27
|
+
end
|
28
|
+
|
29
|
+
Rails.logger.debug "=====DATADOG LOADED (RAILTIE)====="
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/airfoil.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "middleware"
|
4
|
+
|
5
|
+
require_relative "airfoil/version"
|
6
|
+
require_relative "airfoil/middleware/database"
|
7
|
+
require_relative "airfoil/middleware/datadog"
|
8
|
+
require_relative "airfoil/middleware/function_name"
|
9
|
+
require_relative "airfoil/middleware/log_event"
|
10
|
+
require_relative "airfoil/middleware/logger_tagging"
|
11
|
+
require_relative "airfoil/middleware/sentry_catcher"
|
12
|
+
require_relative "airfoil/middleware/sentry_monitoring"
|
13
|
+
require_relative "airfoil/middleware/set_request_id"
|
14
|
+
require_relative "airfoil/middleware/step_function"
|
15
|
+
require_relative "airfoil/logger_patch"
|
16
|
+
require_relative "airfoil/railtie" if defined?(Rails::Railtie)
|
17
|
+
|
18
|
+
module Airfoil
|
19
|
+
class << self
|
20
|
+
def create_stack
|
21
|
+
# ensure that STDOUT streams are synchronous so we don't lose logs
|
22
|
+
$stdout.sync = true
|
23
|
+
|
24
|
+
Signal.trap("TERM") do
|
25
|
+
# We can't use the Rails logger here as the logger is not available in the trap context
|
26
|
+
puts "Received SIGTERM, shutting down gracefully..." # rubocop:disable Rails/Output
|
27
|
+
end
|
28
|
+
|
29
|
+
::Middleware::Builder.new { |b|
|
30
|
+
b.use Middleware::LoggerTagging, Rails.logger
|
31
|
+
b.use Middleware::SetRequestId
|
32
|
+
b.use Middleware::Datadog
|
33
|
+
b.use Middleware::SentryCatcher, Rails.logger
|
34
|
+
b.use Middleware::SentryMonitoring
|
35
|
+
b.use Middleware::LogEvent, Rails.logger
|
36
|
+
yield b
|
37
|
+
}.inject_logger(Rails.logger)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: airfoil
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Highwing Engineering
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-08-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: datadog-lambda
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-monads
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ibsciss-middleware
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.4.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.4.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: railties
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sentry-ruby
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: aws_lambda_ric
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description:
|
126
|
+
email:
|
127
|
+
- engineering@highwing.io
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- README.md
|
133
|
+
- lib/airfoil.rb
|
134
|
+
- lib/airfoil/cloudwatch_formatter.rb
|
135
|
+
- lib/airfoil/logger_patch.rb
|
136
|
+
- lib/airfoil/middleware/base.rb
|
137
|
+
- lib/airfoil/middleware/database.rb
|
138
|
+
- lib/airfoil/middleware/datadog.rb
|
139
|
+
- lib/airfoil/middleware/function_name.rb
|
140
|
+
- lib/airfoil/middleware/log_event.rb
|
141
|
+
- lib/airfoil/middleware/logger_tagging.rb
|
142
|
+
- lib/airfoil/middleware/sentry_catcher.rb
|
143
|
+
- lib/airfoil/middleware/sentry_monitoring.rb
|
144
|
+
- lib/airfoil/middleware/set_request_id.rb
|
145
|
+
- lib/airfoil/middleware/step_function.rb
|
146
|
+
- lib/airfoil/railtie.rb
|
147
|
+
- lib/airfoil/version.rb
|
148
|
+
homepage:
|
149
|
+
licenses: []
|
150
|
+
metadata: {}
|
151
|
+
post_install_message:
|
152
|
+
rdoc_options: []
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '3.2'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubygems_version: 3.4.17
|
167
|
+
signing_key:
|
168
|
+
specification_version: 4
|
169
|
+
summary: Enough structure to get our Lambda handlers in the air
|
170
|
+
test_files: []
|