Merge "tp: delete all v1 db filtering and sorting code" into main
diff --git a/protos/perfetto/config/android/protolog_config.proto b/protos/perfetto/config/android/protolog_config.proto
index 6798bd3..c73256e 100644
--- a/protos/perfetto/config/android/protolog_config.proto
+++ b/protos/perfetto/config/android/protolog_config.proto
@@ -47,4 +47,7 @@
   // e.g. if ProtoLogLevel.WARN is specified only warning, errors and fatal log
   // message will be traced.
   optional ProtoLogLevel log_from = 2;
+  // When set to true we will collect the stacktrace for each protolog message
+  // in this group that we are tracing.
+  optional bool collect_stacktrace = 3;
 }
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index ab07107..d91246b 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -600,6 +600,9 @@
   // e.g. if ProtoLogLevel.WARN is specified only warning, errors and fatal log
   // message will be traced.
   optional ProtoLogLevel log_from = 2;
+  // When set to true we will collect the stacktrace for each protolog message
+  // in this group that we are tracing.
+  optional bool collect_stacktrace = 3;
 }
 
 // End of protos/perfetto/config/android/protolog_config.proto
diff --git a/protos/perfetto/trace/android/protolog.proto b/protos/perfetto/trace/android/protolog.proto
index 49e5521..b520c7a 100644
--- a/protos/perfetto/trace/android/protolog.proto
+++ b/protos/perfetto/trace/android/protolog.proto
@@ -25,13 +25,16 @@
   /* log statement identifier, created from message string and log level. */
   optional fixed64 message_id = 1;
   /* string parameters passed to the log call that have been interned. */
-  repeated uint32 interned_str_params = 2;
+  repeated uint32 str_param_iids = 2;
   /* integer parameters passed to the log call. */
   repeated sint64 sint64_params = 3;
   /* floating point parameters passed to the log call. */
   repeated double double_params = 4;
   /* boolean parameters passed to the log call. */
   repeated int32 boolean_params = 5;
+  // id of the interned stacktrace string
+  // (only dumped if explicitly confuigured to do so)
+  optional uint32 stacktrace_iid = 6;
 }
 
 /* contains all the data required to fully decode the protolog messages */
diff --git a/protos/perfetto/trace/interned_data/interned_data.proto b/protos/perfetto/trace/interned_data/interned_data.proto
index 401ea13..2cae9c6 100644
--- a/protos/perfetto/trace/interned_data/interned_data.proto
+++ b/protos/perfetto/trace/interned_data/interned_data.proto
@@ -135,4 +135,6 @@
 
   // Interned protolog strings args.
   repeated InternedString protolog_string_args = 36;
+  // Interned protolog stacktraces.
+  repeated InternedString protolog_stacktrace = 37;
 }
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index b6bfcb9..f9370cd 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -600,6 +600,9 @@
   // e.g. if ProtoLogLevel.WARN is specified only warning, errors and fatal log
   // message will be traced.
   optional ProtoLogLevel log_from = 2;
+  // When set to true we will collect the stacktrace for each protolog message
+  // in this group that we are tracing.
+  optional bool collect_stacktrace = 3;
 }
 
 // End of protos/perfetto/config/android/protolog_config.proto
@@ -4848,13 +4851,16 @@
   /* log statement identifier, created from message string and log level. */
   optional fixed64 message_id = 1;
   /* string parameters passed to the log call that have been interned. */
-  repeated uint32 interned_str_params = 2;
+  repeated uint32 str_param_iids = 2;
   /* integer parameters passed to the log call. */
   repeated sint64 sint64_params = 3;
   /* floating point parameters passed to the log call. */
   repeated double double_params = 4;
   /* boolean parameters passed to the log call. */
   repeated int32 boolean_params = 5;
+  // id of the interned stacktrace string
+  // (only dumped if explicitly confuigured to do so)
+  optional uint32 stacktrace_iid = 6;
 }
 
 /* contains all the data required to fully decode the protolog messages */
@@ -12453,6 +12459,8 @@
 
   // Interned protolog strings args.
   repeated InternedString protolog_string_args = 36;
+  // Interned protolog stacktraces.
+  repeated InternedString protolog_stacktrace = 37;
 }
 
 // End of protos/perfetto/trace/interned_data/interned_data.proto
diff --git a/src/trace_processor/importers/proto/winscope/protolog_messages_tracker.h b/src/trace_processor/importers/proto/winscope/protolog_messages_tracker.h
index e61c5f5..0f47c32 100644
--- a/src/trace_processor/importers/proto/winscope/protolog_messages_tracker.h
+++ b/src/trace_processor/importers/proto/winscope/protolog_messages_tracker.h
@@ -35,6 +35,7 @@
     std::vector<double> double_params;
     std::vector<bool> boolean_params;
     std::vector<std::string> string_params;
