api_logger 0.2.0
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/Gemfile +16 -0
- data/LICENSE.txt +0 -0
- data/README.md +124 -0
- data/Rakefile +6 -0
- data/lib/api_logger/configuration.rb +23 -0
- data/lib/api_logger/generators.rb +1 -0
- data/lib/api_logger/middleware.rb +93 -0
- data/lib/api_logger/railtie.rb +42 -0
- data/lib/api_logger/version.rb +3 -0
- data/lib/api_logger.rb +95 -0
- data/lib/generators/api_logger/install/install_generator.rb +29 -0
- data/lib/generators/api_logger/install/templates/create_api_logs.rb.tt +20 -0
- data/lib/tasks/api_logger_tasks.rake +11 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 84a8975ee0261c8d69b6d8da6d1aca8e4365abb85b6087eb21ddde88a4051dfa
|
4
|
+
data.tar.gz: '09f10422f744f28ec157ec0486b8e5f50753e9566432bbbabcc2068b4c028967'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4db6070b693462f259cca685bfb1de280d1586b21e671012a8da74f35512d20f9725dde96a2d7ee3d3c7ca43de59e92b0a60709d4c50e4e522fbf7cb3e8e82fa
|
7
|
+
data.tar.gz: 386ae70a35aec046e20e50529b19fc56fbf7bbf01f0d2957d93c50d9641ecb1735b6fd3254a44ef293ea0fb297cd7cecb9138931925d84ee5aa781eaf1a3465c
|
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in api_logger.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'rspec', '~> 3.12'
|
8
|
+
gem 'webmock', '~> 3.19'
|
9
|
+
gem 'simplecov', '~> 0.22', require: false
|
10
|
+
gem 'rubocop', '~> 1.57', require: false
|
11
|
+
gem 'rubocop-rspec', '~> 2.25', require: false
|
12
|
+
gem 'rubocop-rails', '~> 2.22', require: false
|
13
|
+
gem 'pry', '~> 0.14'
|
14
|
+
gem 'pry-byebug', '~> 3.10'
|
15
|
+
gem 'rake', '~> 13.0'
|
16
|
+
end
|
data/LICENSE.txt
ADDED
File without changes
|
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# API Logger
|
2
|
+
|
3
|
+
A simple gem for logging API requests and responses in Rails applications. It automatically logs outbound HTTP requests to specified hosts with zero configuration needed.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+

