google / flogger

A Fluent Logging API for Java
Apache License 2.0
1.45k stars 123 forks source link

Provide a log writer to produce JSON log items according to Elastic Common Schema #357

Closed hlemcke closed 11 months ago

hlemcke commented 11 months ago

In addition to "log(String, ...)" provide something like "logJson(Map<String,Object>)" and a class with predefined keys from Elastic Common Schema.

It would make sense to also provide an option to set some predefined keys to Floggerwhich will be used (merged) by method "logJson()" when writing the log entry. (keys like application name and current version)

chaoren commented 11 months ago

You can use a MetadataKey for this, no? logJson seems like an unnecessary addition that goes against the fluent design of the flogger API.

hlemcke commented 10 months ago

The fluent Api is and should stay as a basic design rule. Json logging would only be an addition. I would appreciate to have two methods like:

chaoren commented 10 months ago

The fluent design is kind of the whole point of Flogger. It's even in the name! It's repeated several times throughout https://google.github.io/flogger/anatomy that this is a very intentional design choice.

For example https://google.github.io/flogger/anatomy#fluent-api

Flogger’s API is designed to require only a single conceptual log method in its API.

If we are to add logJson for this "Elastic Common Schema," then we'd be expected to add a different log method for all the different schemas out there. We'd end up with log, logJson, logXml, logCsv, etc, for every data format imaginable. A single log method plus whatever configuration you want in the fluent chain leading up to it already provides everything necessary to achieve what you're asking for. There is absolutely zero need for a separate log method.

chaoren commented 10 months ago

You could just write a flogger extension so instead of needing logJson(String message, Map<String,Object> jsonMap), you can just do withJson(Map<String,Object> jsonMap).log(String message). Please see https://google.github.io/flogger/anatomy for why we don't want logJson to be a single method.

hlemcke commented 10 months ago

Hi charoren. Thanks for still helping me out. It definitiely feels best to go with something like withJson(Map<String,Object> jsonMap).log(String message)! Do you have any hint where I can find some examples how to implement this?

chaoren commented 10 months ago

You can find some good answers by searching for this on the internet:

You could also ask directly on https://stackoverflow.com/ if those answers are not sufficient.

hlemcke commented 10 months ago

That helps. Thank you very much!

hagbard commented 10 months ago

See my new site dedicated to providing better Flogger documentation: https://hagbard.github.io/the-flogger-manual/advanced/#metadata-contexts-and-scopes

You can implement passing the data without need for a new API method by using a suitably named metadata key:

private static final MetadataKey<MyJsonMapType> JSON_MAP = MetadataKey.single("json_map", MyJsonMapType.class);

logger.atWarning().with(JSON_MAP, map).log(...);

Passing structured or semi-structured data is exactly what metadata is for.

Also, if you want the same values passed to lots of log statements, use ScopedLoggingContexts rather than passing values in. This also gives you access to Tags, which might be just what you want.

HOWEVER, what the logger backend does with this is a different issue. What do you actually want the output to be (you might need a new backend or a customized MetadataKey) ?