+    std::optional<StringId> stacktrace;
     tables::ProtoLogTable::Id table_row_id;
     int64_t timestamp;
   };
diff --git a/src/trace_processor/importers/proto/winscope/protolog_parser.cc b/src/trace_processor/importers/proto/winscope/protolog_parser.cc
index 0543222..15c19ac 100644
--- a/src/trace_processor/importers/proto/winscope/protolog_parser.cc
+++ b/src/trace_processor/importers/proto/winscope/protolog_parser.cc
@@ -30,7 +30,6 @@
 #include "src/trace_processor/types/trace_processor_context.h"
 
 #include <sstream>
-
 namespace perfetto {
 namespace trace_processor {
 
@@ -79,9 +78,9 @@
   }
 
   std::vector<std::string> string_params;
-  if (protolog_message.has_interned_str_params()) {
+  if (protolog_message.has_str_param_iids()) {
     if (sequence_state->state()->IsIncrementalStateValid()) {
-      for (auto it = protolog_message.interned_str_params(); it; ++it) {
+      for (auto it = protolog_message.str_param_iids(); it; ++it) {
         auto decoder =
             sequence_state->state()
                 ->current_generation()
@@ -109,6 +108,28 @@
     }
   }
 
+  std::optional<StringId> stacktrace = std::nullopt;
+  if (protolog_message.has_stacktrace_iid()) {
+    auto stacktrace_decoder =
+        sequence_state->state()
+            ->current_generation()
+            ->LookupInternedMessage<
+                protos::pbzero::InternedData::kProtologStacktraceFieldNumber,
+                protos::pbzero::InternedString>(
+                protolog_message.stacktrace_iid());
+
+    if (!stacktrace_decoder) {
+      // This shouldn't happen since we already checked the incremental
+      // state is valid.
+      string_params.emplace_back("<ERROR>");
+      context_->storage->IncrementStats(
+          stats::winscope_protolog_missing_interned_stacktrace_parse_errors);
+    } else {
+      stacktrace = context_->storage->InternString(
+          base::StringView(stacktrace_decoder->str().ToStdString()));
+    }
+  }
+
   auto* protolog_table = context_->storage->mutable_protolog_table();
 
   tables::ProtoLogTable::Row row;
@@ -122,6 +143,7 @@
       std::move(double_params),
       std::move(boolean_params),
       std::move(string_params),
+      stacktrace,
       row_id,
       timestamp};
   protolog_message_tracker->TrackMessage(std::move(tracked_message));
@@ -195,6 +217,10 @@
         auto message = context_->storage->InternString(
             base::StringView(formatted_message));
         row.set_message(message);
+
+        if (tracked_message.stacktrace.has_value()) {
+          row.set_stacktrace(tracked_message.stacktrace.value());
+        }
       }
     }
   }
