## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----eval = FALSE------------------------------------------------------------- # install.packages("stenographer") ## ----eval = FALSE------------------------------------------------------------- # remotes::install_github("dereckmezquita/stenographer") ## ----------------------------------------------------------------------------- box::use(stenographer[Stenographer, LogLevel, messageParallel]) # Create a basic logger steno <- Stenographer$new() # Log some messages steno$info("This is an informational message") steno$warn("This is a warning") steno$error("This is an error") ## ----------------------------------------------------------------------------- # Create a custom stenographer custom_steno <- Stenographer$new( level = LogLevel$WARNING, file_path = "app.log", print_fn = message ) custom_steno$info("This won't be logged") custom_steno$warn("This will be logged to console and file") custom_steno$error("This is an error message") ## ----------------------------------------------------------------------------- box::use(RSQLite[ SQLite ]) box::use(DBI[ dbConnect, dbDisconnect, dbGetQuery ]) # Create a database connection db <- dbConnect(SQLite(), "log.sqlite") # Create a Stenographer that logs to the database db_steno <- Stenographer$new( db_conn = db, table_name = "app_logs" ) # Log some messages db_steno$info("This is logged to the database") db_steno$warn("This is a warning", data = list(code = 101)) db_steno$error("An error occurred", error = "Division by zero") # Example of querying the logs query <- "SELECT * FROM app_logs WHERE level = 'ERROR'" result <- dbGetQuery(db, query) print(result) ## ----------------------------------------------------------------------------- context_steno <- Stenographer$new( db_conn = db, table_name = "context_logs", context = list(app_name = "MyApp", version = "1.0.0") ) context_steno$info("Application started") # Update context context_steno$update_context(list(user_id = "12345")) context_steno$info("User logged in") # Log an error with context context_steno$error("Operation failed", data = list(operation = "data_fetch")) # Example of querying logs with context query <- "SELECT * FROM context_logs WHERE json_extract(context, '$.user_id') = '12345'" result <- dbGetQuery(db, query) print(result) # Clear context context_steno$clear_context() context_steno$info("Context cleared") ## ----------------------------------------------------------------------------- # Create a combined Stenographer combined_steno <- Stenographer$new( level = LogLevel$INFO, file_path = "combined_app.log", db_conn = db, table_name = "combined_logs", context = list(app_name = "CombinedApp", version = "2.0.0"), print_fn = messageParallel, format_fn = function(level, msg) { # manipulate the message before logging msg <- gsub("API_KEY=[^\\s]+", "API_KEY=***", msg) return(paste(level, msg)) } ) # Log some messages combined_steno$info("Application started") combined_steno$warn("Low memory", data = list(available_mb = 100)) combined_steno$error("Database connection failed", error = "Connection timeout") # Update context combined_steno$update_context(list(user_id = "67890")) combined_steno$info("User action", data = list(action = "button_click")) # Example of a more complex query using context and data query <- " SELECT * FROM combined_logs WHERE json_extract(context, '$.app_name') = 'CombinedApp' AND json_extract(data, '$.available_mb') < 200 " result <- dbGetQuery(db, query) print(result) # Don't forget to close the database connection when you're done dbDisconnect(db) ## ----------------------------------------------------------------------------- box::use(stenographer[valueCoordinates]) # Create a sample dataset with some issues df <- data.frame( a = c(1, NA, 3, 4, 5), b = c(2, 4, NA, 8, 10), c = c(3, 6, 9, NA, 15) ) # Create a Stenographer steno <- Stenographer$new() # Find coordinates of NA values na_coords <- valueCoordinates(df) if (nrow(na_coords) > 0) { steno$warn( "NA values found in the dataset", data = list( na_locations = na_coords ) ) } ## ----------------------------------------------------------------------------- box::use(stenographer[tableToString]) steno <- Stenographer$new() process_data <- function(df) { tryCatch({ result <- df$a / df$b if (any(is.infinite(result))) { inf_coords <- valueCoordinates(data.frame(result), Inf) steno$error( "Division by zero occurred", data = list( infinite_values = inf_coords, dataset_preview = tableToString(df) ) ) cat("Division by zero error") } return(result) }, error = function(e) { steno$error( paste("An error occurred while processing data:", e$message), data = list(dataset_preview = tableToString(df)), error = e ) cat(e) }) } # Test the function with problematic data df <- data.frame(a = c(1, 2, 3), b = c(0, 2, 0)) process_data(df) ## ----------------------------------------------------------------------------- box::use(future) box::use(future.apply[future_lapply]) steno <- Stenographer$new(print_fn = messageParallel) future::plan(future::multisession, workers = 2) result <- future_lapply(1:5, function(i) { messageParallel(sprintf("Processing item %d", i)) if (i == 3) { steno$warn(sprintf("Warning for item %d", i)) } return(i * 2) }) future::plan(future::sequential)