|
7
|
+
|
8
|
+
## Features
|
9
|
+
|
10
|
+
- **Selective Request Logging**: Logs outbound HTTP requests only to specified hosts
|
11
|
+
- **Zero Configuration**: Works out of the box with sensible defaults
|
12
|
+
- **Flexible Control**: Easy to enable/disable logging through configuration
|
13
|
+
- **Comprehensive Logging**: Captures request parameters, response bodies, status codes, and errors
|
14
|
+
- **Database Storage**: All logs are stored in your database for easy querying
|
15
|
+
- **Rails Integration**: Seamlessly integrates with your Rails application
|
16
|
+
- **Stack Safe**: Prevents recursive logging and stack overflow issues
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem 'api_logger', github: 'Superlinear-Insights/api_logger'
|
24
|
+
```
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
```bash
|
29
|
+
$ bundle install
|
30
|
+
$ rails generate api_logger:install
|
31
|
+
$ rails db:migrate
|
32
|
+
```
|
33
|
+
|
34
|
+
## Configuration
|
35
|
+
|
36
|
+
Configure which hosts to log by creating an initializer (`config/initializers/api_logger.rb`):
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
ApiLogger.configure do |config|
|
40
|
+
# The database table where logs will be stored
|
41
|
+
config.table_name = 'api_logs' # default
|
42
|
+
|
43
|
+
# Enable/disable all logging functionality
|
44
|
+
config.enabled = true # default
|
45
|
+
|
46
|
+
# Enable/disable automatic request logging via middleware
|
47
|
+
config.use_middleware = true # default
|
48
|
+
|
49
|
+
# Specify which hosts to log (empty array means log nothing)
|
50
|
+
config.allowed_hosts = [
|
51
|
+
'services.mfcentral.com',
|
52
|
+
'uatservices.mfcentral.com'
|
53
|
+
]
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
### Configuration Options
|
58
|
+
|
59
|
+
- `table_name`: The name of the database table where logs will be stored
|
60
|
+
- `enabled`: Master switch to enable/disable all logging functionality
|
61
|
+
- `use_middleware`: Controls automatic logging of HTTP requests
|
62
|
+
- `allowed_hosts`: Array of host strings that should be logged (empty means log nothing)
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
## Usage
|
67
|
+
|
68
|
+
### Automatic Request Logging
|
69
|
+
|
70
|
+
With default configuration, any HTTP request to allowed hosts will be automatically logged:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
# This request WILL be logged
|
74
|
+
uri = URI('https://services.mfcentral.com/api/v1/users')
|
75
|
+
response = Net::HTTP.get_response(uri)
|
76
|
+
|
77
|
+
# This request will NOT be logged
|
78
|
+
uri = URI('https://api.other-service.com/users')
|
79
|
+
response = Net::HTTP.get_response(uri)
|
80
|
+
```
|
81
|
+
|
82
|
+
### Accessing Logs
|
83
|
+
|
84
|
+
Logs are accessible through the `ApiLog` model:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
# Get the most recent log
|
88
|
+
ApiLog.last
|
89
|
+
|
90
|
+
# Get recent logs
|
91
|
+
ApiLog.order(created_at: :desc)
|
92
|
+
|
93
|
+
# Find logs for a specific endpoint
|
94
|
+
ApiLog.where(endpoint: '/api/v1/users')
|
95
|
+
|
96
|
+
# Get failed requests (status >= 400)
|
97
|
+
ApiLog.where('response_status >= ?', 400)
|
98
|
+
|
99
|
+
# Get successful requests
|
100
|
+
ApiLog.where('response_status < ?', 400)
|
101
|
+
```
|
102
|
+
|
103
|
+
### Log Data Structure
|
104
|
+
|
105
|
+
Each log entry contains:
|
106
|
+
- `endpoint`: The API endpoint that was called
|
107
|
+
- `request_params`: Parameters sent with the request (stored as JSON)
|
108
|
+
- `response_body`: The response received (stored as JSON)
|
109
|
+
- `response_status`: HTTP status code of the response
|
110
|
+
- `error_message`: Error message (for failed requests)
|
111
|
+
- `created_at`: When the log was created
|
112
|
+
- `updated_at`: When the log was last updated
|
113
|
+
|
114
|
+
## Maintenance
|
115
|
+
|
116
|
+
To clean up old logs, use the provided rake task:
|
117
|
+
|
118
|
+
```bash
|
119
|
+
# Clean logs older than 30 days (default)
|
120
|
+
rails api_logger:clean
|
121
|
+
|
122
|
+
# Clean logs older than N days
|
123
|
+
DAYS=7 rails api_logger:clean
|
124
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module ApiLogger
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :table_name, :enabled, :use_middleware, :allowed_hosts, :exclude_hosts, :exclude_routes
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@table_name = 'api_logs'
|
7
|
+
@enabled = true
|
8
|
+
@use_middleware = true
|
9
|
+
@allowed_hosts = ['services.mfcentral.com', 'uatservices.mfcentral.com']
|
10
|
+
# backwards compatibility, to be removed in next release.
|
11
|
+
@exclude_hosts = []
|
12
|
+
@exclude_routes = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def should_log_route?(path, host = nil)
|
16
|
+
return false unless enabled && use_middleware
|
17
|
+
return false unless host
|
18
|
+
|
19
|
+
# Only log if host is in allowed list
|
20
|
+
allowed_hosts.include?(host)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'generators/api_logger/install/install_generator'
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module ApiLogger
|
2
|
+
class Middleware
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
# Apply our patch only if not already applied
|
9
|
+
unless Net::HTTP.method_defined?(:request_with_api_logger)
|
10
|
+
apply_http_patch
|
11
|
+
end
|
12
|
+
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def apply_http_patch
|
19
|
+
Net::HTTP.class_eval do
|
20
|
+
# Only patch if we haven't already
|
21
|
+
unless method_defined?(:request_with_api_logger)
|
22
|
+
# Keep reference to the current 'request' method, which might already be patched by Sentry
|
23
|
+
alias_method :request_without_api_logger, :request
|
24
|
+
|
25
|
+
# Define our wrapper method
|
26
|
+
def request_with_api_logger(req, body = nil, &block)
|
27
|
+
# Skip if we're already processing a request
|
28
|
+
if Thread.current[:api_logger_active]
|
29
|
+
return request_without_api_logger(req, body, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
Thread.current[:api_logger_active] = true
|
33
|
+
begin
|
34
|
+
# Call the existing chain (which might include Sentry's instrumentation)
|
35
|
+
response = request_without_api_logger(req, body, &block)
|
36
|
+
|
37
|
+
# Extract the actual host from the request
|
38
|
+
host = extract_host(req)
|
39
|
+
path = req.path
|
40
|
+
|
41
|
+
if ApiLogger.configuration.should_log_route?(path, host)
|
42
|
+
ApiLogger.log(
|
43
|
+
endpoint: path,
|
44
|
+
http_method: req.method,
|
45
|
+
request_params: req.body || body,
|
46
|
+
request_headers: req.each_header.to_h,
|
47
|
+
response_body: response.body,
|
48
|
+
response_headers: response.each_header.to_h,
|
49
|
+
response_status: response.code.to_i
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
response
|
54
|
+
rescue => e
|
55
|
+
# Log errors
|
56
|
+
host = extract_host(req)
|
57
|
+
path = req.path
|
58
|
+
|
59
|
+
if ApiLogger.configuration.should_log_route?(path, host)
|
60
|
+
ApiLogger.log(
|
61
|
+
endpoint: path,
|
62
|
+
http_method: req.method,
|
63
|
+
request_params: req.body || body,
|
64
|
+
request_headers: req.each_header.to_h,
|
65
|
+
error_message: e.message
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
raise
|
70
|
+
ensure
|
71
|
+
Thread.current[:api_logger_active] = nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Complete the method chain
|
76
|
+
alias_method :request, :request_with_api_logger
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def extract_host(req)
|
81
|
+
# Try to get host from URI first
|
82
|
+
if req.uri
|
83
|
+
return req.uri.host
|
84
|
+
end
|
85
|
+
|
86
|
+
# Fallback to host header or address
|
87
|
+
req['host'] || self.address
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'api_logger/middleware'
|
3
|
+
|
4
|
+
module ApiLogger
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
rake_tasks do
|
7
|
+
load "tasks/api_logger_tasks.rake"
|
8
|
+
end
|
9
|
+
|
10
|
+
generators do
|
11
|
+
require "generators/api_logger/install/install_generator"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Define the model class when Rails initializes
|
15
|
+
config.before_initialize do
|
16
|
+
# Create ApiLog constant if it doesn't exist
|
17
|
+
unless Object.const_defined?('ApiLog')
|
18
|
+
Object.const_set('ApiLog', Class.new(ActiveRecord::Base) do
|
19
|
+
self.table_name = ApiLogger.configuration.table_name
|
20
|
+
|
21
|
+
# Add some useful scopes
|
22
|
+
scope :recent, -> { order(created_at: :desc) }
|
23
|
+
scope :failed, -> { where('response_status >= ?', 400) }
|
24
|
+
scope :successful, -> { where('response_status < ?', 400) }
|
25
|
+
end)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Load middleware as early as possible
|
30
|
+
initializer "api_logger.configure_middleware", before: :load_config_initializers do |app|
|
31
|
+
if ApiLogger.configuration.enabled && ApiLogger.configuration.use_middleware
|
32
|
+
app.middleware.use ApiLogger::Middleware
|
33
|
+
|
34
|
+
# Apply the patch immediately
|
35
|
+
unless Net::HTTP.method_defined?(:request_with_api_logger)
|
36
|
+
middleware = ApiLogger::Middleware.new(-> (env) { [200, {}, []] })
|
37
|
+
middleware.send(:apply_http_patch)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/api_logger.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'api_logger/version'
|
2
|
+
require 'api_logger/configuration'
|
3
|
+
require 'api_logger/middleware'
|
4
|
+
require 'api_logger/railtie' if defined?(Rails)
|
5
|
+
require 'api_logger/generators' if defined?(Rails)
|
6
|
+
|
7
|
+
# :nodoc:
|
8
|
+
module ApiLogger
|
9
|
+
class Error < StandardError; end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_writer :configuration
|
13
|
+
|
14
|
+
def configuration
|
15
|
+
@configuration ||= Configuration.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def configure
|
19
|
+
yield(configuration)
|
20
|
+
end
|
21
|
+
|
22
|
+
def config
|
23
|
+
configuration
|
24
|
+
end
|
25
|
+
|
26
|
+
def log(endpoint:, http_method: nil, request_headers: nil, request_params: nil, response_body: nil,
|
27
|
+
response_headers: nil, response_status: nil, error_message: nil)
|
28
|
+
return unless configuration.enabled
|
29
|
+
|
30
|
+
request_params = prepare_params(request_params)
|
31
|
+
request_headers = prepare_headers(request_headers)
|
32
|
+
response_body = prepare_response(response_body)
|
33
|
+
response_headers = prepare_headers(response_headers)
|
34
|
+
|
35
|
+
# Create the log entry
|
36
|
+
klass = get_model_class
|
37
|
+
klass.create(
|
38
|
+
endpoint: endpoint.to_s,
|
39
|
+
http_method: http_method,
|
40
|
+
request_headers: request_headers,
|
41
|
+
request_params: request_params,
|
42
|
+
response_body: response_body,
|
43
|
+
response_headers: response_headers,
|
44
|
+
response_status: response_status,
|
45
|
+
error_message: error_message
|
46
|
+
)
|
47
|
+
rescue StandardError => e
|
48
|
+
Rails.logger.error("ApiLogger failed to log request: #{e.message}") if defined?(Rails)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def prepare_headers(headers)
|
54
|
+
return nil if headers.nil?
|
55
|
+
|
56
|
+
headers.to_h if headers.respond_to?(:to_h)
|
57
|
+
end
|
58
|
+
|
59
|
+
def prepare_params(params)
|
60
|
+
return nil if params.nil?
|
61
|
+
|
62
|
+
params = params.to_h if params.respond_to?(:to_h)
|
63
|
+
params
|
64
|
+
end
|
65
|
+
|
66
|
+
def prepare_response(response)
|
67
|
+
return nil if response.nil?
|
68
|
+
|
69
|
+
case response
|
70
|
+
when String
|
71
|
+
begin
|
72
|
+
JSON.parse(response)
|
73
|
+
rescue StandardError
|
74
|
+
response
|
75
|
+
end
|
76
|
+
else
|
77
|
+
response
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_model_class
|
82
|
+
# Dynamically define model class if it doesn't exist
|
83
|
+
model_name = configuration.table_name.classify
|
84
|
+
|
85
|
+
begin
|
86
|
+
model_name.constantize
|
87
|
+
rescue NameError
|
88
|
+
# Define the model class dynamically
|
89
|
+
Object.const_set(model_name, Class.new(ActiveRecord::Base) do
|
90
|
+
self.table_name = ApiLogger.configuration.table_name
|
91
|
+
end)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
module ApiLogger
|
5
|
+
module Generators
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
|
9
|
+
source_root File.expand_path('templates', __dir__)
|
10
|
+
|
11
|
+
def self.next_migration_number(dirname)
|
12
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_migration
|
16
|
+
template(
|
17
|
+
'create_api_logs.rb.tt',
|
18
|
+
"db/migrate/#{next_migration_number}_create_#{ApiLogger.config.table_name}.rb"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def next_migration_number
|
25
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Create<%= ApiLogger.config.table_name.camelize %> < ActiveRecord::Migration<%= Rails::VERSION::MAJOR >= 5 ? "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" : "" %>
|
2
|
+
def change
|
3
|
+
create_table :<%= ApiLogger.config.table_name %> do |t|
|
4
|
+
t.string :endpoint, null: false
|
5
|
+
t.string :http_method
|
6
|
+
t.jsonb :request_params
|
7
|
+
t.jsonb :request_headers
|
8
|
+
t.jsonb :response_headers
|
9
|
+
t.jsonb :response_body
|
10
|
+
t.integer :response_status
|
11
|
+
t.string :error_message
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :<%= ApiLogger.config.table_name %>, :endpoint
|
16
|
+
add_index :<%= ApiLogger.config.table_name %>, :http_method
|
17
|
+
add_index :<%= ApiLogger.config.table_name %>, :created_at
|
18
|
+
add_index :<%= ApiLogger.config.table_name %>, :response_status
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
namespace :api_logger do
|
2
|
+
desc "Clean up logs older than a specified age (default: 30 days)"
|
3
|
+
task clean: :environment do
|
4
|
+
days = ENV['DAYS'] || 30
|
5
|
+
table_name = ApiLogger.config.table_name
|
6
|
+
model = ApiLogger.send(:get_model_class)
|
7
|
+
|
8
|
+
deleted = model.where('created_at < ?', Time.now - days.to_i.days).delete_all
|
9
|
+
puts "Deleted #{deleted} records from #{table_name} older than #{days} days"
|
10
|
+
end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: api_logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ashish Rao
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-04-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.57'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.57'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.22'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.22'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webmock
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.19'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.19'
|
111
|
+
description: Logs API requests and responses to a database table for monitoring and
|
112
|
+
debugging
|
113
|
+
email:
|
114
|
+
- ashish.r@superlinearinsights.com
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- Gemfile
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- lib/api_logger.rb
|
124
|
+
- lib/api_logger/configuration.rb
|
125
|
+
- lib/api_logger/generators.rb
|
126
|
+
- lib/api_logger/middleware.rb
|
127
|
+
- lib/api_logger/railtie.rb
|
128
|
+
- lib/api_logger/version.rb
|
129
|
+
- lib/generators/api_logger/install/install_generator.rb
|
130
|
+
- lib/generators/api_logger/install/templates/create_api_logs.rb.tt
|
131
|
+
- lib/tasks/api_logger_tasks.rake
|
132
|
+
homepage: https://github.com/Superlinear-Insights/api_logger
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubygems_version: 3.3.7
|
152
|
+
signing_key:
|
153
|
+
specification_version: 4
|
154
|
+
summary: Simple API request/response logger for Rails applications
|
155
|
+
test_files: []
|