Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions lib/contextual_logging/logstash_message_formatter.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
module ContextualLogging
class LogstashMessageFormatter
MAX_MESSAGE_LENGTH = 2000

def format(severity, message, extra_context)
msg_hash = HashWithIndifferentAccess.new('message' => message, 'log_level' => severity)
logstash_data = extra_context.merge(msg_hash)
if severity == 'INFO'
truncated_message = truncate(message)
limited_extra_context = truncate_log_extra_context(extra_context)
else
truncated_message = message
limited_extra_context = extra_context
end

logstash_data = HashWithIndifferentAccess.new(
'message' => truncated_message,
'log_level' => severity
).merge(limited_extra_context)

logstash_event = LogStash::Event.new(logstash_data)
logstash_event.to_json
end

private

def truncate(message)
message[0...MAX_MESSAGE_LENGTH]
end

def truncate_log_extra_context(extra_context)
extra_context.each_with_object(HashWithIndifferentAccess.new) do |(key, value), limited_extra_context|
if value.is_a?(Hash)
limited_extra_context[key] = HashWithIndifferentAccess.new
value.each do |k, v|
if v.is_a?(String)
limited_extra_context[key][k] = truncate(v)
else
limited_extra_context[key][k] = truncate(v.inspect)
end
end
else
limited_extra_context[key] = value
end
end
end
end
end

20 changes: 19 additions & 1 deletion spec/contextual_logging_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
require 'spec_helper'

describe ContextualLogging do
describe ContextualLogging::LogstashMessageFormatter do
message_formatter = ContextualLogging::LogstashMessageFormatter.new
it 'should limit message size to 2000 characters when severity level is INFO' do
message = (0...3000).map { ('a'..'z').to_a[rand(26)] }.join
log_message = message_formatter.format('INFO', message, {})
expect(JSON[log_message]['message'].length).to equal 2000
end

it 'should limit extra context values that are two levels deep to 2000 characters when severity level is INFO' do
message = (0...3000).map { ('a'..'z').to_a[rand(26)] }.join
extra_context = HashWithIndifferentAccess.new
extra_context['params'] = HashWithIndifferentAccess.new(nodes: {})
extra_context['text'] = (0...3000).map { ('a'..'z').to_a[rand(26)] }.join
extra_context['params']['nodes']['a'] = (0...3000).map { ('a'..'z').to_a[rand(26)] }.join

log_message = message_formatter.format('INFO', message, extra_context)
expect(JSON[log_message]['params']['nodes'].length).to equal 2000
expect(JSON[log_message]['text'].length).to equal 3000
end
end