// Run runs the FileReadFilter filter, which inspects each message, and appends // the content of the file named as the executed template to the existing payload. // The resulting message will be injected back, and have newType type. func (fr FileReadFilter) Run(r pipeline.FilterRunner, h pipeline.PluginHelper) (err error) { if fr.tmpl == nil { return errors.New("FileReadFilter: empty template") } var ( fh *os.File inp io.Reader npack, opack *pipeline.PipelinePack ) out := bytes.NewBuffer(make([]byte, 0, 4096)) log.Printf("FileReadFilter: Starting with template %s", fr.tmpl) for opack = range r.InChan() { //log.Printf("opack=%v", opack) //if opack.Decoded { out.Reset() if err = fr.tmpl.Execute(out, extendedMessage{opack.Message}); err != nil { opack.Recycle() return fmt.Errorf("FileReadFilter: error executing template %v with message %v: %v", fr.tmpl, opack.Message, err) } //log.Printf("out=%q", out) if fh, err = os.Open(out.String()); err != nil { log.Printf("FileReadFilter: cannot read %q: %v", out, err) opack.Recycle() continue } out.Reset() //if _, err = io.Copy(out, io.LimitedReader{R: fh, N: 65000}); err != nil && err != io.EOF { inp = fh if fr.decoder != nil { inp = transform.NewReader(fh, fr.decoder) } if _, err = io.Copy(out, inp); err != nil && err != io.EOF { log.Printf("FileReadFilter: error reading %q: %v", fh.Name(), err) opack.Recycle() fh.Close() continue } fh.Close() npack = h.PipelinePack(opack.MsgLoopCount) if npack == nil { opack.Recycle() return errors.New("FileReadFilter: no output pack - infinite loop?") } npack.Decoded = true npack.Message = message.CopyMessage(opack.Message) npack.Message.SetType(fr.newType) npack.Message.SetPayload(npack.Message.GetPayload() + "\n" + out.String()) if !r.Inject(npack) { log.Printf("FileReadFilter: cannot inject new pack %v", npack) } //} opack.Recycle() } return nil }
func (s *SandboxEncoder) Encode(pack *pipeline.PipelinePack) (output []byte, err error) { if s.sb == nil { err = errors.New("No sandbox.") return } atomic.AddInt64(&s.processMessageCount, 1) s.injected = false var startTime time.Time if s.sample { startTime = time.Now() } cowpack := new(pipeline.PipelinePack) cowpack.Message = pack.Message // the actual copy will happen if write_message is called cowpack.MsgBytes = pack.MsgBytes // no copying is necessary since we don't change it retval := s.sb.ProcessMessage(cowpack) if retval == 0 && !s.injected { // `inject_message` was never called, protobuf encode the copy on write // message. if s.output, err = s.cEncoder.EncodeMessage(cowpack.Message); err != nil { return } } if s.sample { duration := time.Since(startTime).Nanoseconds() s.reportLock.Lock() s.processMessageDuration += duration s.processMessageSamples++ s.reportLock.Unlock() } s.sample = 0 == rand.Intn(s.sampleDenominator) if retval > 0 { err = fmt.Errorf("FATAL: %s", s.sb.LastError()) return } if retval == -2 { // Encoder has nothing to return. return nil, nil } if retval < 0 { atomic.AddInt64(&s.processMessageFailures, 1) err = fmt.Errorf("Failed serializing: %s", s.sb.LastError()) return } return s.output, nil }