Как вести журнал при использовании foreach (print или futile.logger)

Я хочу использовать пакет foreach в сочетании с ведением журнала. Обычно я использую пакет futile.logger. Когда работа передается работникам, информация о журнале теряется (что странно, поскольку вам нужно указать для каждого пакета ведения журнала)

Я видел этот пост но не использует foreach

  library(foreach)                                                                                                                                                                                                                                                                                                       
  library(futile.logger)                                                                                                                                                                                                                                                                                                 
  library(doParallel)                                                                                                                                                                                                                                                                                                    
  flog.threshold(DEBUG)                                                                                                                                                                                                                                                                                                  
  cluster <- makeCluster(8)
  registerDoParallel(cluster)
  doStuff <- function(input){                                                                                                                                                                                                                                                                                            
    flog.debug('Doing some stuff with %s', input)                                                                                                                                                                                                                                                                      
    return(input)                                                                                                                                                                                                                                                                                                      
  }                                                                                                                                                                                                                                                                                                                      
  res <- lapply(FUN=doStuff, X=seq(1,8,1))
  # >> this prints                                                                                                                                                                                                                                                                         
  res2 <- foreach(input = seq(1,8,1)) %do% doStuff(input)                                                                                                                                                                                                                                                                
  # >> this prints
  res3 <- foreach(input = seq(1,8,1), .packages='futile.logger') %dopar% doStuff(input)        
  # >> this does not                                                                                                                                                                                                                          
  identical(res,res2) && identical(res,res3)

Я не очень забочусь о бэкэнде parallele, может быть что угодно, но как я могу просто заставить работать ведение журнала


person statquant    schedule 08.08.2016    source источник


Ответы (1)


Следуя решению из Как я могу печатать при использовании %dopar%: идея состоит в том, чтобы использовать snow для настройки вашего кластера, и установите outfile="" для перенаправления рабочего вывода на мастер.

library(foreach)
library(futile.logger)
library(doParallel)

library(doSNOW)
cluster <- makeCluster(3, outfile="") # I only have 4 cores, but you could do 8
registerDoSNOW(cluster)
flog.threshold(DEBUG)

doStuff <- function(input){
  flog.info('Doing some stuff with %s', input) # change to flog.info
  return(input) 
  } 
res <- lapply(FUN=doStuff, X=seq(1,8,1))
# >> this prints                                                              
res2 <- foreach(input = seq(1,8,1)) %do% doStuff(input) 
# >> this prints
res3 <- foreach(input = seq(1,8,1), .packages='futile.logger') %dopar% doStuff(input)  
# >> this prints too

Выход:

> res3 <- foreach(input = seq(1,8,1), .packages='futile.logger') %dopar% doStuff(input)  
Type: EXEC 
Type: EXEC 
Type: EXEC 
Type: EXEC 
Type: EXEC 
Type: EXEC 
INFO [2016-08-08 08:22:39] Doing some stuff with 3
Type: EXEC 
INFO [2016-08-08 08:22:39] Doing some stuff with 1
INFO [2016-08-08 08:22:39] Doing some stuff with 2
Type: EXEC 
Type: EXEC 
INFO [2016-08-08 08:22:39] Doing some stuff with 5
INFO [2016-08-08 08:22:39] Doing some stuff with 4
Type: EXEC 
Type: EXEC 
INFO [2016-08-08 08:22:39] Doing some stuff with 6
INFO [2016-08-08 08:22:39] Doing some stuff with 7
INFO [2016-08-08 08:22:39] Doing some stuff with 8

Вывод в файл журнала. Вот альтернатива, которая выводит в файл журнала, после в параллельном методе в R?. Его преимущество в том, что он имеет более чистый вывод, но все же требует flog.info:

library(doSNOW)
library(foreach)
library(futile.logger)
nworkers <- 3
cluster <- makeCluster(nworkers)
registerDoSNOW(cluster)
loginit <- function(logfile) flog.appender(appender.file(logfile))
foreach(input=rep('~/Desktop/out.log', nworkers), 
  .packages='futile.logger') %dopar% loginit(input)
doStuff <- function(input){
  flog.info('Doing some stuff with %s', input)
  return(input) 
  } 
foreach(input = seq(1,8,1), .packages='futile.logger') %dopar% doStuff(input) 
stopCluster(cluster)
readLines("~/Desktop/out.log")

Выход:

> readLines("~/Desktop/out.log")
[1] "INFO [2016-08-08 10:07:30] Doing some stuff with 2"
[2] "INFO [2016-08-08 10:07:30] Doing some stuff with 1"
[3] "INFO [2016-08-08 10:07:30] Doing some stuff with 3"
[4] "INFO [2016-08-08 10:07:30] Doing some stuff with 4"
[5] "INFO [2016-08-08 10:07:30] Doing some stuff with 5"
[6] "INFO [2016-08-08 10:07:30] Doing some stuff with 6"
[7] "INFO [2016-08-08 10:07:30] Doing some stuff with 7"
[8] "INFO [2016-08-08 10:07:30] Doing some stuff with 8"
person Weihuang Wong    schedule 08.08.2016
comment
Дело во втором методе в том, что вы НЕ входите в консоль... Вы? - person statquant; 08.08.2016
comment
Весь смысл использования parallel заключается в том, чтобы абстрагироваться от snow и multicore... - person Gerhard Burger; 14.12.2016
comment
Кажется, сейчас это не работает. Работает на Ubuntu с R 3.4.2. Я вообще не вывожу журнал на консоль. - person Dave Kincaid; 22.03.2018