# NAME
Log::Any::Adapter::JSON - One-line JSON logging of arbitrary structured data
# SYNOPSIS
Get a logger and specify the output destination:
use Log::Any '$log';
use Log::Any::Adapter ('JSON', '/path/to/file.log');
# or
use Log::Any '$log';
use Log::Any::Adapter;
my $handle = ...; # FH, pipe, etc
Log::Any::Adapter->set('JSON', $handle);
Log some data:
$log->info('Hello, world');
$log->info('Hello, %s', $name);
$log->debug('Blabla', { tracking_id => 42 });
$log->debug('Blorgle', { foo => 'bar' }, [qw/a b c/], 'last thing');
# DESCRIPTION
This [Log::Any](
https://metacpan.org/pod/Log%3A%3AAny) adapter logs formatted messages and arbitrary structured
data in a single line of JSON per entry. You must pass a filename or an open
handle to which the entries will be printed.
Optionally you may pass an `encoding` argument which will be used to apply
a `binmode` layer to the output handle. The default encoding is `UTF-8`.
# OUTPUT
## Logged data fields
The adapter expects a string and an optional list `@items`.
If the string has no formatting tokens, it is included in the log
entry in the `message` field as-is.
If the string has formatting tokens, `@items` is checked to verify
that the next `N` values are scalars, where `N` is the number of
tokens in the string. If the number is the same, the string and
tokens are combined using `sprintf()` and the resulting string is
included in the log entry in the `message` field. If the token
and value counts don't match, the adapter croaks.
After the format processing, the remainder of the `items` array is
processed. It may hold arrayrefs, which are included in a top-
level key named `list_data`; additional scalars, which are pushed
into the `additional_messages` key; and hashrefs. The first hashref
encountered has its keys promoted to top-level keys in the log entry,
while additional hashrefs are included in a top-level key named
`hash_data`.
## Other fields
In addition, the log entry will have the following fields:
- `time`
- `level`
- `category`
# EXAMPLES
## Plain text message
$log->debug('a simple message');
Output is a **single line** with JSON like:
{
"category":"main",
"level":"debug",
"message":"hello, world",
"time":"2021-03-03T17:23:25.73124"
}
## Formatted message
my $val = "string";
my $num = 2;
$log->debug('a formatted %s with %d tokens', $val, $num);
Output is a **single line** with JSON like:
{
"category":"main",
"level":"debug",
"message":"a formatted string with 2 tokens",
"time":"2021-03-03T17:23:25.73124"
}
## Single hashref
The first hashref encountered has its keys elevated to the top level.
$log->debug('the message', { tracker => 42 });
Output is a **single line** with JSON like:
{
"category":"main",
"level":"debug",
"message":"the message",
"time":"2021-03-03T17:23:25.73124",
"tracker":42
}
Reserved key names that may not be used in the first hashref include:
* category
* context
* level
* message
* time
## Additional hashrefs and arrayrefs
$log->debug('the message', { tracker => 42 }, { foo => 'bar'});
Output is a **single line** with JSON like:
{
"category":"main",
"hash_data":{
"foo":"bar"
},
"level":"debug",
"message":"the message",
"time":"2021-03-03T17:23:25.73124",
"tracker":42
}
Another example:
$log->debug('the message', { tracker => 42 }, {foo => 'bar'}, [1..3]);
Output is a **single line** with JSON like:
{
"category":"main",
"hash_data":[
{"foo":"bar"}
],
"level":"debug",
"list_data":[
[1,2,3]
],
"message":"the message",
"time":"2021-03-03T17:23:25.73124",
"tracker":42
}
## Additional messages
Any scalars that are passed that are not consumed as the values of formatting
tokens will be included in an `additional_messages` key.
$log->debug('a simple message', 'foo', 'bar');
Output is a **single line** with JSON like:
{
"additional_messages":[
'foo',
'bar'
],
"category":"main",
"level":"debug",
"message":"hello, world",
"time":"2021-03-03T17:23:25.73124"
}
# SEE ALSO
[Log::Any](
https://metacpan.org/pod/Log%3A%3AAny)
[Log::Any::Adapter](
https://metacpan.org/pod/Log%3A%3AAny%3A%3AAdapter)