From 6fa388de1c611a687ef7b762e50801f92e09f59d Mon Sep 17 00:00:00 2001 From: urso Date: Fri, 15 Jul 2016 16:35:55 +0200 Subject: [PATCH] Backport: Check stdout being available in console output --- CHANGELOG.asciidoc | 1 + libbeat/outputs/console/console.go | 43 +++++++++++++++---------- libbeat/outputs/console/console_test.go | 11 ++++--- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 8e446aadf70..872dc98de1b 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -73,6 +73,7 @@ https://github.com/elastic/beats/compare/v1.2.3...v1.3.0[View commits] - Fix output modes backoff counter reset. {issue}1803[1803] {pull}1814[1814] {pull}1818[1818] - Set logstash output default bulk_max_size to 2048. {issue}1662[1662] - Seed random number generator using crypto.rand package. {pull}1503[1503] +- Check stdout being available when console output is configured. {issue}2063[2063] *Packetbeat* diff --git a/libbeat/outputs/console/console.go b/libbeat/outputs/console/console.go index f1f23080ed9..330d254974f 100644 --- a/libbeat/outputs/console/console.go +++ b/libbeat/outputs/console/console.go @@ -2,6 +2,7 @@ package console import ( "encoding/json" + "fmt" "os" "github.com/elastic/beats/libbeat/common" @@ -20,28 +21,23 @@ func (p plugin) NewOutput( topologyExpire int, ) (outputs.Outputer, error) { pretty := config.Pretty != nil && *config.Pretty - return newConsole(pretty), nil + c := newConsole(pretty) + + // check stdout actually being available + if _, err := c.out.Stat(); err != nil { + return nil, fmt.Errorf("console output initialization failed with: %v", err) + } + + return c, nil } type console struct { pretty bool + out *os.File } func newConsole(pretty bool) *console { - return &console{pretty} -} - -func writeBuffer(buf []byte) error { - written := 0 - for written < len(buf) { - n, err := os.Stdout.Write(buf[written:]) - if err != nil { - return err - } - - written += n - } - return nil + return &console{pretty: pretty, out: os.Stdout} } func (c *console) PublishEvent( @@ -63,10 +59,10 @@ func (c *console) PublishEvent( return err } - if err = writeBuffer(jsonEvent); err != nil { + if err = c.writeBuffer(jsonEvent); err != nil { goto fail } - if err = writeBuffer([]byte{'\n'}); err != nil { + if err = c.writeBuffer([]byte{'\n'}); err != nil { goto fail } @@ -79,3 +75,16 @@ fail: outputs.SignalFailed(s, err) return err } + +func (c *console) writeBuffer(buf []byte) error { + written := 0 + for written < len(buf) { + n, err := c.out.Write(buf[written:]) + if err != nil { + return err + } + + written += n + } + return nil +} diff --git a/libbeat/outputs/console/console_test.go b/libbeat/outputs/console/console_test.go index e029f6ba70d..d854b2f4040 100644 --- a/libbeat/outputs/console/console_test.go +++ b/libbeat/outputs/console/console_test.go @@ -44,8 +44,9 @@ func event(k, v string) common.MapStr { return common.MapStr{k: v} } -func run(c *console, events ...common.MapStr) (string, error) { +func run(pretty bool, events ...common.MapStr) (string, error) { return withStdout(func() { + c := newConsole(pretty) for _, event := range events { c.PublishEvent(nil, outputs.Options{}, event) } @@ -53,21 +54,21 @@ func run(c *console, events ...common.MapStr) (string, error) { } func TestConsoleOneEvent(t *testing.T) { - lines, err := run(newConsole(false), event("event", "myevent")) + lines, err := run(false, event("event", "myevent")) assert.Nil(t, err) expected := "{\"event\":\"myevent\"}\n" assert.Equal(t, expected, lines) } func TestConsoleOneEventIndented(t *testing.T) { - lines, err := run(newConsole(true), event("event", "myevent")) + lines, err := run(true, event("event", "myevent")) assert.Nil(t, err) expected := "{\n \"event\": \"myevent\"\n}\n" assert.Equal(t, expected, lines) } func TestConsoleMultipleEvents(t *testing.T) { - lines, err := run(newConsole(false), + lines, err := run(false, event("event", "event1"), event("event", "event2"), event("event", "event3"), @@ -79,7 +80,7 @@ func TestConsoleMultipleEvents(t *testing.T) { } func TestConsoleMultipleEventsIndented(t *testing.T) { - lines, err := run(newConsole(true), + lines, err := run(true, event("event", "event1"), event("event", "event2"), event("event", "event3"),