---
title: "Layouts"
author: Brandon Moretz
date: "`r Sys.Date()`"
output:
  prettydoc::html_pretty:
    theme: architect
    highlight: github
vignette: >
  %\VignetteIndexEntry{Layouts}
  %\VignetteEngine{knitr::rmarkdown}
  \usepackage[utf8]{inputenc}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```
# Format Objects

```{r setup}
library(dyn.log)

configs <- dyn.log::get_configurations(pkgname = "dyn.log")

init_logger(configs$knitr)
```

```{r, comment="", results="asis", echo=F}
options(crayon.enabled=TRUE)
knitr::opts_chunk$set(collapse = TRUE,
                      fig.path = "man/figures/FORMAT-",
                      comment = "")
old.hooks <- fansi::set_knit_hooks(knitr::knit_hooks)
```

## Overview

Log **Layouts** are the mechanism that ties everything in the package together with a composition based design. A log layout is essentially a container for formats, which defines exactly how the log message will get rendered. Layouts also have additional metadata attributes which allow for overrides to the default format *separators*, *spacing*, etc., as well as mechanism for associating a particular log layout with a type of R6 class.

### Defaults

There are two basic layouts that come with the standard configuration (*default.yaml*) bundled with the package, **default** and **log_level**.

```yaml
layouts:
- association: default
  seperator: ' '
  new_line: \n
  formats: new_fmt_log_level(),
           new_fmt_timestamp(crayon::silver$italic),
           new_fmt_log_msg()
- association: level_msg
  seperator: ' '
  new_line: \n
  formats: new_fmt_log_level(),
           new_fmt_log_msg()

```

The R equivalent of creating the default layout is essentially the same as the yaml definition:

```{r}
new_log_layout(
  format = list(
    new_fmt_log_level(),
    new_fmt_timestamp(crayon::silver$italic),
    new_fmt_log_msg()    
  ),
  association = "default_via_r"
)
```

An info level log message generated with the package default config:

```{r}
Logger$info("this is the default layout")
```

Now with the new layout defined above:

```{r}
Logger$info("this is the custom layout object", layout = "default_via_r")
```

which render the exact same output, the idea here is that defining layouts via custom R code or via yaml in the configuration are exactly the same.

### Customization

To create a customized log layout you only need to specify what formats you want rendered (and their arguments) in the formats argument, as seen above. See the **Formats** vignette for more detail on formats.

```{r}
new_log_layout(
  format = list(
    new_fmt_metric(crayon::green$bold, "sysname"),
    new_fmt_metric(crayon::yellow$bold, "release"),
    new_fmt_line_break(),
    new_fmt_log_level(),
    new_fmt_timestamp(crayon::silver$italic),
    new_fmt_exec_scope(crayon::magenta$bold, "calling_fn"),
    new_fmt_literal(crayon::blue$italic, "literal text"),
    new_fmt_log_msg(),
    new_fmt_line_break(),
    new_fmt_exec_scope(crayon::cyan$bold, "call_stack")
  ),
  seperator = '-',
  association = "log-with-callstack"
)
```

```{r}
log_fn <- function() {
  outer <- function() {
    inner <- function() {
      
      var1 <- "abc"; var2 <- 123; var3 <- round(runif(1), digits = 6)
      
      Logger$debug("my log message - var1: '{var1}', var2: '{var2}', var3: '{var3}'", 
                   layout = 'log-with-callstack')
    }
    inner()
  }
  outer()
}

log_fn()
```

