Skip to content

Commit

Permalink
Merge pull request #6 from code0-tech/json-logging
Browse files Browse the repository at this point in the history
Enable json logging
  • Loading branch information
Taucher2003 authored Dec 12, 2023
2 parents 1fd4e7b + b39d247 commit a8513e0
Show file tree
Hide file tree
Showing 26 changed files with 941 additions and 19 deletions.
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ Style/ArgumentsForwarding:
Style/Documentation:
Enabled: false

Style/FormatStringToken:
Exclude:
- spec/tooling/rubocop/**/*

Style/HashSyntax:
EnforcedShorthandSyntax: never

Expand Down
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ group :development, :test do
gem 'shoulda-matchers', '~> 5.3'

gem 'rspec_junit_formatter', '~> 0.6.0', require: false
gem 'rspec-parameterized', '~> 1.0'

gem 'database_cleaner-active_record', '~> 2.1'

Expand All @@ -66,3 +67,5 @@ gem 'graphql', '~> 2.1'
gem 'seed-fu', '~> 2.3'

gem 'sidekiq', '~> 7.1'

gem 'lograge', '~> 0.14.0'
35 changes: 35 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,12 @@ GEM
base64 (0.2.0)
bcrypt (3.1.20)
bigdecimal (3.1.4)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
bootsnap (1.17.0)
msgpack (~> 1.2)
builder (3.2.4)
coderay (1.1.3)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
crass (1.0.6)
Expand All @@ -93,6 +96,7 @@ GEM
debug (1.8.0)
irb (>= 1.5.0)
reline (>= 0.3.1)
debug_inspector (1.1.0)
diff-lcs (1.5.0)
docile (1.4.0)
drb (2.2.0)
Expand All @@ -115,6 +119,11 @@ GEM
reline (>= 0.3.8)
json (2.6.3)
language_server-protocol (3.17.0.3)
lograge (0.14.0)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
Expand Down Expand Up @@ -145,6 +154,10 @@ GEM
ast (~> 2.4.1)
racc
pg (1.5.4)
proc_to_ast (0.1.0)
coderay
parser
unparser
psych (5.1.1.1)
stringio
puma (6.4.0)
Expand Down Expand Up @@ -196,7 +209,13 @@ GEM
regexp_parser (2.8.2)
reline (0.4.1)
io-console (~> 0.5)
request_store (1.5.1)
rack (>= 1.4)
rexml (3.2.6)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
Expand All @@ -205,6 +224,17 @@ GEM
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-parameterized (1.0.0)
rspec-parameterized-core (< 2)
rspec-parameterized-table_syntax (< 2)
rspec-parameterized-core (1.0.0)
parser
proc_to_ast
rspec (>= 2.13, < 4)
unparser
rspec-parameterized-table_syntax (1.0.1)
binding_of_caller
rspec-parameterized-core (< 2)
rspec-rails (6.1.0)
actionpack (>= 6.1)
activesupport (>= 6.1)
Expand Down Expand Up @@ -271,6 +301,9 @@ GEM
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
unparser (0.6.10)
diff-lcs (~> 1.3)
parser (>= 3.2.2.4)
webrick (1.8.1)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
Expand All @@ -287,9 +320,11 @@ DEPENDENCIES
debug
factory_bot_rails (~> 6.2)
graphql (~> 2.1)
lograge (~> 0.14.0)
pg (~> 1.1)
puma (>= 5.0)
rails (~> 7.1.2)
rspec-parameterized (~> 1.0)
rspec-rails (~> 6.0)
rspec_junit_formatter (~> 0.6.0)
rubocop-factory_bot (~> 2.23)
Expand Down
1 change: 1 addition & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true

class ApplicationController < ActionController::API
include Sagittarius::Loggable
end
25 changes: 13 additions & 12 deletions app/controllers/graphql_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,20 @@ def execute
context = {
current_user: current_user,
}
result = SagittariusSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
render json: result
rescue StandardError => e
raise e unless Rails.env.development?

handle_error_in_development(e)
Sagittarius::Context.with_context(user: { id: current_user&.id, username: current_user&.username }) do
result = SagittariusSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
render json: result
rescue StandardError => e
logger.error message: e.message, backtrace: e.backtrace, exception_class: e.class

if Rails.env.local?
render json: { errors: [{ message: e.message, backtrace: e.backtrace }], data: {} },
status: :internal_server_error
else
render json: { message: 'Internal server error' }, status: :internal_server_error
end
end
end
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Metrics/CyclomaticComplexity
Expand All @@ -57,13 +65,6 @@ def prepare_variables(variables_param)
end
end

def handle_error_in_development(e)
logger.error e.message
logger.error e.backtrace.join("\n")

