Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I create a custom log format for JSON files like say one for logstash? #29

Closed
chintanp opened this issue Nov 24, 2019 · 2 comments

Comments

@chintanp
Copy link

I say the custom format for logstash, like done by NodeJS logger Winston (https://github.com/winstonjs/logform#logstash).

This would be look something like so:

{"@message":"analysis status updated to processing ","@timestamp":"2019-11-23T21:39:41.853Z","@fields":{"level":"info","IP":"128.95.204.113"}}

This isnt, ofcourse, too critical as logstash can parse the JSON generated by lgr. Wanted to understand how I can totally transform the log format. I am able to add custom fields right now.

@s-fleck
Copy link
Owner

s-fleck commented Nov 25, 2019

So to achieve this, you have to create your own Layout. This is pretty straight forward, but you need to know a bit about R6 classes and the inner workings of lgr [that are properly not documented sufficiently]. Basically you just have to inherit from LayoutJson and modify it's format_event() method to transform the log event before writing the JSON output.

LayoutLogstash <- R6::R6Class(
  "LayoutLogstash",
  inherit = lgr::LayoutJson,
  public = list(
    format_event = function(event) {
      dd <- list(
        "@message" = event$msg,
        "@timestamp" = event$timestamp,
        "@fields" = c(
          level = unname(event$level_name), 
          event$values[setdiff(names(event$values), c("timestamp", "msg", "level"))]
        )
      )
      do.call(
        jsonlite::toJSON,
        args = c(list(x = dd), get(".toJSON_args", private))
      )
    }  
  )
)

lg <- lgr::get_logger("test")
lg$add_appender(lgr::AppenderJson$new(layout = LayoutLogstash$new(), file = tempfile()), name = "logstash")
lg$info("test")
lg$appenders$logstash$show()

This is also a nicer place to label the levels with label_levels() than the filter solution from the other issue (because the filter modifies the event for all appenders connected to the logger)

@s-fleck
Copy link
Owner

s-fleck commented Dec 7, 2019

edit: I forgott hat you can just use event$level_name to get the character representation of a log level, no need to call lgr::label_levels(event$level) manually

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants