-3

I have to review lots of java logs from various sources, that contain java objects dumped to a single long line. Sometimes I'd like to see them in a more formatted fashion. Note that I'm not in control of the logging or the logs I receive.

Are there any command line tools that will format these types of objects nicely? I'm not looking for perfectly, but something like json formatting?

A sample object

[sampleObject{objId=c1, request=sampleRequest(bean=bean1, method=method1), env=job(pattern=*), step=1, state=SUCCESS}, sampleObject{objId=c2, request=sampleRequest(bean=bean1, method=method1), env=job(pattern=*), step=1, state=SUCCESS}, sampleObject{objId=c2, request=sampleRequest(bean=bean1, method=method2), env=job(pattern=*), step=2, state=SUCCESS}, sampleObject{objId=c3, request=sampleRequest(bean=bean1, method=method1), env=job(pattern=*), step=1, state=SUCCESS}, sampleObject{objId=c3, request=sampleRequest(bean=bean1, method=method2), env=job(pattern=*), step=2, state=SUCCESS}]

Sample desired output

[
 sampleObject{
 objId=c1,
 request=sampleRequest(
 bean=bean1,
 method=method1
 ),
 env=job(
 pattern=*
 ),
 step=1,
 state=SUCCESS
 },
 sampleObject{
 objId=c2,
 request=sampleRequest(
 bean=bean1,
 method=method2
 ),
 env=job(
 pattern=test
 ),
 step=2,
 state=SUCCESS
 },
]
asked Mar 8, 2024 at 14:59
4
  • fwiw, feeding that string to jq generates a parsing error (so jq won't be an 'easy' solution); the sample input has 5x sampleObject{...} blocks while the expected output only has 2x such blocks (can't tell if this is a typo or if we're missing instructions on how to filter out desired blocks); sample input ends with }] but the expected output ends with },] (can't tell if this is a typo or we're supposed to 'add' to the data); [ and { are followed by 2-char indents while ( is followed by 4-char indents (variable indent req's?); so .... Commented Mar 8, 2024 at 17:14
  • (imo) looks like a candidate for a custom script (awk, perl, java, etc) to do the pretty-printing; wrapping in a (bash) function would make it easier to call (either on a line-by-line basis or processing a whole log file at once) Commented Mar 8, 2024 at 17:15
  • yeah the formatting is mostly indent on any braces, like (, [ or { and I think a bash script is probably what I will do, if no solutions pop up and no filtering required, I just supplied 2 examples, since they all follow that general pattern Commented Mar 8, 2024 at 17:57
  • 1
    Your expected output doesn't match your sample input (objId=c3 is missing, idk what else is different) so we can't test a potential solution with it. Make sure the minimal reproducible example you post is exactly that so it's as easy as possible for people to help you. Commented Mar 9, 2024 at 8:15

1 Answer 1

2

A quick google for convert java object to json so you could then use jq or similar to pretty-print produced hits for tools named Jackson and GSON as well as the obvious suggestion of reading the Java output into a Java script and printing it however you like from there.

If you can't do any of that, though, then below is a character-by-character brute-force approach using any awk. Your expected output doesn't match your sample input so idk if this does what you want or not but it looks like it might, or at least be close.

$ cat tst.awk
BEGIN { incIn = 3 }
{
 out = ""
 numChars = length()
 for ( i=1; i<=numChars; i++ ) {
 char = substr(0,ドルi,1)
 if ( char ~ /[[{(]/ ) {
 indent += incIn
 out = out sprintf("%s\n%*s", char, indent, "")
 }
 else if ( char ~ /[]})]/ ) {
 indent -= incIn
 out = out sprintf("\n%*s%s", indent, "", char)
 }
 else if ( char == "," ) {
 out = out sprintf("%s\n%*s", char, indent, "")
 }
 else if ( char != " " ) {
 out = out char
 }
 }
 print out
}

$ awk -f tst.awk file
[
 sampleObject{
 objId=c1,
 request=sampleRequest(
 bean=bean1,
 method=method1
 ),
 env=job(
 pattern=*
 ),
 step=1,
 state=SUCCESS
 },
 sampleObject{
 objId=c2,
 request=sampleRequest(
 bean=bean1,
 method=method1
 ),
 env=job(
 pattern=*
 ),
 step=1,
 state=SUCCESS
 },
 sampleObject{
 objId=c2,
 request=sampleRequest(
 bean=bean1,
 method=method2
 ),
 env=job(
 pattern=*
 ),
 step=2,
 state=SUCCESS
 },
 sampleObject{
 objId=c3,
 request=sampleRequest(
 bean=bean1,
 method=method1
 ),
 env=job(
 pattern=*
 ),
 step=1,
 state=SUCCESS
 },
 sampleObject{
 objId=c3,
 request=sampleRequest(
 bean=bean1,
 method=method2
 ),
 env=job(
 pattern=*
 ),
 step=2,
 state=SUCCESS
 }
]

Obviously if any of the chars being specifically tested by the script can appear in other contexts (e.g. inside strings or comments) then you'd need to modify the code to handle those cases.

answered Mar 9, 2024 at 8:27
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.