From 8be4f0f9e39f85d198993b05e51a7877850021ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Lisowski?= Date: Thu, 19 Apr 2018 18:02:50 +0200 Subject: [PATCH] Added stack messages --- pkg/formats/java.go | 67 ++++++++++++++++++++++++------------- pkg/formats/message_test.go | 5 +++ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/pkg/formats/java.go b/pkg/formats/java.go index 90754a7..2d52f32 100644 --- a/pkg/formats/java.go +++ b/pkg/formats/java.go @@ -11,10 +11,11 @@ type StandardJavaMessage struct { JSONMessage IsValidJavaMessage bool - thread string - level string - loggerName string - message string + thread string + level string + loggerName string + message string + extendedStackTrace string } // NewStandardJavaMessage is a StandardJavaMessage factory. @@ -24,12 +25,31 @@ type StandardJavaMessage struct { func NewStandardJavaMessage(jsonObject map[string]interface{}) StandardJavaMessage { var sj StandardJavaMessage sj.JSONMessage = NewJSONMessage(jsonObject) - sj.parseJSONObject() + sj.parseAndVerifyJSONObject() return sj } -func (sj *StandardJavaMessage) parseJSONObject() { +func (sj StandardJavaMessage) String() string { + out := sj.formatMessage() + + return out +} + +// SetToValid sets the property of StandardJavaMessage indicating that the provided jsonObject +// contains valid Log4j2 standard message (all required fields are in place) +func (sj *StandardJavaMessage) SetToValid() { + sj.IsValidJavaMessage = true +} + +// SetToInvalid sets the property of StandardJavaMessage indicating that the provided jsonObject +// does not contain valid Log4j2 standard message (some required fields are missing) +func (sj *StandardJavaMessage) SetToInvalid() { + sj.IsValidJavaMessage = false +} + +func (sj *StandardJavaMessage) parseAndVerifyJSONObject() { var err error + var errEst error sj.SetToValid() if sj.thread, err = getJSONStringFieldSafe("thread", sj.jsonObject); err != nil { @@ -44,36 +64,35 @@ func (sj *StandardJavaMessage) parseJSONObject() { sj.SetToInvalid() } - if sj.message, err = getJSONStringFieldSafe("message", sj.jsonObject); err != nil { + sj.message, err = getJSONStringFieldSafe("message", sj.jsonObject) + sj.extendedStackTrace, errEst = sj.getExtendedStackTrace() + if err != nil && errEst != nil { sj.SetToInvalid() } } -func (sj StandardJavaMessage) String() string { - out := sj.formatMessage() - - return out -} - func (sj StandardJavaMessage) formatMessage() string { + var sep string + if sj.message != "" { + sep = "\n" + } else { + sep = "" + } msg := fmt.Sprintf("[%s] %s %s - %s", sj.thread, sj.level, sj.loggerName, sj.message) if thrown, err := getJSONObjectFieldSafe("thrown", sj.jsonObject); err == nil { if stm, err := getJSONStringFieldSafe("extendedStackTrace", thrown); err == nil { - msg = strings.Join([]string{msg, stm}, "\n") + msg = strings.Join([]string{msg, stm}, sep) } } return msg } -// SetToValid sets the property of StandardJavaMessage indicating that the provided jsonObject -// contains valid Log4j2 standard message (all required fields are in place) -func (sj *StandardJavaMessage) SetToValid() { - sj.IsValidJavaMessage = true -} - -// SetToInvalid sets the property of StandardJavaMessage indicating that the provided jsonObject -// does not contain valid Log4j2 standard message (some required fields are missing) -func (sj *StandardJavaMessage) SetToInvalid() { - sj.IsValidJavaMessage = false +func (sj StandardJavaMessage) getExtendedStackTrace() (string, error) { + if thrown, err := getJSONObjectFieldSafe("thrown", sj.jsonObject); err == nil { + if stm, err := getJSONStringFieldSafe("extendedStackTrace", thrown); err == nil { + return stm, nil + } + } + return "", fmt.Errorf("Extended Stack Trace not found") } diff --git a/pkg/formats/message_test.go b/pkg/formats/message_test.go index 196fb4f..25df46b 100644 --- a/pkg/formats/message_test.go +++ b/pkg/formats/message_test.go @@ -77,6 +77,11 @@ func TestNew(t *testing.T) { args{"{\"thread\":\"vert.x-eventloop-thread-0\",\"level\":\"INFO\",\"loggerName\":\"com.example.demo.MainVerticle\",\"message\":\"Received request!\",\"endOfBatch\":true,\"loggerFqcn\":\"io.vertx.core.logging.Logger\",\"instant\":{\"epochSecond\":1523444015,\"nanoOfSecond\":299000000},\"contextMap\":{},\"threadId\":15,\"threadPriority\":5,\"hostname\":\"4cbd459504f5\",\"service\":\"ci-example\",\"release\":\"RMBYTXJUUGO\",\"thrown\":{\"commonElementCount\":0,\"localizedMessage\":\"Connection reset by peer\",\"message\":\"Connection reset by peer\",\"name\":\"java.io.IOException\",\"extendedStackTrace\":\"java.io.IOException: Connection reset by peer\\n\\tat sun.nio.ch.FileDispatcherImpl.read0(Native Method) ~[?:1.8.0_162]\\n\\tat sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) ~[?:1.8.0_162]\\n\\tat sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[?:1.8.0_162]\\n\\tat sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[?:1.8.0_162]\\n\\tat sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ~[?:1.8.0_162]\\n\\tat io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288) ~[subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108) ~[subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345) ~[subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:126) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat java.lang.Thread.run(Thread.java:748) [?:1.8.0_162]\\n\"}}"}, TestMessage{"[vert.x-eventloop-thread-0] INFO com.example.demo.MainVerticle - Received request!\njava.io.IOException: Connection reset by peer\n\tat sun.nio.ch.FileDispatcherImpl.read0(Native Method) ~[?:1.8.0_162]\n\tat sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) ~[?:1.8.0_162]\n\tat sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[?:1.8.0_162]\n\tat sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[?:1.8.0_162]\n\tat sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ~[?:1.8.0_162]\n\tat io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288) ~[subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108) ~[subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345) ~[subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:126) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [subscription-api-jar-with-dependencies.jar:?]\n\tat java.lang.Thread.run(Thread.java:748) [?:1.8.0_162]\n"}, }, + { + "Java JSON thrown no message", + args{"{\"thread\":\"vert.x-eventloop-thread-0\",\"level\":\"INFO\",\"loggerName\":\"com.example.demo.MainVerticle\",\"endOfBatch\":true,\"loggerFqcn\":\"io.vertx.core.logging.Logger\",\"instant\":{\"epochSecond\":1523444015,\"nanoOfSecond\":299000000},\"contextMap\":{},\"threadId\":15,\"threadPriority\":5,\"hostname\":\"4cbd459504f5\",\"service\":\"ci-example\",\"release\":\"RMBYTXJUUGO\",\"thrown\":{\"commonElementCount\":0,\"localizedMessage\":\"Connection reset by peer\",\"message\":\"Connection reset by peer\",\"name\":\"java.io.IOException\",\"extendedStackTrace\":\"java.io.IOException: Connection reset by peer\\n\\tat sun.nio.ch.FileDispatcherImpl.read0(Native Method) ~[?:1.8.0_162]\\n\\tat sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) ~[?:1.8.0_162]\\n\\tat sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[?:1.8.0_162]\\n\\tat sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[?:1.8.0_162]\\n\\tat sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ~[?:1.8.0_162]\\n\\tat io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288) ~[subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108) ~[subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345) ~[subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:126) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [subscription-api-jar-with-dependencies.jar:?]\\n\\tat java.lang.Thread.run(Thread.java:748) [?:1.8.0_162]\\n\"}}"}, + TestMessage{"[vert.x-eventloop-thread-0] INFO com.example.demo.MainVerticle - java.io.IOException: Connection reset by peer\n\tat sun.nio.ch.FileDispatcherImpl.read0(Native Method) ~[?:1.8.0_162]\n\tat sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) ~[?:1.8.0_162]\n\tat sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[?:1.8.0_162]\n\tat sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[?:1.8.0_162]\n\tat sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ~[?:1.8.0_162]\n\tat io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288) ~[subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108) ~[subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345) ~[subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:126) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) [subscription-api-jar-with-dependencies.jar:?]\n\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [subscription-api-jar-with-dependencies.jar:?]\n\tat java.lang.Thread.run(Thread.java:748) [?:1.8.0_162]\n"}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {