| Title: | Logging in 'R' and Post to 'Azure Log Analytics' Workspace |
|---|---|
| Description: | It extends the functionality of 'logger' package. Additional logging metadata can be configured to be collected. Logging messages are displayed on console and optionally they are sent to 'Azure Log Analytics' workspace in real-time. |
| Authors: | Vivek Atal [aut, cre] (ORCID: <https://orcid.org/0000-0002-9948-7458>) |
| Maintainer: | Vivek Atal <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.0.6 |
| Built: | 2026-05-18 08:31:07 UTC |
| Source: | https://github.com/atalv/azlogr |
Add additional meta variables in the logging context on top of the ones
that are readily collected in get_logger_meta_variables
function. It might be needed to add some other metadata specific to the
logging usage - that goal is served by this function.
.add_meta_variables( additional_fields = NULL, log_level = NULL, namespace = NA_character_, .logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame() ).add_meta_variables( additional_fields = NULL, log_level = NULL, namespace = NA_character_, .logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame() )
additional_fields |
A named vector of type list with key-value pairs of
additional meta data which needs to be added in logging context on top of
|
log_level |
log level as per |
namespace |
string referring to the |
.logcall |
the logging call being evaluated (useful in formatters and layouts when you want to have access to the raw, unevaluated R expression) |
.topcall |
R expression from which the logging function was called (useful in formatters and layouts to extract the calling function's name or arguments) |
.topenv |
original frame of the |
Returns a vector of collected meta-data. It is used in defining the
log_layout function.
'Azure Log Analytics' HTTP REST API documentation for 'Python' is followed to create the 'R' version of it. 'Python' version of this function is described at https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api?tabs=python#sample-requests/
.build_signature( customer_id, shared_key, date, content_length, method, content_type, resource ).build_signature( customer_id, shared_key, date, content_length, method, content_type, resource )
customer_id |
|
shared_key |
|
date |
date-time of logging event |
content_length |
Content length of the body |
method |
Only one value is expected - |
content_type |
Only one value is expected - |
resource |
Only one value is expected - |
Returns part of the header of HTTP POST request to be sent to 'Azure Log Analytics' workspace
This is an extended function of layout_json function
from 'logger' package. Objective is to add additional component in the
logging layout in JSON format so that they can also be reported while
logging along with the components collected by
.add_meta_variables.
.layout_json_custom( log_fields = c("time", "level", "ns", "ans", "topenv", "fn", "node", "arch", "os_name", "os_release", "os_version", "pid", "user", "msg"), additional_fields = NULL, enforce_ascii_msg = TRUE, enforce_tz_utc = TRUE ).layout_json_custom( log_fields = c("time", "level", "ns", "ans", "topenv", "fn", "node", "arch", "os_name", "os_release", "os_version", "pid", "user", "msg"), additional_fields = NULL, enforce_ascii_msg = TRUE, enforce_tz_utc = TRUE )
log_fields |
Vector of components which are collected in
|
additional_fields |
A named vector of type list with key-value pairs of
additional meta data which needs to be added in logging context on top of
|
enforce_ascii_msg |
If |
enforce_tz_utc |
If |
Returns a generator function typically to be used by
log_layout function.
Build and send a request to the POST API of 'Azure Log Analytics'
.post_data(customer_id, shared_key, body, log_type).post_data(customer_id, shared_key, body, log_type)
customer_id |
|
shared_key |
|
body |
Content or message to be logged in JSON format |
log_type |
Log-Type as defined in 'Azure Log Analytics' document, for custom logging |
Returns the HTTP response object
Get the configuration value of a specific key which was set (or not set) using
set_log_config function. If nothing was set, then it reuses the
default value defined in the function signature of
set_log_config function.
get_log_config(key = NULL)get_log_config(key = NULL)
key |
Specify the key whose value needs to be extracted. |
Returns the respective configuration value of the given key.
If key is NULL, then all the configuration values will be
returned together as a list.
# Get configuration value without setting anything get_log_config("log_to_azure") # Set some configuration first and then get the respective values set_log_config(enforce_tz_utc = FALSE, log_to_azure = FALSE) get_log_config("enforce_tz_utc") get_log_config("log_to_azure") # Reset the values set_log_config() get_log_config("log_to_azure") # Extract list of all configurations get_log_config()# Get configuration value without setting anything get_log_config("log_to_azure") # Set some configuration first and then get the respective values set_log_config(enforce_tz_utc = FALSE, log_to_azure = FALSE) get_log_config("enforce_tz_utc") get_log_config("log_to_azure") # Reset the values set_log_config() get_log_config("log_to_azure") # Extract list of all configurations get_log_config()
Logger function defined which are created on top of
log_level and layout_json -
these are part of another package 'logger'. Additional
capabilities have been added to those functions which enables this function
to be able to send logs directly to the 'Azure Log Analytics' workspace, and
also have control to post log outputs into the console - as per user input.
Note that, logging threshold can be directly set (if needed) using
log_threshold function from 'logger' package.
logger_level( ..., log_fields = get_log_config("log_fields"), additional_fields = get_log_config("additional_fields"), enforce_ascii_msg = get_log_config("enforce_ascii_msg"), enforce_tz_utc = get_log_config("enforce_tz_utc"), log_to_azure = get_log_config("log_to_azure"), log_type = get_log_config("log_type"), log_customer_id = Sys.getenv(get_log_config("customer_id_env"), "abcd"), log_shared_key = Sys.getenv(get_log_config("shared_key_env"), "abcd") ) logger_info(...) logger_error(...) logger_warn(...) logger_debug(...) logger_fatal(...) logger_success(...) logger_trace(...)logger_level( ..., log_fields = get_log_config("log_fields"), additional_fields = get_log_config("additional_fields"), enforce_ascii_msg = get_log_config("enforce_ascii_msg"), enforce_tz_utc = get_log_config("enforce_tz_utc"), log_to_azure = get_log_config("log_to_azure"), log_type = get_log_config("log_type"), log_customer_id = Sys.getenv(get_log_config("customer_id_env"), "abcd"), log_shared_key = Sys.getenv(get_log_config("shared_key_env"), "abcd") ) logger_info(...) logger_error(...) logger_warn(...) logger_debug(...) logger_fatal(...) logger_success(...) logger_trace(...)
... |
Content(s) of this argument is directly passed on to
|
log_fields |
Character vector of field names to be included in the JSON.
These field names are automatically collected by
|
additional_fields |
A named vector of type list with key-value pairs of
additional meta data which needs to be added in logging context on top of
|
enforce_ascii_msg |
If |
enforce_tz_utc |
If |
log_to_azure |
If |
log_type |
Single element character vector is expected. Logs will be
posted to this event on 'Azure Log Analytics'. For details, check this:
https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api?tabs=python/
. Default value is |
log_customer_id |
Workspace ID of 'Azure Log Analytics' workspace. By
default it fetches from the environment variable named |
log_shared_key |
Shared key of 'Azure Log Analytics' workspace. By
default it fetches from the environment variable named |
Most of the arguments of this function have a default value which
is read from the output of get_log_config. The idea is
to run the set_log_config function once to define the
default arguments; and use them automatically while logging anything
without the need of specifying them every time it is triggered.
'Azure Log Analytics' workspace id and shared key are intentionally fetched from environment variables for security purpose. It is not a good practice to specify them explicitly. Using environment variable is one easy approach to potentially hide it from unintentional user.
It may take ~5–10 minutes to see the logging messages on the 'Azure Log Analytics' portal after the first time a message is posted to a new custom log table.
If log_to_azure is FALSE then log output is shown on
console. Else, if TRUE, then log output is shown on console, as
well as posted to 'Azure Log Analytics' workspace under the custom table
name as specified by log_type argument. If POST request is
unsuccessful, then additional warning message is thrown with POST request
response. If POST request is successful, then it invisibly returns the
POST object.
Logging layout is set in JSON format, required to send to 'Azure Log
Analytics'. Note that this layout modifies the global namespace of
'logger' package by default - that is not important for this use
case.
logger_info is a wrapper function around
logger_level - logging level is set as
INFO by default.
logger_error is a wrapper function around
logger_level - logging level is set as
ERROR by default.
logger_warn is a wrapper function around
logger_level - logging level is set as
WARN by default.
logger_debug is a wrapper function around
logger_level - logging level is set as
DEBUG by default.
logger_fatal is a wrapper function around
logger_level - logging level is set as
FATAL by default.
logger_success is a wrapper function around
logger_level - logging level is set as
SUCCESS by default.
logger_trace is a wrapper function around
logger_level - logging level is set as
TRACE by default.
# Define logging config and then use logger_* functions to log set_log_config(log_to_azure = FALSE) logger_level(logger::INFO, "logging message") # Specify other arguments explicitly inside the logger_level function logger_level(logger::INFO, "logging message", log_to_azure = FALSE) # For ease, use wrapper functions instead of using `logger_level` function as # below logger_info("logging message info", log_to_azure = FALSE) # Also, instead of writing `log_to_azure = FALSE` every time, set the # configuration in one step using `set_log_config`, and continue to use # wrapper functions as usual. set_log_config(log_to_azure = FALSE) logger_info("logging message info") # Wrapper function for log level 'error' logger_error("logging message error") # Wrapper function for log level 'warn' logger_warn("logging message warn") # Change log threshold to debug logger::log_threshold(logger::DEBUG) # Wrapper function for log level 'debug' logger_debug("logging message debug") # Wrapper function for log level 'fatal' logger_fatal("logging message fatal") # Wrapper function for log level 'success' logger_success("logging message success") # Change logging threshold logger::log_threshold(logger::TRACE) # Wrapper function for log level 'trace' logger_trace("logging message trace")# Define logging config and then use logger_* functions to log set_log_config(log_to_azure = FALSE) logger_level(logger::INFO, "logging message") # Specify other arguments explicitly inside the logger_level function logger_level(logger::INFO, "logging message", log_to_azure = FALSE) # For ease, use wrapper functions instead of using `logger_level` function as # below logger_info("logging message info", log_to_azure = FALSE) # Also, instead of writing `log_to_azure = FALSE` every time, set the # configuration in one step using `set_log_config`, and continue to use # wrapper functions as usual. set_log_config(log_to_azure = FALSE) logger_info("logging message info") # Wrapper function for log level 'error' logger_error("logging message error") # Wrapper function for log level 'warn' logger_warn("logging message warn") # Change log threshold to debug logger::log_threshold(logger::DEBUG) # Wrapper function for log level 'debug' logger_debug("logging message debug") # Wrapper function for log level 'fatal' logger_fatal("logging message fatal") # Wrapper function for log level 'success' logger_success("logging message success") # Change logging threshold logger::log_threshold(logger::TRACE) # Wrapper function for log level 'trace' logger_trace("logging message trace")
Set the logging configuration once by executing this function. There won't be
any need to set them every time while logging something via
logger_level or any wrapper of that, e.g.
logger_info function(s).
set_log_config( log_fields = c("level", "time", "msg"), additional_fields = NULL, enforce_ascii_msg = TRUE, enforce_tz_utc = TRUE, log_to_azure = TRUE, log_type = "log_from_r", customer_id_env = "AZ_LOG_ID", shared_key_env = "AZ_LOG_KEY" )set_log_config( log_fields = c("level", "time", "msg"), additional_fields = NULL, enforce_ascii_msg = TRUE, enforce_tz_utc = TRUE, log_to_azure = TRUE, log_type = "log_from_r", customer_id_env = "AZ_LOG_ID", shared_key_env = "AZ_LOG_KEY" )
log_fields |
Character vector of field names to be included in the JSON.
These field names are automatically collected by
|
additional_fields |
A named vector of type list with key-value pairs of
additional meta data which needs to be added in logging context on top of
|
enforce_ascii_msg |
If |
enforce_tz_utc |
If |
log_to_azure |
If |
log_type |
Single element character vector is expected. Logs will be
posted to this event on 'Azure Log Analytics'. For details, check this:
https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api?tabs=python/
. Default value is |
customer_id_env |
The name of the environment variable (default is
|
shared_key_env |
The name of the environment variable (default is
|
It saves the configuration in an environment enclosed within this package. Returns nothing explicitly.
set_log_config(log_fields = c("level", "time", "msg", "user", "pid")) set_log_config(enforce_tz_utc = FALSE, log_to_azure = FALSE)set_log_config(log_fields = c("level", "time", "msg", "user", "pid")) set_log_config(enforce_tz_utc = FALSE, log_to_azure = FALSE)