Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
Neal Fultz committed Feb 24, 2015
0 parents commit 80c954e
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 0 deletions.
10 changes: 10 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Package: autolog
Type: Package
Title: Automatically add logging to functions
Version: 1.0
Date: 2015-02-24
Author: Neal Fultz <njf@zestfinance.com>
Maintainer: Neal Fultz <njf@zestfinance.com>
Description: This function automatically adds logging code to other functions.
License: GPL-3
Copyright: ZestFinance 2015
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Generated by roxygen2 (4.1.0): do not edit by hand

export(autolog)
77 changes: 77 additions & 0 deletions R/autolog.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#' Automatic Logging
#'
#' @name autolog-package
#' @docType package
NULL

# Class name for wrapped fns
.C = "autologger";

# Package variable, used for tabbing function calls over
.a <- new.env(parent = emptyenv());
.a$depth = 0;

#' Automatic Logging
#'
#' @param e an environment to process; default to Global
#' @param logger a logging function accepting \code{...}
#' @param verbose verbose output of what functions are being instrumented
#'
#' @export
#' @examples
#' f <- function(a,b) a / b
#' zzz <- function(x,y) f(x,y) / f(y,x)
#' autolog(environment(), verbose=TRUE)
#' zzz(2,1)

autolog <- function(e = .GlobalEnv, logger="message", verbose=getOption("autolog.verbose", FALSE)) {

logger <- match.fun(logger);

objNames <- ls(e);

for(i in objNames) {
x <- get(i, e);
if(!is.function(x)) next;
if(class(x) == .C) {
if(verbose) logger("skipping\t", i);
next
}
if(verbose)
logger("wrapping\t", i);
assign(i, wrap(x, logger), e);
}

e$.AUTOLOG <- TRUE;
}



wrap <- function(x, logger) {

# Bug 1: make sure x is forced, R is too lazy, it will infinitely recur on the final function in the loop above if one function calls another.
force(x);
force(logger);

#using `class<-` to keep local environment clean
`class<-`(
function(...) {
txt <- deparse(sys.call());

.a$depth <- .a$depth + 1;
logger(Sys.time(), rep("\t", .a$depth), txt, " enter" );

on.exit( {
logger(Sys.time(), rep("\t", .a$depth), txt, " exit");
.a$depth <- .a$depth - 1;
})

x(...);
},
.C
)
}

unwrap <- function(x) {
if(class(x) == .C) environment(x)$x else x
}
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Autologger: Pain Free Logging

This package provides the `autolog` function, which instruments all functions in an environment to let you follow along with the execution.

Here is an example:

autolg> f <- function(a,b) a / b

autolg> zzz <- function(x,y) f(x,y) / f(y,x)

autolg> autolog(environment(), verbose=TRUE)
wrapping f
wrapping zzz

autolg> zzz(2,1)
2015-02-24 18:55:10 zzz(2, 1) enter
2015-02-24 18:55:10 f(x, y) enter
2015-02-24 18:55:10 f(x, y) exit
2015-02-24 18:55:10 f(y, x) enter
2015-02-24 18:55:10 f(y, x) exit
2015-02-24 18:55:10 zzz(2, 1) exit
18 changes: 18 additions & 0 deletions autolog.Rproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Version: 1.0

RestoreWorkspace: Default
SaveWorkspace: Default
AlwaysSaveHistory: Default

EnableCodeIndexing: Yes
UseSpacesForTab: Yes
NumSpacesForTab: 2
Encoding: UTF-8

RnwWeave: Sweave
LaTeX: pdfLaTeX

BuildType: Package
PackageUseDevtools: Yes
PackageInstallArgs: --no-multiarch --with-keep.source
PackageRoxygenize: rd,namespace
10 changes: 10 additions & 0 deletions man/autolog-package.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
% Generated by roxygen2 (4.1.0): do not edit by hand
% Please edit documentation in R/autolog.R
\docType{package}
\name{autolog-package}
\alias{autolog-package}
\title{Automatic Logging}
\description{
Automatic Logging
}

26 changes: 26 additions & 0 deletions man/autolog.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
% Generated by roxygen2 (4.1.0): do not edit by hand
% Please edit documentation in R/autolog.R
\name{autolog}
\alias{autolog}
\title{Automatic Logging}
\usage{
autolog(e = .GlobalEnv, logger = "message",
verbose = getOption("autolog.verbose", FALSE))
}
\arguments{
\item{e}{an environment to process; default to Global}

\item{logger}{a logging function accepting \code{...}}

\item{verbose}{verbose output of what functions are being instrumented}
}
\description{
Automatic Logging
}
\examples{
f <- function(a,b) a / b
zzz <- function(x,y) f(x,y) / f(y,x)
autolog(environment(), verbose=TRUE)
zzz(2,1)
}

0 comments on commit 80c954e

Please sign in to comment.