#!/usr/bin/env ruby ################# reprocesslog -- brent@mbari.org #################### # Copyright (C) 2014 MBARI # MBARI Proprietary Information. All rights reserved. # # Reprocess the log file # first argument is source file name (defaults to stdin) # 2nd argument is destination file name (defaults to stdout) # ######################################################################## require 'getoptlong' require 'framework' opts = GetoptLong.new( ["--init", "-i", GetoptLong::REQUIRED_ARGUMENT], ["--prefix", "-p", GetoptLong::REQUIRED_ARGUMENT], ["--ttyOK", "-t", GetoptLong::NO_ARGUMENT], ["--help", "-h", GetoptLong::NO_ARGUMENT] ) progName = File.basename $0 logFn = ESP.logFn initString = prefix = "" ttyOK = false opts.each do |opt, arg| case opt when "--init" initString=arg when "--prefix" prefix=arg when "--ttyOK" ttyOK = true else STDERR.puts "\ Copy ESP log file while reprocessing CTD and Can data -- 11/7/14 brent@mbari.org Options: --help #displays this text --init='expression' #(optional, quoted) ruby initialization code --prefix=string #retain original sensor data records prefixed with string --ttyOK #allow output of binary log to terminal (tty device) First argument is the name of the source log file to read This defaults to #{logFn} (or stdin, if not a tty) if omitted. Second argument is the name of the (new) log file to write This defaults to stdout if omitted. Examples: #{progName} /var/log/esp/real.log newReal.log curl -s ftp://espmoe/esp/real.log | #{progName} > newReal.log Note: if you see Log::Reader parse errors, check the ESPpath environment variable " exit end end begin logFile = (ARGV[0] || $stdin.tty?) ? File.new(ARGV[0]||logFn) : $stdin logOutFile = ARGV[1] ? open(ARGV[1], "w") : $stdout raise ArgumentError.new "Refusing to output binary log to terminal" if not ttyOK and logOutFile.tty? rescue STDERR.puts "Invalid or Missing log file names. Try: #{progName} --help" raise end require 'logproc' #requisite object definitions for reading log require 'log' #log writer log = Log.new logOutFile, :noMarks (sch = Schedule.new Time.at(0), log). thread.name=("MAIN_scheduler").intern class Schedule def setTime! time @time = time end end class Symbol #so Symbols rather than Threads or Microcontrollers can be message sources def name self end end CTDlatitude = /\ACTD\.latitude\s*=\s*(.*)\s*Degrees/ FirstSensor = /\ACan@/ LastSensor = /\ACTD@/ CTDstatus = /\A\s?SBE .*SERIAL NO\. /m #instanciate contextual sensors sensors=Instrument::Sensors sensors << Can.new sensors << :CTD.denotes(Instrument::CTD.new nil) Thread :MAIN do begin MainThread = Thread.current sch.setTime! Time.now log.debug "Reprocessed all Can and CTD contextual data" eval initString #after the sensors are set up reader = Log::Reader.new(logFile, Targets) ctdCals=:needStatus reader.each do |entry| if entry sch.setTime! reader.time case entry #must check subclasses their superclasses when Log::Msg log.recordMsg src=entry.source, msg=entry.rawMsg sensors[0] = Can.parse msg, sch.time if src==:Can when Log::Method log.recordMethod! entry, entry.source when Log::Object log.recordObject obj=entry.object, src=entry.source if src == :pollContext case obj when Instrument::CTDRawSample ctdCals=CTD.readCals if ctdCals==:readStatus CTD.rawSample= obj.data end end when Log::Data log.recordData entry, entry.source when Log::Debug log.recordDebug entry, entry.source when Log::Comment if (src=entry.source) == :pollContext case entry when FirstSensor log.comment "#{prefix}#{entry}", src unless prefix.empty? contxt = entry.split "\n" contxt.each do |line| case line when FirstSensor line.replace sensors.first.asIRBtext when LastSensor line.replace sensors.last.asIRBtext end end entry = contxt.join "\n" when CTDstatus CTD.lastStatus=entry ctdCals=:readStatus end elsif case entry when CTDlatitude CTD.latitude=eval($1) next end end log.comment entry, src when Log::Moniker if entry.symbol log.denote entry.symbol => entry.abbreviation else log.monikers= Hash.new end when Time #begin or end of log file section log.mark entry log.clearMonikers CTD.clearCals ctdCals=:needStatus else unknown = entry.logEntry STDERR.puts unknown log.comment unknown end end end rescue Exception puts $!, $!.backtrace end end.finish