mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 03:03:44 +08:00
EXPERIMENTAL: Allow logs to be shipped via different methods.
See https://github.com/dwbutler/logstash-logger#uri-configuration for a list of available methods.
This commit is contained in:
parent
0d8e9a88c9
commit
89d9ffa884
1
Gemfile
1
Gemfile
|
@ -174,6 +174,7 @@ gem 'cppjieba_rb', require: false
|
||||||
|
|
||||||
gem 'lograge', require: false
|
gem 'lograge', require: false
|
||||||
gem 'logstash-event', require: false
|
gem 'logstash-event', require: false
|
||||||
|
gem 'logstash-logger', require: false
|
||||||
gem 'logster'
|
gem 'logster'
|
||||||
|
|
||||||
gem 'sassc', require: false
|
gem 'sassc', require: false
|
||||||
|
|
|
@ -156,6 +156,8 @@ GEM
|
||||||
railties (>= 4, < 5.2)
|
railties (>= 4, < 5.2)
|
||||||
request_store (~> 1.0)
|
request_store (~> 1.0)
|
||||||
logstash-event (1.2.02)
|
logstash-event (1.2.02)
|
||||||
|
logstash-logger (0.25.1)
|
||||||
|
logstash-event (~> 1.2)
|
||||||
logster (1.2.8)
|
logster (1.2.8)
|
||||||
loofah (2.1.1)
|
loofah (2.1.1)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
|
@ -440,6 +442,7 @@ DEPENDENCIES
|
||||||
listen
|
listen
|
||||||
lograge
|
lograge
|
||||||
logstash-event
|
logstash-event
|
||||||
|
logstash-logger
|
||||||
logster
|
logster
|
||||||
lru_redux
|
lru_redux
|
||||||
mail
|
mail
|
||||||
|
|
|
@ -8,8 +8,6 @@ if (Rails.env.production? && SiteSetting.logging_provider == 'lograge') || ENV["
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
config.lograge.enabled = true
|
config.lograge.enabled = true
|
||||||
|
|
||||||
logstash_formatter = ENV["LOGSTASH_FORMATTER"]
|
|
||||||
|
|
||||||
config.lograge.custom_options = lambda do |event|
|
config.lograge.custom_options = lambda do |event|
|
||||||
exceptions = %w(controller action format id)
|
exceptions = %w(controller action format id)
|
||||||
|
|
||||||
|
@ -21,12 +19,17 @@ if (Rails.env.production? && SiteSetting.logging_provider == 'lograge') || ENV["
|
||||||
database: RailsMultisite::ConnectionManagement.current_db,
|
database: RailsMultisite::ConnectionManagement.current_db,
|
||||||
}
|
}
|
||||||
|
|
||||||
output[:time] = event.time unless logstash_formatter
|
|
||||||
output
|
output
|
||||||
end
|
end
|
||||||
|
|
||||||
if logstash_formatter
|
if ENV["LOGSTASH_URI"]
|
||||||
config.lograge.formatter = Lograge::Formatters::Logstash.new
|
config.lograge.formatter = Lograge::Formatters::Logstash.new
|
||||||
|
|
||||||
|
require 'discourse_logstash_logger'
|
||||||
|
|
||||||
|
config.lograge.logger = DiscourseLogstashLogger.logger(
|
||||||
|
uri: ENV['LOGSTASH_URI'], type: :rails
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
# See http://unicorn.bogomips.org/Unicorn/Configurator.html
|
# See http://unicorn.bogomips.org/Unicorn/Configurator.html
|
||||||
|
|
||||||
if ENV["UNICORN_JSON_LOG_FORMAT"]
|
if ENV["LOGSTASH_URI"]
|
||||||
unicorn_logger = Logger.new($stderr)
|
require_relative '../lib/discourse_logstash_logger'
|
||||||
require_relative '../lib/unicorn/unicorn_json_log_formatter'
|
logger DiscourseLogstashLogger.logger(uri: ENV['LOGSTASH_URI'], type: :unicorn)
|
||||||
unicorn_logger.formatter = UnicornJSONLogFormatter.new
|
|
||||||
logger unicorn_logger
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# enable out of band gc out of the box, it is low risk and improves perf a lot
|
# enable out of band gc out of the box, it is low risk and improves perf a lot
|
||||||
|
|
16
lib/discourse_logstash_logger.rb
Normal file
16
lib/discourse_logstash_logger.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
require 'logstash-logger'
|
||||||
|
|
||||||
|
class DiscourseLogstashLogger
|
||||||
|
def self.logger(uri:, type:)
|
||||||
|
LogStashLogger.new(
|
||||||
|
uri: uri,
|
||||||
|
sync: true,
|
||||||
|
customize_event: ->(event) {
|
||||||
|
event['hostname'] = `hostname`.chomp
|
||||||
|
event['severity'] = Object.const_get("Logger::Severity::#{event['severity']}")
|
||||||
|
event['severity_name'] = event['severity']
|
||||||
|
event['type'] = type
|
||||||
|
},
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,22 +0,0 @@
|
||||||
require 'json'
|
|
||||||
|
|
||||||
class UnicornJSONLogFormatter < Logger::Formatter
|
|
||||||
def call(severity, datetime, progname, message)
|
|
||||||
default = {
|
|
||||||
severity: Object.const_get("Logger::Severity::#{severity}"),
|
|
||||||
severity_name: severity,
|
|
||||||
datetime: DateTime.parse(datetime.to_s).to_s,
|
|
||||||
progname: progname || '',
|
|
||||||
pid: $$,
|
|
||||||
}
|
|
||||||
|
|
||||||
default[:message] =
|
|
||||||
if message.is_a?(Exception)
|
|
||||||
"#{message.message}: #{message.backtrace.join("\n")}"
|
|
||||||
else
|
|
||||||
message
|
|
||||||
end
|
|
||||||
|
|
||||||
"#{default.to_json}\n"
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,32 +0,0 @@
|
||||||
require 'rails_helper'
|
|
||||||
require 'unicorn/unicorn_json_log_formatter'
|
|
||||||
|
|
||||||
RSpec.describe UnicornJSONLogFormatter do
|
|
||||||
context 'when message is an exception' do
|
|
||||||
it 'should include the backtrace' do
|
|
||||||
freeze_time do
|
|
||||||
begin
|
|
||||||
raise 'boom'
|
|
||||||
rescue => e
|
|
||||||
error = e
|
|
||||||
|
|
||||||
output = described_class.new.call(
|
|
||||||
'ERROR',
|
|
||||||
Time.zone.now,
|
|
||||||
'',
|
|
||||||
e
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
output = JSON.parse(output)
|
|
||||||
|
|
||||||
expect(output["severity"]).to eq(3)
|
|
||||||
expect(output["severity_name"]).to eq("ERROR")
|
|
||||||
expect(output["datetime"]).to be_present
|
|
||||||
expect(output["progname"]).to eq('')
|
|
||||||
expect(output["pid"]).to be_present
|
|
||||||
expect(output["message"]).to match(/boom:.*/)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in New Issue
Block a user