From f116a6d298262483b7321e1e2adb6873b5a93ae2 Mon Sep 17 00:00:00 2001 From: Francesco Belladonna Date: Mon, 18 Aug 2025 13:47:39 -0700 Subject: [PATCH] Add high priority fields to beginning of JSON object when json format --- CHANGELOG.md | 2 ++ lib/semantic_logger/formatters/raw.rb | 6 ++-- test/formatters/json_test.rb | 45 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 test/formatters/json_test.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index fc9a74d4..fe2fc31b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] +- Add high priority fields (timestamp, level, level index and message) to beginning of JSON object output when using JSON formatter to ensure log entries are parsable even when JSON logs are mangled + ## [4.17.0] - Correct `source_code_uri` URL diff --git a/lib/semantic_logger/formatters/raw.rb b/lib/semantic_logger/formatters/raw.rb index 44fffa9f..d82b1bc7 100644 --- a/lib/semantic_logger/formatters/raw.rb +++ b/lib/semantic_logger/formatters/raw.rb @@ -117,11 +117,12 @@ def call(log, logger) self.log = log self.logger = logger + time + level + message host application environment - time - level pid thread_name file_name_and_line @@ -129,7 +130,6 @@ def call(log, logger) tags named_tags name - message payload exception metric diff --git a/test/formatters/json_test.rb b/test/formatters/json_test.rb new file mode 100644 index 00000000..d1569190 --- /dev/null +++ b/test/formatters/json_test.rb @@ -0,0 +1,45 @@ +require_relative "../test_helper" + +module SemanticLogger + module Formatters + class JsonTest < Minitest::Test + describe Json do + let(:log_time) do + Time.utc(2017, 1, 14, 8, 32, 5.375276) + end + + let(:level) do + :debug + end + + let(:log) do + log = SemanticLogger::Log.new("JsonTest", level) + log.time = log_time + log + end + + let(:expected_time) do + SemanticLogger::Formatters::Base::PRECISION == 3 ? "2017-01-14T08:32:05.375Z" : "2017-01-14T08:32:05.375276Z" + end + + let(:formatter) do + formatter = SemanticLogger::Formatters::Json.new(log_host: false) + # Does not use the logger instance for formatting purposes + formatter.call(log, nil) + formatter + end + + describe "call" do + it "sets timestamp, level, level_index, and message at the beginning of the JSON object" do + log.message = "Some message" + expected_start = %({"timestamp":"#{expected_time}","level":"debug","level_index":1,"message":"Some message") + + is_starting_with_high_priority_fields = formatter.call(log, nil).start_with?(expected_start) + + assert is_starting_with_high_priority_fields, "Expected #{formatter.call(log, nil)} to start with #{expected_start}" + end + end + end + end + end +end