From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

#!perl
use strict;
use App::jl;
App::jl->new(@ARGV)->run;
__END__
=head1 NAME
jl - Show the "JSON in JSON" Log Nicely
=head1 SYNOPSIS
The B<jl> command allows you to recursively decode JSON in JSON string
$ echo '{"foo":"{\"bar\":\"{\\\"baz\\\":123}\"}"}' | jl
{
"foo" : {
"bar" : {
"baz" : 123
}
}
}
=head2 OPTIONS
=head3 x
If you set C<x> option, then JSON values and parsed elements are split as array by [\t\n\r] before/after recursive JSON decoding.
This option is useful for below case:
$ echo '{"message":"[05/09/2019 23:51:51]\t[warn]\t{\"foo\":\"bar\"}"}' | jl -x
{
"message" : [
"[05/09/2019 23:51:51]",
"[warn]",
{
"foo" : "bar"
}
]
}
TAB delimited string has been arraynized. It's easy to treat by C<jq>.
=head3 xx
If you set C<xx> option, then the elements are split as array by comma after recursive JSON decoding.
This option is useful for below case:
$ echo '{"message":"[05/09/2019 23:51:51] foo, bar, baz \n{\"foo\":\"bar\"}\n"}' | jl -xx
{
"message" : [
[
"[05/09/2019 23:51:51] foo",
"bar",
"baz "
],
{
"foo" : "bar"
}
]
}
=head3 xxx
If you set C<xxx> option, then the elements are split as array without delimiter by each parenthesis and brackets (exclude braces {}) after recursive JSON decoding.
This option is useful for below case:
$ echo '{"message":"[05/09/2019 23:51:51](warn)<server> \n{\"foo\":\"bar\"}\n"}' | jl -xxx
{
"message" : [
[
"[05/09/2019 23:51:51]",
"(warn)",
"<server>",
" "
],
{
"foo" : "bar"
}
]
}
=head3 xxxx
If you set C<xxxx> option, then the elements such like a unix timestamp are converted as local date time after recursive JSON decoding.
This option is useful for below case:
$ echo '{"message":"[05/09/2019 23:51:51](warn)<server> \n{\"time\":1560026367123}"}' | jl -xxxx
{
"message" : [
[
"[05/09/2019 23:51:51]",
"(warn)",
"<server>",
" "
],
{
"time" : "2019-06-09 05:39:27.123"
}
]
}
=head3 timestamp-key
You can set custom timestamp-key to convert unix timestamp to date time.
$ echo '{"message":"{\"ts\":1560026367123}"}' | jl --timestamp-key ts
{
"message" : {
"ts" : "2019-06-09 05:39:27.123"
}
}
Supports unixtime C<1560026367>, msec C<1560026367123> and C<1560026367.123>
=head3 xxxxx
If you set C<xxxxx> option, then forcely convert to datetime string from integer value which is over 946684800 (2000-01-01T00:00:00Z).
B<NOTE> that if you set C<xxxx> option, then it means that C<x>, C<xx> and C<xxx> are enabled as well. C<xxx> is going to be enabled C<x> and C<xx> as well. So C<xx> is including C<x>.
=head3 X
If you set C<X> (capital X) option, it's a shortcut to work as same as C<xxxxx> option.
=head3 gmtime
If you set C<gmtime> flag, then unix timestamp converts date time as GMT instead of localtime.
=head3 grep REGEXP
If set C<grep> option with regexp, filtering JSON which is matched regexp.
=head3 ignore REGEXP
If set C<ignore> option with regexp, filtering JSON which is unmatched regexp.
=head3 no-pretty
If set C<no-pretty> option, then output JSON is not prettify. (default: false, Do prettify)
=head3 yaml
If set C<yaml> option, show output string as YAML instead.
=head3 unbuffered
If set C<unbuffered> option, flush the output after each line is printed.
=head3 stderr
If set C<stderr> option, output line to STDERR instead.
=head3 sweep
If set C<sweep> option, filtering non-JSON lines. By default, non-JSON line prints as raw.
NOTE that non-JSON line, a line just consists of [\t\s\r\n] will be filtered.
=head1 AUTHOR
Dai Okabayashi E<lt>bayashi@cpan.orgE<gt>
=head1 SEE ALSO
L<App::jl>
=head1 LICENSE
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself. See L<perlartistic>.
=cut