2010-11-04 19 views
8

Attualmente sto correndo in un tipo di problema.Posso disabilitare l'intestazione del registro per il logger rubino?

Come probabilmente sapete, il logger ruby ​​aggiunge un'intestazione di registrazione nella parte superiore di ogni file di registro appena creato.

"# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName] 

sto accedendo file CSV per importarli in un magazzino in seguito, di solito ho appena saltare la prima linea con l'intestazione. Sembra che ci sia un bug nel logger, perché a volte l'intestazione del log appare più di una volta, proprio nel mezzo di un file di log.

Quindi ho deciso di lasciare semplicemente l'intestazione. Con mia sorpresa, non ho trovato alcun argomento che si possa passare alla creazione di un logger. Ho pensato a qualcosa di simile:

Logger.new "info.log", :skip_header => true 

Ma non è solo lì. Ho cercato nelle fonti principali rubino e sorprendentemente non c'è davvero nulla che possa impedire il registratore di aggiungere l'intestazione di registro:

def create_logfile(filename) 
    logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT)) 
    logdev.sync = true 
    add_log_header(logdev) 
    logdev 
end 

def add_log_header(file) 
    file.write(
    "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName] 
) 
end 

Qualcuno ha un'idea che cosa potevo fare, per evitare che l'intestazione del registro? Sto usando Ruby 1.8.7 302 con Rails 2.3.5 qui. Semplicemente ignorando i commenti sul lato del magazzino non è possibile perché non ho il controllo del codice lì, e sembra essere rischioso ignorarlo semplicemente, se qualcosa va storto con una linea di registrazione.

Qualcuno conosce un registratore che consente questo? Pensi che sarebbe una buona idea usare e scrivere semplicemente in un file?

Grazie in anticipo, Tommy

risposta

7

Idealmente il metodo add_log_header nell'istanza Logger devono essere sovrascritti, ma dal momento che add_log_header è chiamata inizializzazione, sei troppo in ritardo con il tempo di mettere le mani su di esso. Bene, potresti semplicemente sovrascrivere il metodo add_log_header sulla Classe.

class Logger::LogDevice 
    def add_log_header(file) 
    end 
end 

log1 = Logger.new('info1.log') 

Ma se la vostra applicazione ha bisogno di più istanze di Logger dopo questo, si comporteranno allo stesso: nessuna intestazione. Per evitare ciò:

# dismantle the header and save it under another name 
class Logger::LogDevice 
    alias orig_add_log_header add_log_header 

    def add_log_header(file) 
    end 
end 

# Quick,create an instance 
log1 = Logger.new('test_log1file.log') 

# restore the old method: 
class Logger::LogDevice 
    alias add_log_header orig_add_log_header 
end 
+0

Ottimo, grazie! Non ho pensato di "rattoppare le scimmie" nel logger perché è considerato sporco. Ma con il tuo approccio non cambia nulla per le chiamate precedenti e successive. Grande! –

2

Ecco una soluzione che prevede la sottoclasse Logger. Dobbiamo essere furbi con initialize e super per impedirgli di creare uno standard Logger::LogDevice troppo presto.

class HeadlessLogger < Logger 
    def initialize(logdev, shift_age = 0, shift_size = 1048576) 
    super(nil) # this prevents it from initializing a LogDevice 
    if logdev 
     @logdev = HeadlessLogger::LogDevice.new(logdev, shift_age: shift_age, shift_size: shift_size) 
    end 
    end 

    class LogDevice < ::Logger::LogDevice 
    def add_log_header(file) ; end 
    end 
end 
2

In alternativa al patching classe logger, semplicemente non lasciare che creare il file di log toccandolo in anticipo:

FileUtils.touch logfile_path 
Logger.new logfile_path 

In pianura Rubino si avrà bisogno di require 'fileutils' da stdlib ovviamente.

Modifica: Questo non funzionerà se si utilizza la procedura di registrazione incorporata, o se il file viene eliminato, poiché non vi è alcun gancio su-ruota e quindi scriverà nuovamente l'intestazione.

Problemi correlati