2024-07-08 02:03:11 -04:00
# frozen_string_literal: true
RSpec . describe DiscourseLogstashLogger do
let ( :lograge_logstash_formatter_formatted_message ) do
" { \" method \" : \" GET \" , \" path \" : \" / \" , \" format \" : \" html \" , \" controller \" : \" ListController \" , \" action \" : \" latest \" , \" status \" :200, \" allocations \" :242307, \" duration \" :178.2, \" view \" :78.36, \" db \" :0.0, \" params \" : \" \" , \" ip \" : \" 127.0.0.1 \" , \" username \" :null, \" @timestamp \" : \" 2024-07-01T07:51:11.283Z \" , \" @version \" : \" 1 \" , \" message \" : \" [200] GET / (ListController # latest) \" } "
end
let ( :output ) { StringIO . new }
let ( :logger ) { described_class . logger ( logdev : output , type : " test " ) }
describe " # add " do
it " logs a JSON string with the right fields " do
logger . add ( Logger :: INFO , lograge_logstash_formatter_formatted_message )
output . rewind
expect ( output . read . chomp ) . to eq (
{
" message " = > " [200] GET / (ListController # latest) " ,
" severity " = > 1 ,
" severity_name " = > " INFO " ,
" pid " = > described_class :: PROCESS_PID ,
" type " = > " test " ,
" host " = > described_class :: HOST ,
2024-07-09 22:36:22 -04:00
" git_version " = > described_class :: GIT_VERSION ,
2024-07-08 02:03:11 -04:00
" method " = > " GET " ,
" path " = > " / " ,
" format " = > " html " ,
" controller " = > " ListController " ,
" action " = > " latest " ,
" status " = > 200 ,
" allocations " = > 242_307 ,
" duration " = > 178 . 2 ,
" view " = > 78 . 36 ,
" db " = > 0 . 0 ,
" params " = > " " ,
" ip " = > " 127.0.0.1 " ,
" username " = > nil ,
" @timestamp " = > " 2024-07-01T07:51:11.283Z " ,
" @version " = > " 1 " ,
} . to_json ,
)
end
it " accepts an error object as the message " do
logger = described_class . logger ( logdev : output , type : " test " )
logger . add ( Logger :: ERROR , StandardError . new ( " error message " ) )
output . rewind
parsed = JSON . parse ( output . read . chomp )
expect ( parsed [ " message " ] ) . to eq ( " error message " )
end
2024-07-11 02:17:18 -04:00
context " when `progname` is `sidekiq-exception` " do
it " logs a JSON string with the `exception.class`, `exception.message`, `job.class`, `job.opts` and `job.problem_db` fields " do
logger = described_class . logger ( logdev : output , type : " test " )
2024-07-09 23:04:17 -04:00
2024-07-11 02:17:18 -04:00
logger . add_with_opts (
Logger :: ERROR ,
" Job exception: some job error message " ,
" sidekiq-exception " ,
exception_class : " Some::StandardError " ,
exception_message : " some job error message " ,
context : {
opts : {
user_id : 1 ,
} ,
problem_db : " some_db " ,
job : " SomeJob " ,
} ,
)
2024-07-09 23:04:17 -04:00
2024-07-11 02:17:18 -04:00
output . rewind
parsed = JSON . parse ( output . read . chomp )
2024-07-09 23:04:17 -04:00
2024-07-11 02:17:18 -04:00
expect ( parsed [ " exception.class " ] ) . to eq ( " Some::StandardError " )
expect ( parsed [ " exception.message " ] ) . to eq ( " some job error message " )
expect ( parsed [ " job.class " ] ) . to eq ( " SomeJob " )
2024-07-22 18:27:43 -04:00
expect ( parsed [ " job.opts " ] ) . to eq ( " { \" user_id \" =>1} " )
2024-07-11 02:17:18 -04:00
expect ( parsed [ " job.problem_db " ] ) . to eq ( " some_db " )
end
2024-07-09 23:04:17 -04:00
end
2024-07-11 02:17:18 -04:00
context " when `progname` is `web-exception` " do
it " logs a JSON string with the `exception.class` and `exception.message` fields " do
logger = described_class . logger ( logdev : output , type : " test " )
2024-07-09 23:04:17 -04:00
2024-07-11 02:17:18 -04:00
logger . add (
Logger :: ERROR ,
" Some::StandardError (this is a normal message) \n test " ,
" web-exception " ,
)
2024-07-09 23:04:17 -04:00
2024-07-11 02:17:18 -04:00
output . rewind
parsed = JSON . parse ( output . read . chomp )
expect ( parsed [ " exception.class " ] ) . to eq ( " Some::StandardError " )
expect ( parsed [ " exception.message " ] ) . to eq ( " this is a normal message " )
end
it " logs a JSON string with the `exception_class` and `exception_message` fields when the exception message contains newlines " do
logger = described_class . logger ( logdev : output , type : " test " )
logger . add (
Logger :: ERROR ,
" Some::StandardError ( \n \n some error message \n \n something else \n \n ) \n test " ,
" web-exception " ,
)
output . rewind
parsed = JSON . parse ( output . read . chomp )
expect ( parsed [ " exception.class " ] ) . to eq ( " Some::StandardError " )
expect ( parsed [ " exception.message " ] ) . to eq ( " some error message \n \n something else " )
end
described_class :: ALLOWED_HEADERS_FROM_ENV . each do | header |
it " includes ` #{ header } ` from `env` keyword argument in the logged JSON string " do
logger . add (
Logger :: ERROR ,
lograge_logstash_formatter_formatted_message ,
" web-exception " ,
env : {
header = > " header " ,
} ,
)
output . rewind
parsed = JSON . parse ( output . read . chomp )
expect ( parsed [ " request.headers. #{ header . downcase } " ] ) . to eq ( " header " )
end
end
it " does not include keys from `env` keyword argument in the logged JSOn string which are not in the allow list " do
logger . add (
Logger :: ERROR ,
lograge_logstash_formatter_formatted_message ,
" web-exception " ,
env : {
" SOME_RANDOM_HEADER " = > " header " ,
} ,
)
2024-07-09 20:54:39 -04:00
2024-07-11 02:17:18 -04:00
output . rewind
parsed = JSON . parse ( output . read . chomp )
expect ( parsed ) . not_to have_key ( " request.headers.some_random_header " )
end
2024-07-09 20:54:39 -04:00
end
2024-07-08 02:03:11 -04:00
it " logs a JSON string with the right fields when `customize_event` attribute is set " do
logger =
described_class . logger (
logdev : output ,
type : " test " ,
customize_event : - > ( event ) { event [ " custom " ] = " custom " } ,
)
logger . add ( Logger :: INFO , lograge_logstash_formatter_formatted_message )
output . rewind
parsed = JSON . parse ( output . read . chomp )
expect ( parsed [ " custom " ] ) . to eq ( " custom " )
end
it " does not log a JSON string with the `backtrace` field when severity is less than `Logger::WARN` " do
logger . add (
Logger :: INFO ,
lograge_logstash_formatter_formatted_message ,
nil ,
backtrace : " backtrace " ,
)
output . rewind
parsed = JSON . parse ( output . read . chomp )
expect ( parsed ) . not_to have_key ( " backtrace " )
end
it " logs a JSON string with the `backtrace` field when severity is at least `Logger::WARN` " do
logger . add (
Logger :: ERROR ,
lograge_logstash_formatter_formatted_message ,
nil ,
backtrace : " backtrace " ,
)
output . rewind
parsed = JSON . parse ( output . read . chomp )
expect ( parsed [ " backtrace " ] ) . to eq ( " backtrace " )
end
2024-07-10 01:51:42 -04:00
it " does not log the event if message matches a pattern configured by `Logster.store.ignore` " do
original_logster_store_ignore = Logster . store . ignore
Logster . store . ignore = [ / ^Some::StandardError / ]
logger . add (
Logger :: ERROR ,
" Some::StandardError (this is a normal message) \n test " ,
" web-exception " ,
)
output . rewind
expect ( output . read . chomp ) . to be_empty
ensure
Logster . store . ignore = original_logster_store_ignore
end
2024-07-08 02:03:11 -04:00
end
end