Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
bump: patch
type: fix
---

Do not log long (error) messages to the internal AppSignal log. If an error like `ActionController::BadRequest` occurred and the error message contained the entire file upload, this would grow the `appsignal.log` file quickly if the error happens often. Internal log messages are now truncated by default.
25 changes: 25 additions & 0 deletions lib/appsignal/utils/integration_logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,31 @@
module Appsignal
module Utils
class IntegrationLogger < ::Logger
MAX_MESSAGE_LENGTH = 2_000

def add(severity, message = nil, progname = nil)
if message.nil? && !block_given?
# When called as logger.error("msg"), the message is in progname
progname = truncate_message(progname)
elsif message
message = truncate_message(message)
elsif block_given?
message = truncate_message(yield)
end
super
end

private

def truncate_message(message)
return message unless message.is_a?(String)

if message.length > MAX_MESSAGE_LENGTH
"#{message[0, MAX_MESSAGE_LENGTH]}..."
else
message
end
end
end
end
end
48 changes: 48 additions & 0 deletions spec/lib/appsignal/utils/integration_logger_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,58 @@
logger.info("info message")
logger.warn("warning message")
logger.error("error message")
logger.error(ExampleStandardError.new("example error with message"))
logger.info { "block error message" }

expect(logs).to contains_log(:debug, "debug message")
expect(logs).to contains_log(:info, "info message")
expect(logs).to contains_log(:warn, "warning message")
expect(logs).to contains_log(:error, "error message")
expect(logs).to contains_log(:error, "example error with message")
expect(logs).to contains_log(:info, "block error message")
end

describe "message truncation" do
it "does not truncate short messages" do
logger.error("Short error message")

expect(logs).to contains_log(:error, "Short error message")
end

context "when calling logger.error(message)" do
it "truncates long messages" do
long_message = "a" * 2500
logger.error(long_message)

expect(logs).to contains_log(:error, "#{"a" * 2000}...")
end
end

context "when calling logger.error { message }" do
it "truncates long messages passed as a block" do
long_message = "a" * 2500
logger.error { long_message }

expect(logs).to contains_log(:error, "#{"a" * 2000}...")
end
end

context "when calling logger.add(severity, message)" do
it "truncates long messages" do
long_message = "a" * 2500
logger.add(Logger::ERROR, long_message)

expect(logs).to contains_log(:error, "#{"a" * 2000}...")
end
end

context "when calling logger.error(progname) { message }" do
it "truncates long messages from block" do
long_message = "a" * 2500
logger.error("progname") { long_message }

expect(logs).to contains_log(:error, "#{"a" * 2000}...")
end
end
end
end