From b4949aaf4f6abf8dc4d8d98d5cf4857ad56d3790 Mon Sep 17 00:00:00 2001 From: Arthur Barr Date: Wed, 24 Jun 2020 17:40:11 +0100 Subject: [PATCH] Append inserts to mirrored error log messages --- cmd/runmqserver/logging.go | 27 +++++++++++++--- cmd/runmqserver/logging_test.go | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 cmd/runmqserver/logging_test.go diff --git a/cmd/runmqserver/logging.go b/cmd/runmqserver/logging.go index 35f5245..776f4d4 100644 --- a/cmd/runmqserver/logging.go +++ b/cmd/runmqserver/logging.go @@ -1,5 +1,5 @@ /* -© Copyright IBM Corporation 2017, 2019 +© Copyright IBM Corporation 2017, 2020 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import ( "os" "os/exec" "path/filepath" + "sort" "strings" "sync" @@ -60,8 +61,25 @@ func getLogFormat() string { return os.Getenv("LOG_FORMAT") } -func formatSimple(datetime string, message string) string { - return fmt.Sprintf("%v %v\n", datetime, message) +// formatBasic formats a log message parsed from JSON, as "basic" text +func formatBasic(obj map[string]interface{}) string { + // Emulate the MQ "MessageDetail=Extended" option, by appending inserts to the message + // This is important for certain messages, where key details are only available in the extended message content + inserts := make([]string, 0) + for k, v := range obj { + if strings.HasPrefix(k, "ibm_commentInsert") { + inserts = append(inserts, fmt.Sprintf("%s(%v)", strings.Replace(k, "ibm_comment", "Comment", 1), obj[k])) + } else if strings.HasPrefix(k, "ibm_arithInsert") { + if v.(float64) != 0 { + inserts = append(inserts, fmt.Sprintf("%s(%v)", strings.Replace(k, "ibm_arith", "Arith", 1), obj[k])) + } + } + } + sort.Strings(inserts) + if len(inserts) > 0 { + return fmt.Sprintf("%s %s [%v]\n", obj["ibm_datetime"], obj["message"], strings.Join(inserts, ", ")) + } + return fmt.Sprintf("%s %s\n", obj["ibm_datetime"], obj["message"]) } // mirrorSystemErrorLogs starts a goroutine to mirror the contents of the MQ system error logs @@ -126,7 +144,8 @@ func configureLogger(name string) (mirrorFunc, error) { if err != nil { log.Printf("Failed to unmarshall JSON - %v", err) } else { - fmt.Printf(formatSimple(obj["ibm_datetime"].(string), obj["message"].(string))) + fmt.Printf(formatBasic(obj)) + // fmt.Printf(formatSimple(obj["ibm_datetime"].(string), obj["message"].(string))) } return true }, nil diff --git a/cmd/runmqserver/logging_test.go b/cmd/runmqserver/logging_test.go new file mode 100644 index 0000000..d2d9ec4 --- /dev/null +++ b/cmd/runmqserver/logging_test.go @@ -0,0 +1,55 @@ +/* +© Copyright IBM Corporation 2020 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +import ( + "encoding/json" + "fmt" + "strings" + "testing" +) + +var formatBasicTests = []struct { + in []byte + outContains string +}{ + { + []byte("{\"ibm_datetime\":\"2020/06/24 00:00:00\",\"message\":\"Hello world\"}"), + "Hello", + }, + { + []byte("{\"ibm_datetime\":\"2020/06/24 00:00:00\",\"message\":\"Hello world\", \"ibm_commentInsert1\":\"foo\"}"), + "CommentInsert1(foo)", + }, + { + []byte("{\"ibm_datetime\":\"2020/06/24 00:00:00\",\"message\":\"Hello world\", \"ibm_arithInsert1\":1}"), + "ArithInsert1(1)", + }, +} + +func TestFormatBasic(t *testing.T) { + for i, table := range formatBasicTests { + t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { + var inObj map[string]interface{} + json.Unmarshal(table.in, &inObj) + t.Logf("Unmarshalled: %+v", inObj) + out := formatBasic(inObj) + if !strings.Contains(out, table.outContains) { + t.Errorf("formatBasic() with input=%v - expected output to contain %v, got %v", string(table.in), table.outContains, out) + } + }) + } +}