diff --git a/src/trace_processor/storage/stats.h b/src/trace_processor/storage/stats.h
index 4c9a697..66a524e 100644
--- a/src/trace_processor/storage/stats.h
+++ b/src/trace_processor/storage/stats.h
@@ -304,7 +304,10 @@
       "ProtoLog message string has invalid interplation parameter."),          \
   F(winscope_protolog_missing_interned_arg_parse_errors,                       \
                                           kSingle,  kInfo,     kAnalysis,      \
-      "Failed to find interned ProtoLog argument."),          \
+      "Failed to find interned ProtoLog argument."),                           \
+  F(winscope_protolog_missing_interned_stacktrace_parse_errors,                \
+                                          kSingle,  kInfo,     kAnalysis,      \
+      "Failed to find interned ProtoLog stacktrace."),                         \
   F(ftrace_missing_event_id,              kSingle,  kInfo,    kAnalysis,       \
       "Indicates that the ftrace event was dropped because the event id was "  \
       "missing. This is an 'info' stat rather than an error stat because "     \
diff --git a/src/trace_processor/tables/winscope_tables.py b/src/trace_processor/tables/winscope_tables.py
index 830f88e..8a60e43 100644
--- a/src/trace_processor/tables/winscope_tables.py
+++ b/src/trace_processor/tables/winscope_tables.py
@@ -112,6 +112,7 @@
         C('level', CppString()),
         C('tag', CppString()),
         C('message', CppString()),
+        C('stacktrace', CppString()),
     ],
     tabledoc=TableDoc(
         doc='Protolog',
@@ -121,6 +122,7 @@
             'level': 'The log level of the protolog message',
             'tag': 'The log tag of the protolog message',
             'message': 'The protolog message',
+            'stacktrace': 'Stacktrace captured at the message\'s logpoint',
         }))
 
 # Keep this list sorted.
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
index 25fb3c5..590d1c0 100644
--- a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
+++ b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
@@ -1 +1 @@
-9f4d57409034b11957935bbd94c8fa925d24db453b617503b6c908366b1f11cc
\ No newline at end of file
+71f0799ce780f36dbdeb601ba535ee012b7323afc57254a5b383704ec384da62
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
index f99f37b..fd6b0fe 100644
--- a/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
+++ b/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
@@ -1 +1 @@
-f358a8b059b98a0445674d5e720230047f85829a6366439559ffc5908508ba11
\ No newline at end of file
+725ff7289949bda82fc4c2d454e1ee0b4218b3d56f20c1098d6fa7914ef19bfc
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_missing_track_names_load.png.sha256 b/test/data/ui-screenshots/ui-chrome_missing_track_names_load.png.sha256
index d8f53e7..06a3e7b 100644
--- a/test/data/ui-screenshots/ui-chrome_missing_track_names_load.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_missing_track_names_load.png.sha256
@@ -1 +1 @@
-a4b1867255b838c3ab73f6d00c84aa5bd7fc31bb53da5b83f52ceb84d99e96b2
\ No newline at end of file
+22ca974ba2f262c4e421e95dba686746eb89564a8ff213e50f78c9424277587c
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
index 6cbb409..a917bab 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
@@ -1 +1 @@
-ec9873453c3834735d55eb21138bf510069cf863342509a799076d821a8f01dd
\ No newline at end of file
+90505c5620c73940b88d163a73c79005fa8e81d097d0fcabf2585e56f7bc6a99
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256
index 6667e5f..89a9c57 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256
@@ -1 +1 @@
-351edcf1ade9e6b1b7ced9d4f204e9a939370b7a56066f66793e56c9d93ec972
\ No newline at end of file
+d1a9ace55344d8a2850a8238b698892aca1ea2eacf80886420108043de8d3c56
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
index 90d04b9..470075f 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
@@ -1 +1 @@
-3699ab1be1ccf7f41559fad373027c884b3f1539183f4b405e29852f01985937
\ No newline at end of file
+a97c6027c4bef120c4227a7ed32e6a6fb6b290938ef8d66652e6d369b7e5d157
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_navigate_open_trace_from_url.png.sha256 b/test/data/ui-screenshots/ui-routing_navigate_open_trace_from_url.png.sha256
index 92f9c01..a0ddb77 100644
--- a/test/data/ui-screenshots/ui-routing_navigate_open_trace_from_url.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_navigate_open_trace_from_url.png.sha256
@@ -1 +1 @@
-1bcbdbf6d1c2c1c2e77faa90be1c060b350f21472f67aed9477e6ba5e5219e81
\ No newline at end of file
+47cda8e8a9ed007945bff13d7c10fa4d33fc6e264c1198b2038a216559bec962
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256 b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
index bd02978..98f2571 100644
--- a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
@@ -1 +1 @@
-0b44f0292e51fcf599f17622193d67b17bbaca02440cf2f0e994dbbbac65306a
\ No newline at end of file
+bd495271f97ffe17851f6605acaf24463c2363cb6a4bcf8e1b3fd78b9e18353f
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256
index ff33850..5b79980 100644
--- a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256
@@ -1 +1 @@
-7d8429af94229b4cb96f3e7691e987b4eb0ade9683acce9a2c14c41777415d73
\ No newline at end of file
+ab93fa5646ab5e2bc63922ee8f6c6d7657f128fe7b5426df97d02f19c770a1bc
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_first_trace_from_url.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_first_trace_from_url.png.sha256
index 92f9c01..a0ddb77 100644
--- a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_first_trace_from_url.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_first_trace_from_url.png.sha256
@@ -1 +1 @@
-1bcbdbf6d1c2c1c2e77faa90be1c060b350f21472f67aed9477e6ba5e5219e81
\ No newline at end of file
+47cda8e8a9ed007945bff13d7c10fa4d33fc6e264c1198b2038a216559bec962
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256
index ff33850..5b79980 100644
--- a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256
@@ -1 +1 @@
-7d8429af94229b4cb96f3e7691e987b4eb0ade9683acce9a2c14c41777415d73
\ No newline at end of file
+ab93fa5646ab5e2bc63922ee8f6c6d7657f128fe7b5426df97d02f19c770a1bc
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256
index ff33850..5b79980 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256
@@ -1 +1 @@
-7d8429af94229b4cb96f3e7691e987b4eb0ade9683acce9a2c14c41777415d73
\ No newline at end of file
+ab93fa5646ab5e2bc63922ee8f6c6d7657f128fe7b5426df97d02f19c770a1bc
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
index 2fe4afb..d806076 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
@@ -1 +1 @@
-b3f9edabe8db232b481a7484c5230fa08d01f37336f9e60eaf6fbe8e8d0ded16
\ No newline at end of file
+2dc0e3ade667e7578fa6b5b8911177ab272300bfddb015c4979c3b4361d93047
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_second_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_second_trace.png.sha256
index 92f9c01..a0ddb77 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_second_trace.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_second_trace.png.sha256
@@ -1 +1 @@
-1bcbdbf6d1c2c1c2e77faa90be1c060b350f21472f67aed9477e6ba5e5219e81
\ No newline at end of file
+47cda8e8a9ed007945bff13d7c10fa4d33fc6e264c1198b2038a216559bec962
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256
index ff33850..5b79980 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256
@@ -1 +1 @@
-7d8429af94229b4cb96f3e7691e987b4eb0ade9683acce9a2c14c41777415d73
\ No newline at end of file
+ab93fa5646ab5e2bc63922ee8f6c6d7657f128fe7b5426df97d02f19c770a1bc
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256
index ff33850..5b79980 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256
@@ -1 +1 @@
-7d8429af94229b4cb96f3e7691e987b4eb0ade9683acce9a2c14c41777415d73
\ No newline at end of file
+ab93fa5646ab5e2bc63922ee8f6c6d7657f128fe7b5426df97d02f19c770a1bc
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/parser/android/protolog.textproto b/test/trace_processor/diff_tests/parser/android/protolog.textproto
index 4ab660d..6e65ffd 100644
--- a/test/trace_processor/diff_tests/parser/android/protolog.textproto
+++ b/test/trace_processor/diff_tests/parser/android/protolog.textproto
@@ -20,15 +20,27 @@
 packet {
   trusted_uid: 1000
   trusted_packet_sequence_id: 2
+  interned_data {
+    protolog_stacktrace {
+      iid: 1
+      str: "A STACK TRACE"
+    }
+  }
+  trusted_pid: 1716
+}
+packet {
+  trusted_uid: 1000
+  trusted_packet_sequence_id: 2
   sequence_flags: 2
   trusted_pid: 1716
   timestamp: 857384100
   protolog_message {
     message_id: 6924537961316301726
-    interned_str_params: 1
+    str_param_iids: 1
     sint64_params: 888
     double_params: 8.88
     boolean_params: 1
+    stacktrace_iid: 1
   }
 }
 packet {
@@ -83,10 +95,10 @@
   timestamp: 857384130
   protolog_message {
     message_id: 9274895847396301003
-    interned_str_params: 1
-    interned_str_params: 1
-    interned_str_params: 2
-    interned_str_params: 1
+    str_param_iids: 1
+    str_param_iids: 1
+    str_param_iids: 2
+    str_param_iids: 1
   }
 }
 packet {
diff --git a/test/trace_processor/diff_tests/parser/android/tests_protolog.py b/test/trace_processor/diff_tests/parser/android/tests_protolog.py
index 6db8cfe..404f34e 100644
--- a/test/trace_processor/diff_tests/parser/android/tests_protolog.py
+++ b/test/trace_processor/diff_tests/parser/android/tests_protolog.py
@@ -24,10 +24,10 @@
   def test_has_expected_protolog_rows(self):
     return DiffTestBlueprint(
         trace=Path('protolog.textproto'),
-        query="SELECT id, ts, level, tag, message FROM protolog;",
+        query="SELECT id, ts, level, tag, message, stacktrace FROM protolog;",
         out=Csv("""
-        "id","ts","level","tag","message"
-        0,857384100,"DEBUG","MyFirstGroup","Test message with a string (MyTestString), an int (1776), a double 8.88, and a boolean true."
-        1,857384110,"WARN","MySecondGroup","Test message with different int formats: 1776, 0o3360, 0x6f0, 888.000000, 8.880000e+02."
-        2,857384130,"ERROR","MyThirdGroup","Message re-using interned string 'MyOtherTestString' == 'MyOtherTestString', but 'SomeOtherTestString' != 'MyOtherTestString'"
+        "id","ts","level","tag","message","stacktrace"
+        0,857384100,"DEBUG","MyFirstGroup","Test message with a string (MyTestString), an int (1776), a double 8.88, and a boolean true.","A STACK TRACE"
+        1,857384110,"WARN","MySecondGroup","Test message with different int formats: 1776, 0o3360, 0x6f0, 888.000000, 8.880000e+02.","[NULL]"
+        2,857384130,"ERROR","MyThirdGroup","Message re-using interned string 'MyOtherTestString' == 'MyOtherTestString', but 'SomeOtherTestString' != 'MyOtherTestString'","[NULL]"
         """))