render json: { errors: [{ message: e.message, backtrace: e.backtrace }], data: {} }, status: :internal_server_error
end

def find_authorization(authorization)
return Authorization.new(:none, nil) if authorization.blank?

Expand Down
1 change: 1 addition & 0 deletions app/jobs/application_job.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

class ApplicationJob < ActiveJob::Base
include Sagittarius::Loggable
# Automatically retry jobs that encountered a deadlock
# retry_on ActiveRecord::Deadlocked

Expand Down
23 changes: 23 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ class Application < Rails::Application
# like if you have constraints or database-specific column types
config.active_record.schema_format = :sql

# Enable sql log tags
config.active_record.query_log_tags_enabled = true
config.active_record.query_log_tags = [
:controller,
:job,
{
correlation_id: -> { Sagittarius::Context.correlation_id },
user_id: -> { Sagittarius::Context.current&.[](:user)&.[](:id) },
user_name: -> { Sagittarius::Context.current&.[](:user)&.[](:username) },
application: lambda {
if Rails.const_defined?('Console')
'console'
else
Sagittarius::Context.current&.[](:application) || 'unknown'
end
},
}
]
ActiveRecord::QueryLogs.prepend_comment = true

Rails.application.default_url_options =
if ENV['SAGITTARIUS_RAILS_HOSTNAME'].nil?
{
Expand All @@ -37,6 +57,9 @@ class Application < Rails::Application
# Common ones are `templates`, `generators`, or `middleware`, for example.
config.autoload_lib(ignore: %w[assets tasks])

# Configure active job to use sidekiq
config.active_job.queue_adapter = :sidekiq

# Generated with 'bin/rails db:encryption:init'
# Use some random generated keys, production will override this with the environment variables
config.active_record.encryption.primary_key = ENV.fetch('SAGITTARIUS_DATABASE_ENCRYPTION_PRIMARY_KEY',
Expand Down
3 changes: 2 additions & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'active_support/core_ext/integer/time'
require_relative '../../lib/sagittarius/utils'

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
Expand Down Expand Up @@ -44,7 +45,7 @@
# config.assume_ssl = true

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
config.force_ssl = Sagittarius::Utils.to_boolean(ENV.fetch('RAILS_FORCE_SSL', nil), default: true)

# Log to STDOUT by default
config.logger = ActiveSupport::Logger.new($stdout)
Expand Down
7 changes: 7 additions & 0 deletions config/initializers/context.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

require_relative '../../lib/sagittarius/context'
require_relative '../../lib/sagittarius/middleware/rack'

Rails.application.config.middleware.move(1, ActionDispatch::RequestId)
Rails.application.config.middleware.insert(1, Sagittarius::Middleware::Rack)
2 changes: 1 addition & 1 deletion config/initializers/filter_parameter_logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
# Use this to limit dissemination of sensitive information.
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
Rails.application.config.filter_parameters += %i[
passw secret token _key crypt salt certificate otp ssn
passw secret token _key crypt salt certificate otp ssn query variables
]
13 changes: 13 additions & 0 deletions config/initializers/logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

require_relative '../../lib/sagittarius/logs/json_formatter'

Rails.application.configure do
config.lograge.enabled = true
config.lograge.base_controller_class = 'ActionController::API'
config.lograge.formatter = Lograge::Formatters::Raw.new # let formatting be done by our own formatter
end

Rails.logger.formatter = Sagittarius::Logs::JsonFormatter::Tagged.new

Rails.application.config.colorize_logging = Rails.const_defined? 'Console'
29 changes: 24 additions & 5 deletions config/initializers/sidekiq.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,29 @@

redis_host = "redis://#{redis_host}:#{redis_port}/#{redis_database}"

Sidekiq.configure_server do |config|
config.redis = { url: redis_host }
end
Rails.application.config.to_prepare do
Sidekiq.configure_server do |config|
config.redis = { url: redis_host }
config.server_middleware do |chain|
chain.add Sagittarius::Middleware::Sidekiq::Context::Server
end

config.logger.formatter = Class.new(Sidekiq::Logger::Formatters::Base) do
def call(severity, time, _progname, message)
@formatter ||= Sagittarius::Logs::JsonFormatter.new

data = @formatter.data(severity, time, message)
data.merge!(context: ctx) unless ctx.empty?

Sidekiq.dump_json(data) << "\n"
end
end.new
end

Sidekiq.configure_client do |config|
config.redis = { url: redis_host }
Sidekiq.configure_client do |config|
config.redis = { url: redis_host }
config.client_middleware do |chain|
chain.add Sagittarius::Middleware::Sidekiq::Context::Client
end
end
end
Loading

0 comments on commit a8513e0

Please sign in to comment.