From bf5dc3c47584184f40e849a716d48e412dfd164a Mon Sep 17 00:00:00 2001 From: bogdan Date: Tue, 26 Jan 2021 15:07:50 +0000 Subject: [PATCH 01/19] Added usage instructions to the readme file --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 74f5290..8e7d01a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,18 @@ # json-rails-logger -A custom rails logger that outputs json instead of raw text +A custom rails logger that outputs JSON instead of raw text. As an extra the logger also saves the `request_id` for any log message, in the returned JSON object. The formatter has a couple of changes that are down to preference, but these don't affect the functionality in any way. This gem can be used with any Rails app using the installation steps below. + +## Installation +In your Rails app, add this to your gemfile:\ +`gem 'json_rails_logger', git: 'git@github.com:epimorphics/json-rails-logger.git'` + +And this to your environment config:\ +`config.logger = JsonRailsLogger::Logger.new(STDOUT)` + +## Running the tests +Tests are located in the `./test/` folder. + +After cloning the repo, first execute:\ +`bundle install` + +To run the tests, use:\ +`rake test` \ No newline at end of file From b22849a7480ff2bc2aed685e5ac2250197dac4af Mon Sep 17 00:00:00 2001 From: bogdan Date: Tue, 26 Jan 2021 16:31:30 +0000 Subject: [PATCH 02/19] Added request id to constants file --- lib/json_rails_logger/constants.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 lib/json_rails_logger/constants.rb diff --git a/lib/json_rails_logger/constants.rb b/lib/json_rails_logger/constants.rb new file mode 100644 index 0000000..511718c --- /dev/null +++ b/lib/json_rails_logger/constants.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module JsonRailsLogger + REQUEST_ID = :request_id +end From 3e4be0695ca47a91ea57e4904e2fbde7751b8d0d Mon Sep 17 00:00:00 2001 From: bogdan Date: Tue, 26 Jan 2021 16:31:48 +0000 Subject: [PATCH 03/19] Middleware that saves the request id added --- lib/json_rails_logger/middleware.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 lib/json_rails_logger/middleware.rb diff --git a/lib/json_rails_logger/middleware.rb b/lib/json_rails_logger/middleware.rb new file mode 100644 index 0000000..1999f7c --- /dev/null +++ b/lib/json_rails_logger/middleware.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require_relative 'constants' + +module JsonRailsLogger + # Middleware that saves the request_id into a constant + # and clears it after usage in the formatter + class Middleware + def initialize(app) + @app = app + end + + def call(env) + request_id = env['action_dispatch.request_id'] + Thread.current[JsonRailsLogger::REQUEST_ID] = request_id + @app.call(env) + ensure + Thread.current[JsonRailsLogger::REQUEST_ID] = nil + end + end +end From ac7092393000f5ebf34af942a2db6167b5eee5c1 Mon Sep 17 00:00:00 2001 From: bogdan Date: Tue, 26 Jan 2021 16:33:05 +0000 Subject: [PATCH 04/19] New middleware added to the rack using the railtie --- lib/json_rails_logger/railtie.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/json_rails_logger/railtie.rb b/lib/json_rails_logger/railtie.rb index a79439b..654eeeb 100644 --- a/lib/json_rails_logger/railtie.rb +++ b/lib/json_rails_logger/railtie.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require_relative 'middleware' + module JsonRailsLogger # This class is used to configure and setup lograge, as well as our gem class Railtie < Rails::Railtie @@ -15,5 +17,10 @@ class Railtie < Rails::Railtie JsonRailsLogger.setup(app) if JsonRailsLogger.enabled?(app) Lograge.setup(app) if JsonRailsLogger.enabled?(app) end + + initializer 'railtie.configure_rails_initialization' do |app| + app.middleware.insert_after ActionDispatch::RequestId, + JsonRailsLogger::Middleware + end end end From 37db2c22c8e050598625048789287529bc1b6aa0 Mon Sep 17 00:00:00 2001 From: bogdan Date: Tue, 26 Jan 2021 16:34:00 +0000 Subject: [PATCH 05/19] Adding request id in the json log message via formatter --- lib/json_rails_logger/json_formatter.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/json_rails_logger/json_formatter.rb b/lib/json_rails_logger/json_formatter.rb index f74ce32..951350a 100644 --- a/lib/json_rails_logger/json_formatter.rb +++ b/lib/json_rails_logger/json_formatter.rb @@ -8,11 +8,10 @@ def call(severity, timestamp, _progname, raw_msg) timestp = process_timestamp(timestamp) msg = process_message(raw_msg) - payload = { - level: sev, - timestamp: timestp, - rails_environment: ::Rails.env - } + payload = { level: sev, + timestamp: timestp, + rails_environment: ::Rails.env, + request_id: Thread.current[JsonRailsLogger::REQUEST_ID] } payload.merge!(msg) From 3b293bfb5d664f03807673d4156913085ca42a45 Mon Sep 17 00:00:00 2001 From: bogdan Date: Wed, 27 Jan 2021 14:38:00 +0000 Subject: [PATCH 06/19] Renamed middleware to more suggestive name --- lib/json_rails_logger/railtie.rb | 6 +++--- .../{middleware.rb => request_id_middleware.rb} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename lib/json_rails_logger/{middleware.rb => request_id_middleware.rb} (94%) diff --git a/lib/json_rails_logger/railtie.rb b/lib/json_rails_logger/railtie.rb index 654eeeb..436389a 100644 --- a/lib/json_rails_logger/railtie.rb +++ b/lib/json_rails_logger/railtie.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative 'middleware' +require_relative 'request_id_middleware' module JsonRailsLogger # This class is used to configure and setup lograge, as well as our gem @@ -19,8 +19,8 @@ class Railtie < Rails::Railtie end initializer 'railtie.configure_rails_initialization' do |app| - app.middleware.insert_after ActionDispatch::RequestId, - JsonRailsLogger::Middleware + app.middleware.insert_after(ActionDispatch::RequestId, + JsonRailsLogger::RequestIdMiddleware) end end end diff --git a/lib/json_rails_logger/middleware.rb b/lib/json_rails_logger/request_id_middleware.rb similarity index 94% rename from lib/json_rails_logger/middleware.rb rename to lib/json_rails_logger/request_id_middleware.rb index 1999f7c..c18c92b 100644 --- a/lib/json_rails_logger/middleware.rb +++ b/lib/json_rails_logger/request_id_middleware.rb @@ -5,7 +5,7 @@ module JsonRailsLogger # Middleware that saves the request_id into a constant # and clears it after usage in the formatter - class Middleware + class RequestIdMiddleware def initialize(app) @app = app end From c3ee34ba236bcb17a634775eaf31c2ea94386eba Mon Sep 17 00:00:00 2001 From: bogdan Date: Wed, 27 Jan 2021 15:14:48 +0000 Subject: [PATCH 07/19] Refactored request id feature in the formatter It also now guards against nil values --- lib/json_rails_logger/json_formatter.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/json_rails_logger/json_formatter.rb b/lib/json_rails_logger/json_formatter.rb index 951350a..aab14bc 100644 --- a/lib/json_rails_logger/json_formatter.rb +++ b/lib/json_rails_logger/json_formatter.rb @@ -10,10 +10,10 @@ def call(severity, timestamp, _progname, raw_msg) payload = { level: sev, timestamp: timestp, - rails_environment: ::Rails.env, - request_id: Thread.current[JsonRailsLogger::REQUEST_ID] } + rails_environment: ::Rails.env } - payload.merge!(msg) + parload.merge!(x_request_id.to_h) + payload.merge!(msg.to_h) "#{payload.to_json}\n" end @@ -28,6 +28,11 @@ def process_timestamp(timestamp) format_datetime(timestamp) end + def x_request_id + x_request_id = Thread.current[JsonRailsLogger::REQUEST_ID] + { 'x-request-id': x_request_id } if x_request_id + end + def process_message(raw_msg) msg = normalize_message(raw_msg) From f57807d0a7ecb947a225f266276181bc61910883 Mon Sep 17 00:00:00 2001 From: bogdan Date: Wed, 27 Jan 2021 15:16:10 +0000 Subject: [PATCH 08/19] Small fix --- lib/json_rails_logger/json_formatter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json_rails_logger/json_formatter.rb b/lib/json_rails_logger/json_formatter.rb index aab14bc..b2015a2 100644 --- a/lib/json_rails_logger/json_formatter.rb +++ b/lib/json_rails_logger/json_formatter.rb @@ -12,7 +12,7 @@ def call(severity, timestamp, _progname, raw_msg) timestamp: timestp, rails_environment: ::Rails.env } - parload.merge!(x_request_id.to_h) + payload.merge!(x_request_id.to_h) payload.merge!(msg.to_h) "#{payload.to_json}\n" From affb2184791a15e602827fd26f9344be23ba1f4c Mon Sep 17 00:00:00 2001 From: Bogdan-Adrian Marc Date: Wed, 27 Jan 2021 16:43:19 +0000 Subject: [PATCH 09/19] Added MIT license --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1728b69 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Epimorphics Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 9e8f338cd7f9c860604fb33d98cf5f94f7a5383b Mon Sep 17 00:00:00 2001 From: bogdan Date: Thu, 28 Jan 2021 18:49:01 +0000 Subject: [PATCH 10/19] Changelog file added --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..23f8e93 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog for the JSON Rails Logger gem + +## 0.1.0 - 2021-01-26 (Bogdan) + +- This is an initial release, contains a simple JSON Rails Logger + with some customisation applied to it From 877e7fc8583502ddfe575623262d004de557e632 Mon Sep 17 00:00:00 2001 From: bogdan Date: Thu, 28 Jan 2021 20:26:24 +0000 Subject: [PATCH 11/19] Added common keys array --- lib/json_rails_logger/json_formatter.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/json_rails_logger/json_formatter.rb b/lib/json_rails_logger/json_formatter.rb index b2015a2..8b97b41 100644 --- a/lib/json_rails_logger/json_formatter.rb +++ b/lib/json_rails_logger/json_formatter.rb @@ -3,6 +3,10 @@ module JsonRailsLogger # This class is the json formatter for our logger class JsonFormatter < ::Logger::Formatter + COMMON_KEYS = %w[ + method path status duration + ].freeze + def call(severity, timestamp, _progname, raw_msg) sev = process_severity(severity) timestp = process_timestamp(timestamp) From 761c13d636b5a2137f59050b1e8c48cf13aeb13f Mon Sep 17 00:00:00 2001 From: bogdan Date: Thu, 28 Jan 2021 20:27:19 +0000 Subject: [PATCH 12/19] Further message formatting added --- lib/json_rails_logger/json_formatter.rb | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/json_rails_logger/json_formatter.rb b/lib/json_rails_logger/json_formatter.rb index 8b97b41..71118d5 100644 --- a/lib/json_rails_logger/json_formatter.rb +++ b/lib/json_rails_logger/json_formatter.rb @@ -11,13 +11,13 @@ def call(severity, timestamp, _progname, raw_msg) sev = process_severity(severity) timestp = process_timestamp(timestamp) msg = process_message(raw_msg) + new_msg = format_message(msg) payload = { level: sev, - timestamp: timestp, - rails_environment: ::Rails.env } + timestamp: timestp } payload.merge!(x_request_id.to_h) - payload.merge!(msg.to_h) + payload.merge!(new_msg.to_h) "#{payload.to_json}\n" end @@ -49,6 +49,24 @@ def process_message(raw_msg) { message: msg.strip } end + def format_message(msg) + new_msg = { rails: { environment: ::Rails.env } } + + return msg.merge(new_msg) if msg.is_a?(Hash) && + msg.length == 1 && + msg.fetch(:message, nil).is_a?(String) + + is_key_common = ->(k, _v) { COMMON_KEYS.include?(k) } + + common_keys = msg.select(&is_key_common) + uncommon_keys = msg.reject(&is_key_common) + + new_msg.merge!(common_keys) + new_msg[:rails].merge!(uncommon_keys) + + new_msg + end + def normalize_message(raw_msg) return raw_msg unless raw_msg.is_a?(String) From dd08350feed7b5bfc208f1232d451a3acf7bfdb3 Mon Sep 17 00:00:00 2001 From: bogdan Date: Fri, 29 Jan 2021 10:41:36 +0000 Subject: [PATCH 13/19] Using partition instead of select --- lib/json_rails_logger/json_formatter.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/json_rails_logger/json_formatter.rb b/lib/json_rails_logger/json_formatter.rb index 71118d5..adc43e3 100644 --- a/lib/json_rails_logger/json_formatter.rb +++ b/lib/json_rails_logger/json_formatter.rb @@ -56,13 +56,13 @@ def format_message(msg) msg.length == 1 && msg.fetch(:message, nil).is_a?(String) - is_key_common = ->(k, _v) { COMMON_KEYS.include?(k) } + split_msg = msg.partition { |k, _v| COMMON_KEYS.include?(k) }.map(&:to_h) - common_keys = msg.select(&is_key_common) - uncommon_keys = msg.reject(&is_key_common) + new_msg.merge!(split_msg[0]) + new_msg[:rails].merge!(split_msg[1]) - new_msg.merge!(common_keys) - new_msg[:rails].merge!(uncommon_keys) + new_msg + end new_msg end From 1724ac6f7a69173f65a6c259dd38799028315fd3 Mon Sep 17 00:00:00 2001 From: bogdan Date: Fri, 29 Jan 2021 10:45:15 +0000 Subject: [PATCH 14/19] Refactoring return condition to method --- lib/json_rails_logger/json_formatter.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/json_rails_logger/json_formatter.rb b/lib/json_rails_logger/json_formatter.rb index adc43e3..9ab3568 100644 --- a/lib/json_rails_logger/json_formatter.rb +++ b/lib/json_rails_logger/json_formatter.rb @@ -52,9 +52,7 @@ def process_message(raw_msg) def format_message(msg) new_msg = { rails: { environment: ::Rails.env } } - return msg.merge(new_msg) if msg.is_a?(Hash) && - msg.length == 1 && - msg.fetch(:message, nil).is_a?(String) + return msg.merge(new_msg) if string_message_field?(msg) split_msg = msg.partition { |k, _v| COMMON_KEYS.include?(k) }.map(&:to_h) @@ -64,7 +62,10 @@ def format_message(msg) new_msg end - new_msg + def string_message_field?(msg) + msg.is_a?(Hash) && + msg.length == 1 && + msg.fetch(:message, nil).is_a?(String) end def normalize_message(raw_msg) From add10e0fc5d7c9fa7e932a891e9f2a7f8329f518 Mon Sep 17 00:00:00 2001 From: bogdan Date: Fri, 29 Jan 2021 19:37:48 +0000 Subject: [PATCH 15/19] Tests related fix --- lib/json_rails_logger/json_formatter.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/json_rails_logger/json_formatter.rb b/lib/json_rails_logger/json_formatter.rb index 9ab3568..71c42b6 100644 --- a/lib/json_rails_logger/json_formatter.rb +++ b/lib/json_rails_logger/json_formatter.rb @@ -54,7 +54,8 @@ def format_message(msg) return msg.merge(new_msg) if string_message_field?(msg) - split_msg = msg.partition { |k, _v| COMMON_KEYS.include?(k) }.map(&:to_h) + split_msg = msg.partition { |k, _v| COMMON_KEYS.include?(k.to_s) } + .map(&:to_h) new_msg.merge!(split_msg[0]) new_msg[:rails].merge!(split_msg[1]) From 853d822e950406cf404868343c59fe61eec39b63 Mon Sep 17 00:00:00 2001 From: bogdan Date: Fri, 29 Jan 2021 19:38:10 +0000 Subject: [PATCH 16/19] Fixed unit tests --- test/formatter_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/formatter_test.rb b/test/formatter_test.rb index b26ca58..79d9ab8 100644 --- a/test/formatter_test.rb +++ b/test/formatter_test.rb @@ -52,8 +52,8 @@ _(log_output).must_be_kind_of(String) json_output = JSON.parse(log_output) - _(json_output['user_agent']).must_equal('Faraday v1.3.0') - _(json_output['accept']).must_equal('application/json') + _(json_output['rails']['user_agent']).must_equal('Faraday v1.3.0') + _(json_output['rails']['accept']).must_equal('application/json') end it 'should correctly format the timestamp' do From aa36008bf15b69b88ecb8632ed49977549e7bf5f Mon Sep 17 00:00:00 2001 From: bogdan Date: Mon, 1 Feb 2021 16:46:19 +0000 Subject: [PATCH 17/19] Fixed some readme issues --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e7d01a..f3883c4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,13 @@ # json-rails-logger -A custom rails logger that outputs JSON instead of raw text. As an extra the logger also saves the `request_id` for any log message, in the returned JSON object. The formatter has a couple of changes that are down to preference, but these don't affect the functionality in any way. This gem can be used with any Rails app using the installation steps below. + +A custom rails logger that outputs JSON instead of raw text. As an extra the +logger also saves the `request_id` for any log message, in the returned JSON +object. The formatter has a couple of changes that are down to preference, but +these don't affect the functionality in any way. This gem can be used with any +Rails app using the installation steps below. ## Installation + In your Rails app, add this to your gemfile:\ `gem 'json_rails_logger', git: 'git@github.com:epimorphics/json-rails-logger.git'` @@ -9,10 +15,11 @@ And this to your environment config:\ `config.logger = JsonRailsLogger::Logger.new(STDOUT)` ## Running the tests + Tests are located in the `./test/` folder. After cloning the repo, first execute:\ `bundle install` To run the tests, use:\ -`rake test` \ No newline at end of file +`rake test` From 36fcbfa7053b8aab2f47c0c7ace7fc5c3f5bd965 Mon Sep 17 00:00:00 2001 From: bogdan Date: Mon, 1 Feb 2021 16:46:42 +0000 Subject: [PATCH 18/19] Bumped app version --- Gemfile.lock | 2 +- lib/json_rails_logger/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5cf6eec..4f84051 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - json_rails_logger (0.1.0) + json_rails_logger (0.2.0) json lograge railties diff --git a/lib/json_rails_logger/version.rb b/lib/json_rails_logger/version.rb index ffd0cc1..6522c83 100644 --- a/lib/json_rails_logger/version.rb +++ b/lib/json_rails_logger/version.rb @@ -2,7 +2,7 @@ module JsonRailsLogger MAJOR = 0 - MINOR = 1 + MINOR = 2 FIX = 0 VERSION = "#{MAJOR}.#{MINOR}.#{FIX}" end From b9e9de8704b1db3c1206e99c8030d45ddd653c7a Mon Sep 17 00:00:00 2001 From: bogdan Date: Mon, 1 Feb 2021 16:46:55 +0000 Subject: [PATCH 19/19] Added changelog entry with new changes --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f8e93..971b567 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog for the JSON Rails Logger gem +## 0.2.0 - 2021-02-01 (Bogdan) + +- Platform related fields are now grouped together inside the 'rails' field +- Request ID is now present in every log message +- MIT license file added to the repo +- Added readme file with usage instructions + ## 0.1.0 - 2021-01-26 (Bogdan) - This is an initial release, contains a simple JSON Rails Logger