Skip to contents

Integrate the message printing function with the cli package, and the base::message function. The message could be suppressed by base::suppressMessages.

Usage

log_message(
  ...,
  verbose = TRUE,
  message_type = c("info", "success", "warning", "error"),
  cli_model = TRUE,
  level = 1,
  symbol = "  ",
  text_color = NULL,
  back_color = NULL,
  text_style = NULL,
  multiline_indent = FALSE,
  timestamp = TRUE,
  timestamp_format = paste0("[", format(Sys.time(), "%Y-%m-%d %H:%M:%S"), "] "),
  timestamp_style = TRUE,
  .envir = parent.frame(),
  .frame = .envir
)

Arguments

...

The message to print.

verbose

Whether to print the message. Default is TRUE.

message_type

Type of message. Could be choose one of info, success, warning, and error. Default is info.

cli_model

Whether to use the cli package to print the message. Default is TRUE.

level

The level of the message, which affects the indentation. Level 1 has no indentation, higher levels add more indentation. Default is 1.

symbol

The symbol used for indentation. When specified, it ignores the level parameter and uses the symbol directly. Default is " " (two spaces).

text_color

Color for the message text. Supports R color names (e.g., "orange"), hexadecimal colors (e.g., "#000000"), basic colors: "red", "green", "blue", "yellow", "magenta", "cyan", "white", "black", "grey", "silver", "none", and bright colors: "br_red", "br_green", "br_blue", "br_yellow", "br_magenta", "br_cyan", "br_white", "br_black". Default is NULL.

back_color

Background color for the message text. Details see parameter text_color. Default is NULL.

text_style

Text styles to apply. Can be one or more of: "bold", "italic", "underline", "strikethrough", "dim", "inverse". Multiple styles can be combined (e.g., c("bold", "underline")). Default is NULL.

multiline_indent

Whether to apply consistent formatting (timestamp and indentation) to each line in multiline messages. When TRUE, each line gets the full formatting; when FALSE, only the first line gets the timestamp. Default is FALSE.

timestamp

Whether to show the current time in the message. Default is TRUE.

timestamp_format

Format string for timestamp display. Default is "%Y-%m-%d %H:%M:%S".

timestamp_style

Whether to apply the same text styling to the timestamp as the message text. When TRUE, timestamp formatting matches the message; when FALSE, timestamp keeps its default appearance. Default is TRUE.

.envir

The environment to evaluate calls in. Default is parent.frame().

.frame

The frame to use for error reporting. Default is .envir.

Value

Formated message.

Examples

# basic usage
log_message("Hello, ", "world!")
#>  [2025-07-25 01:38:52] Hello, world!

log_message("hello, world!")
#>  [2025-07-25 01:38:52] Hello, world!

log_message("Hello, world!", timestamp = FALSE)
#>  Hello, world!

log_message(
  "Hello, ", "world!",
  message_type = "success"
)
#>  [2025-07-25 01:38:52] Hello, world!

log_message(
  "Hello, world!",
  message_type = "warning"
)
#> ! [2025-07-25 01:38:52] Hello, world!

log_message(
  "Hello, ", "world!",
  cli_model = FALSE
)
#> Hello, world!


# suppress messages
suppressMessages(log_message("Hello, world!"))
log_message("Hello, world!", verbose = FALSE)
options(log_message.verbose = FALSE)
log_message("Hello, world!")

# for global verbose option
options(log_message.verbose = TRUE)
log_message("Hello, world!", verbose = FALSE)
#>  [2025-07-25 01:38:52] Hello, world!
options(log_message.verbose = NULL)


# cli inline markup
log_message("{.arg abc} is a argument")
#>  [2025-07-25 01:38:52] `abc` is a argument

## 'message' can not deal with cli inline markup
message("hello, {.code world}!")
#> hello, {.code world}!

log_message("{.val list('abc')} is a {.cls {class(list('abc'))}}")
#>  [2025-07-25 01:38:52] "list('abc')" is a <list>

log_message("{.code lm(y ~ x)} is a code example")
#>  [2025-07-25 01:38:52] `lm(y ~ x)` is a code example

log_message("{.dt List}list('abc')")
#>  [2025-07-25 01:38:52] List: list('abc')

log_message("address: {.email example@example.com}")
#>  [2025-07-25 01:38:52] Address: example@example.com

log_message("{.emph R} is a programming language")
#>  [2025-07-25 01:38:52] R is a programming language

log_message("{.envvar R_HOME}")
#>  [2025-07-25 01:38:52] `R_HOME`

log_message("{.file log_message.R} is a file")
#>  [2025-07-25 01:38:52] log_message.R is a file

log_message("{.fn lm} is a function")
#>  [2025-07-25 01:38:52] `lm()` is a function

log_message("{.fun lm} is a function")
#>  [2025-07-25 01:38:52] `lm()` is a function

log_message("{.help lm} to get help")
#>  [2025-07-25 01:38:52] `?lm()` to get help

log_message("... see {.help [{.fun lm}](stats::lm)} to learn more")
#>  [2025-07-25 01:38:52] ... see `lm()` (`?stats::lm()`) to learn more

log_message(
  "See the {.href [cli homepage](https://cli.r-lib.org)} for details"
)
#>  [2025-07-25 01:38:52] See the cli homepage (<https://cli.r-lib.org>) for details

log_message("press {.kbd ENTER}")
#>  [2025-07-25 01:38:52] Press [ENTER]

log_message("press {.key ENTER}")
#>  [2025-07-25 01:38:52] Press [ENTER]

