question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The message attribute in the JSON log has backslash, new line and special charecters

See original GitHub issue

Hi Team,

I have applied the logstash-logback-encoder and the logs generate in JSON format but some portion of the logs as below for message attritbute still has backslash, new line and special charecters in it.

{"@timestamp":"2018-01-31T19:21:27.624+04:00","@version":1,"message":"{\"type\":\"API_REQUEST\",\"uid\":\"35f53fe5-7c63-4936-a617-14601073a5f7\",\"sessionId\":\"9E998B68C5A6D66C30D215DE0B4B5EF3\",\"remoteAddress\":\"0:0:0:0:0:0:0:1\",\"methodType\":\"POST\",\"headers\":\"{content-length=76, accept-language=en-US,en;q=0.9, cookie=JSESSIONID=50D17B32E96A6A8850F2A5FD52A4C07D, postman-token=a5be9806-a0a6-3905-e45d-2bea9036f3ed, origin=chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop, accept=*/*, host=localhost:3080, connection=keep-alive, content-type=application/json, cache-control=no-cache, accept-encoding=gzip, deflate, br, user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36}\",\"uri\":\"/user/login\",\"query\":null,\"contentType\":\"application/json\",\"requestTime\":\"2018-01-31 19:21:26.024\",\"responseTime\":\"2018-01-31 19:21:27.604\",\"executionTimeMillisecond\":1580,\"requestPayload\":\"{\\n \\\"\\": \\\"+971\\\",\\n \\\"phone\\\": \\\"545901009\\\",\\n \\\"employeeType\\\": \\\"PHONE\\\"\\n }\",\"responsePayload\":\"{\\\"status\\\":\\\"FAIL\\\",\\\"statusCode\\\":1000,\\\"message\\\":\\\"Internal Server Error\\\",\\\"desc\\\":\\\"FAIL\\\",\\\"debug\\\":\\\"org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: non null key required\\\\n\\\\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)\\\\n\\\\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)\\\\n\\\\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:648)\\\\n\\\\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)\\\\n\\\\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:729)\\\\n\\\\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)\\\\n\\\\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)\\\\n\\\\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)\\\\n\\\\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)\\\\n\\\\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)\\\\n\\\\tat

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:34

github_iconTop GitHub Comments

3reactions
philsttrcommented, Feb 21, 2018

You are encountering the main problem with trying to serialize every argument as JSON. Jackson is not able to serialize every object due to things like infinite recursion in object graphs, like you are encountering.

My recommendation is to not try to serialize every argument as JSON. Again, because there is no guarantee that jackson will be able to serialize every type of object passed as an argument as JSON. You are extremely likely to encounter objects that are not JSON serializable by jackson, unless custom class-specific hints (such as JsonSerializers or mixin) are registered for the class.

Instead, I would recommend utilizing StructuredArguments. When StructuredArguments are used, it forces the developer to follow the contract of a StructuredArgument… in that the argument must be JSON serializable. This forces developers to select which arguments it makes sense to try to JSON-serialize, and ensure those classes JSON-serializable.

However, if you would like to continue trying to serialize every argument, then you are going to have to come up with your own strategy. Most likely that strategy is not going to be able to magically make every object JSON-serializable. Therefore, you’re going to have to make compromises.

For example, a simple strategy might be to whitelist classes that are known to be serializable, and not attempt to serialize classes that are not in the whitelist in your JsonProvider.

For classes that jackson cannot serialize by default, you can register mixins and custom serializers in a JsonFactoryDecorator. After including the appropriate mixin or custom serializer, you can add them to your whitelist.

You could also take the opposite approach, by having a blacklist… i.e. classes that are known to NOT be serializable. And only serialize classes that are not in that list. This would be more error prone than a whitelist approach, since new classes (that might not be serializable) are invented every day.

Another strategy would be to catch the exceptions from jackson in your JsonProvider, and dynamically add the classes that cannot be serialized by jackson to a list of blacklisted classes at runtime. (Therefore preventing them from being attempted to be serialized again).

There are probably other strategies that you can think of that will work for you.

The choice is yours to make. You will need to pick a compromise with which you are willing to live.

The logstash-logback-encoder library gives you the tools needed to implement your strategy. You can configure the JsonFactory, ObjectMapper, and JsonGenerator exactly how you want it with decorators. And you can create your own JsonProvider with full control over what to write to the JsonGenerator. You can experiment with Jackson, and find what options work best for you.

1reaction
philsttrcommented, Feb 17, 2018

LoggingEventCompositeJsonEncoder encodes LoggingEvents as JSON by using JsonProviders. By default, LoggingEventCompositeJsonEncoder has no providers. It’s up to you to add the providers that you want to get the output you want.

Each provider contributes something to the JSON output by the encoder. For example, the timestamp provider will add the LoggingEvent’s timestamp to the JSON output. logstash-logback-encoder comes with many providers, but you can also add your own if those provided by logstash-logback-encoder do not handle your use case.

LogstashEncoder is a subclass of LoggingEventCompositeJsonEncoder with a set of providers pre-configured as sensible defaults.

Both LogstashEncoder and LoggingEventCompositeJsonEncoder use providers to contribute to the output. It’s just that LogstashEncoder starts with a set of default providers to handle common use cases, and LoggingEventCompositeJsonEncoder starts with no providers.

For simple use cases, users can just use LogstashEncoder.

For complex use cases, it might be easier to start with LoggingEventCompositeJsonEncoder, and add the exact providers what you want, rather than starting with LogstashEncoder, and trying to remove/add/override functionality. For example, if you want to customize the ordering of fields in the JSON output, you can configure LoggingEventCompositeJsonEncoder with providers in the order you want. Or if you want to override some of the providers used by LogstashEncoder (like your desire to not output the formatted message field), it might be easier to use LoggingEventCompositeJsonEncoder

In summary, for your use case, I would recommend LoggingEventCompositeJsonEncoder, but you could probably still use LogstashEncoder if you wanted.

Here’s what your configuration could potentially look like using the LoggingEventCompositeJsonEncoder. You can also add any other provider you want, depending on what you want included in the JSON output.

(Notice that the rawMessage provider is used here. This can be used instead of your UnformattedMessageJsonProvider. I didn’t realize that logstash-logback-encoder already had a provider that outputs the unformatted message.)

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
	<providers>
		<!-- Write a @timestamp field containing the LoggingEvent's timestamp-->
		<timestamp/>

		<!-- Write a @version field containing a value of 1-->
		<version/>

		<!-- Write a message field containing the raw/unformatted LoggingEvent message-->
		<rawMessage>
			<fieldName>message</fieldName>
		</rawMessage>

		<!-- Write the LoggingEvent's arguments as separate fields-->
		<provider class="config.NamedArgumentJsonProvider"/>
	</providers>
</encoder>

Regarding the clubbed messages, there is probably an exception occurring while generating the JSON output. I would recommend registering a logback status listener so you can see error messages and exceptions from logback. You can use <configuration debug="true"> or <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />

Read more comments on GitHub >

github_iconTop Results From Across the Web

The message attribute in the JSON log has backslash, new ...
Hi Team,. I have applied the logstash-logback-encoder and the logs generate in JSON format but some portion of the logs as below for...
Read more >
How to escape a JSON string containing newline characters ...
I tried escaping the new line character \n to \\n. It is working fine. But i am looking for any JS library which...
Read more >
Escaping new line character in JSON to avoid data loading ...
This article details how to escape the new-line character to avoid such data loading errors. JSON strings do not allow real newlines in...
Read more >
How FOR JSON escapes special characters and control ...
If the source data contains special characters, the FOR JSON clause escapes them in the JSON output with \ , as shown in...
Read more >
The message attribute in the JSON log has backslash, new ...
The message attribute in the JSON log has backslash, new line and special charecters.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found