Skip to content

Commit 169866a

Browse files
authored
Merge pull request #459 from Dynamoid/add-log-formatter-config-option
Log formatting
2 parents ba039e7 + b2adbee commit 169866a

File tree

7 files changed

+159
-5
lines changed

7 files changed

+159
-5
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,7 @@ Listed below are all configuration options.
10691069
* `models_dir` - `dynamoid:create_tables` rake task loads DynamoDb
10701070
models from this directory. Default is `./app/models`.
10711071
* `application_timezone` - Dynamoid converts all `datetime` fields to
1072-
* specified time zone when loads data from the storage.
1072+
specified time zone when loads data from the storage.
10731073
Acceptable values - `:utc`, `:local` (to use system time zone) and
10741074
time zone name e.g. `Eastern Time (US & Canada)`. Default is `utc`
10751075
* `dynamodb_timezone` - When a datetime field is stored in string format
@@ -1089,6 +1089,11 @@ Listed below are all configuration options.
10891089
`nil`
10901090
* `backoff_strategies`: is a hash and contains all available strategies.
10911091
Default is { constant: ..., exponential: ...}
1092+
* `log_formatter`: overrides default AWS SDK formatter. There are
1093+
several canned formatters: `Aws::Log::Formatter.default`,
1094+
`Aws::Log::Formatter.colored` and `Aws::Log::Formatter.short`. Please
1095+
look into `Aws::Log::Formatter` AWS SDK documentation in order to
1096+
provide own formatter.
10921097
* `http_continue_timeout`: The number of seconds to wait for a
10931098
100-continue HTTP response before sending the request body. Default
10941099
option value is `nil`. If not specified effected value is `1`

lib/dynamoid/adapter_plugin/aws_sdk_v3.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,14 @@ def connection_config
109109
end
110110
end
111111

112-
# https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/plugins/logging.rb
113-
# https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/log/formatter.rb
114-
formatter = Aws::Log::Formatter.new(':operation | Request :http_request_body | Response :http_response_body')
115112
@connection_hash[:logger] = Dynamoid::Config.logger
116113
@connection_hash[:log_level] = :debug
117-
@connection_hash[:log_formatter] = formatter
114+
115+
# https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/plugins/logging.rb
116+
# https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/log/formatter.rb
117+
if Dynamoid::Config.log_formatter
118+
@connection_hash[:log_formatter] = Dynamoid::Config.log_formatter
119+
end
118120

119121
@connection_hash
120122
end

lib/dynamoid/config.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ module Config
5454
constant: BackoffStrategies::ConstantBackoff,
5555
exponential: BackoffStrategies::ExponentialBackoff
5656
}
57+
option :log_formatter, default: nil
5758
option :http_continue_timeout, default: nil # specify if you'd like to overwrite Aws Configure - default: 1
5859
option :http_idle_timeout, default: nil # - default: 5
5960
option :http_open_timeout, default: nil # - default: 15

lib/dynamoid/log/formatter.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module Dynamoid
2+
module Log
3+
module Formatter
4+
5+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Log/Formatter.html
6+
# https://docs.aws.amazon.com/sdk-for-ruby/v2/api/Seahorse/Client/Response.html
7+
# https://aws.amazon.com/ru/blogs/developer/logging-requests/
8+
class Debug
9+
def format(response)
10+
bold = "\x1b[1m"
11+
color = "\x1b[34m"
12+
reset = "\x1b[0m"
13+
14+
[
15+
response.context.operation.name,
16+
"#{bold}#{color}\nRequest:\n#{reset}#{bold}",
17+
JSON.pretty_generate(JSON.parse(response.context.http_request.body.string)),
18+
"#{bold}#{color}\nResponse:\n#{reset}#{bold}",
19+
JSON.pretty_generate(JSON.parse(response.context.http_response.body.string)),
20+
reset
21+
].join("\n")
22+
end
23+
end
24+
end
25+
end
26+
end

spec/dynamoid/config_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,30 @@
2626
expect(credentials.secret_access_key).to eq 'your_secret_access_key'
2727
end
2828
end
29+
30+
describe 'log_formatter' do
31+
let(:log_formatter) { Aws::Log::Formatter.short }
32+
let(:logger) { Logger.new(buffer) }
33+
let(:buffer) { StringIO.new }
34+
35+
before do
36+
@log_formatter = Dynamoid.config.log_formatter
37+
@logger = Dynamoid.config.logger
38+
39+
Dynamoid.config.log_formatter = log_formatter
40+
Dynamoid.config.logger = logger
41+
Dynamoid.adapter.connect! # clear cached client
42+
end
43+
44+
after do
45+
Dynamoid.config.log_formatter = @log_formatter
46+
Dynamoid.config.logger = @logger
47+
Dynamoid.adapter.connect! # clear cached client
48+
end
49+
50+
it 'changes logging format' do
51+
new_class.create_table
52+
expect(buffer.string).to match(/\[Aws::DynamoDB::Client 200 .+\] create_table \n/)
53+
end
54+
end
2955
end
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
require 'spec_helper'
2+
require 'dynamoid/log/formatter'
3+
4+
describe Dynamoid::Log::Formatter::Debug do
5+
describe '#format' do
6+
let(:subject) { described_class.new }
7+
8+
let(:logger) { Logger.new(buffer) }
9+
let(:buffer) { StringIO.new }
10+
11+
let(:request) do
12+
<<~JSON
13+
{
14+
"TableName": "dynamoid_tests_items",
15+
"KeySchema": [
16+
{
17+
"AttributeName": "id",
18+
"KeyType": "HASH"
19+
}
20+
],
21+
"AttributeDefinitions": [
22+
{
23+
"AttributeName": "id",
24+
"AttributeType": "S"
25+
}
26+
],
27+
"BillingMode": "PROVISIONED",
28+
"ProvisionedThroughput": {
29+
"ReadCapacityUnits": 100,
30+
"WriteCapacityUnits": 20
31+
}
32+
}
33+
JSON
34+
end
35+
36+
let(:response_pattern) do
37+
Regexp.compile <<~JSON
38+
\\{
39+
"TableDescription": \\{
40+
"AttributeDefinitions": \\[
41+
\\{
42+
"AttributeName": "id",
43+
"AttributeType": "S"
44+
\\}
45+
\\],
46+
"TableName": "dynamoid_tests_items",
47+
"KeySchema": \\[
48+
\\{
49+
"AttributeName": "id",
50+
"KeyType": "HASH"
51+
\\}
52+
\\],
53+
"TableStatus": "ACTIVE",
54+
"CreationDateTime": .+?,
55+
"ProvisionedThroughput": \\{
56+
"LastIncreaseDateTime": 0.0,
57+
"LastDecreaseDateTime": 0.0,
58+
"NumberOfDecreasesToday": 0,
59+
"ReadCapacityUnits": 100,
60+
"WriteCapacityUnits": 20
61+
\\},
62+
"TableSizeBytes": 0,
63+
"ItemCount": 0,
64+
"TableArn": ".+?"
65+
\\}
66+
\\}
67+
JSON
68+
end
69+
70+
before do
71+
@log_formatter = Dynamoid.config.log_formatter
72+
@logger = Dynamoid.config.logger
73+
74+
Dynamoid.config.log_formatter = subject
75+
Dynamoid.config.logger = logger
76+
Dynamoid.adapter.connect! # clear cached client
77+
end
78+
79+
after do
80+
Dynamoid.config.log_formatter = @log_formatter
81+
Dynamoid.config.logger = @logger
82+
Dynamoid.adapter.connect! # clear cached client
83+
end
84+
85+
it 'logs request and response JSON body' do
86+
new_class(table_name: 'items').create_table
87+
88+
expect(buffer.string).to include(request)
89+
expect(buffer.string).to match(response_pattern)
90+
end
91+
end
92+
end

spec/spec_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
require 'rspec'
1212
require 'dynamoid'
13+
require 'dynamoid/log/formatter'
1314
require 'pry'
1415
require 'byebug' if ENV['DEBUG']
1516

@@ -27,6 +28,7 @@
2728
config.warn_on_scan = false
2829
config.sync_retry_wait_seconds = 0
2930
config.sync_retry_max_times = 3
31+
config.log_formatter = Dynamoid::Log::Formatter::Debug.new
3032
end
3133

3234
Dynamoid.logger.level = Logger::FATAL

0 commit comments

Comments
 (0)