log_message("URL: {.url https://cli.r-lib.org}")
#>  [2025-07-25 01:38:52] URL: <https://cli.r-lib.org>

log_message("Some {.field field}")
#>  [2025-07-25 01:38:52] Some field

log_message("{.path /usr/bin/R} is a path")
#>  [2025-07-25 01:38:52] /usr/bin/R is a path

log_message("{.pkg cli} is a package")
#>  [2025-07-25 01:38:53] cli is a package

log_message("{.val object} is a variable")
#>  [2025-07-25 01:38:53] "object" is a variable

log_message("{.run Rscript log_message.R} is a runnable file")
#>  [2025-07-25 01:38:53] `Rscript log_message.R` is a runnable file

log_message("{.str object} is a string")
#>  [2025-07-25 01:38:53] "object" is a string

log_message("{.strong abc} is a strong string")
#>  [2025-07-25 01:38:53] abc is a strong string

log_message("{.topic stats::lm} is a topic")
#>  [2025-07-25 01:38:53] `?stats::lm` is a topic

log_message("{.vignette cli} is a vignette")
#>  [2025-07-25 01:38:53] `vignette(cli)` is a vignette


# set indentation
log_message("Hello, world!", level = 2)
#>  [2025-07-25 01:38:53]   Hello, world!

log_message("Hello, world!", symbol = "->")
#>  [2025-07-25 01:38:53] -> Hello, world!

log_message(
  "Hello, world!",
  symbol = "#####",
  level = 3
)
#>  [2025-07-25 01:38:53] ############### Hello, world!

# color formatting
log_message(
  "This is a red message",
  text_color = "#ff9900"
)
#>  [2025-07-25 01:38:53] This is a red message

log_message(
  "This is a message with background",
  back_color = "#EE4000"
)
#>  [2025-07-25 01:38:53] This is a message with background

log_message(
  "This is a message with both text and background",
  text_color = "white",
  back_color = "cyan"
)
#>  [2025-07-25 01:38:53] This is a message with both text and background

log_message(
  "This is a message with background",
  back_color = "#EE4000",
  cli_model = FALSE
)
#> This is a message with background

log_message(
  "This is a message with both text and background",
  text_color = "red",
  back_color = "cyan",
  cli_model = FALSE
)
#> This is a message with both text and background

log_message(
  "Hex color with {.arg cli_model = FALSE}",
  text_color = "#FF5733",
  cli_model = FALSE
)
#> Hex color with `cli_model = FALSE`

log_message(
  "Bright red text",
  text_color = "br_red"
)
#>  [2025-07-25 01:38:53] Bright red text

log_message(
  "Bright background",
  back_color = "br_yellow"
)
#>  [2025-07-25 01:38:53] Bright background

log_message(
  "Combined grey and style",
  text_color = "grey",
  text_style = "bold"
)
#>  [2025-07-25 01:38:53] Combined grey and style

# text style formatting
log_message(
  "Bold message",
  text_style = "bold"
)
#>  [2025-07-25 01:38:53] Bold message

log_message(
  "Italic message",
  text_style = "italic"
)
#>  [2025-07-25 01:38:53] Italic message

log_message(
  "Underlined message",
  text_style = "underline"
)
#>  [2025-07-25 01:38:53] Underlined message

log_message(
  "Combined styles",
  text_style = c("bold", "underline")
)
#>  [2025-07-25 01:38:53] Combined styles

log_message(
  "Color and style",
  text_color = "blue",
  text_style = c("bold", "italic")
)
#>  [2025-07-25 01:38:53] Color and style

log_message(
  "Hex color and style",
  text_color = "#FF5733",
  text_style = c("bold", "underline")
)
#>  [2025-07-25 01:38:53] Hex color and style


# multiline message
log_message(
  "Line 1\nLine 2\nLine 3",
  multiline_indent = TRUE,
  text_style = "italic"
)
#>  [2025-07-25 01:38:53] Line 1
#>  [2025-07-25 01:38:53] Line 2
#>  [2025-07-25 01:38:53] Line 3

log_message(
  "Multi-line\ncolored\nmessage",
  text_color = "blue",
  text_style = "italic"
)
#>  [2025-07-25 01:38:53] Multi-line
#>                        colored
#>                        message

log_message(
  "Multi-line\ncolored\nmessage",
  text_color = "blue",
  timestamp = FALSE
)
#>  Multi-line
#>  colored
#>  message

# timestamp styling
log_message(
  "Multi-line message\nwith timestamp styling",
  text_color = "red",
  text_style = "bold",
  timestamp_style = TRUE
)
#>  [2025-07-25 01:38:53] Multi-line message
#>                        with timestamp styling

log_message(
  "Multi-line message\nwithout timestamp styling",
  text_color = "#669999",
  text_style = c("bold", "italic"),
  timestamp_style = FALSE
)
#>  [2025-07-25 01:38:53] Multi-line message
#>                        without timestamp styling


# combine cli package and log_message
log_message(
  cli::col_green(
    "I am a green line ",
    cli::col_blue(
      cli::style_underline(
        cli::style_bold("with a blue substring")
      )
    ),
    " that becomes green again!"
  )
)
#>  [2025-07-25 01:38:53] I am a green line with a blue substring that becomes green again!

# cli variables
fun <- function(x = 1) {
  log_message("{.val x}")
  log_message("{.val {x}}")
  log_message("{.val {x + 1}}")
}
fun()
#>  [2025-07-25 01:38:53] "x"
#>  [2025-07-25 01:38:53] 1
#>  [2025-07-25 01:38:53] 2