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
},
]
1 Answer 1
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.
jqgenerates a parsing error (sojqwon't be an 'easy' solution); the sample input has 5xsampleObject{...}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 ....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)objId=c3is 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.