func (s *S) TestReconnect(c *C) {
	l, err := net.Listen("tcp", ":0")
	c.Assert(err, IsNil)
	err = l.Close()
	c.Assert(err, IsNil)

	msgc := make(chan *rfc5424.Message)
	handler := func(msg *rfc5424.Message) {
		msgc <- msg
	}

	addr := l.Addr().String()
	_, err = s.discd.AddServiceAndRegister("test-reconnect", addr)
	c.Assert(err, IsNil)

	donec := make(chan struct{})
	defer close(donec)

	sc, err := connect(s.discd, "test-reconnect", donec)
	c.Assert(err, IsNil)

	l, err = net.Listen("tcp", addr)
	c.Assert(err, IsNil)
	go runServer(l, handler)

	want := rfc5424.NewMessage(&rfc5424.Header{Version: 1}, []byte("test message"))
	_, err = sc.Write(rfc6587.Bytes(want))
	c.Assert(err, IsNil)

	c.Assert(<-msgc, DeepEquals, want)
}
Exemple #2
0
func (s *S) TestAddSort(c *C) {
	b := NewBuffer()

	// add first message
	first := rfc5424.NewMessage(nil, []byte("msg1"))
	b.Add(first)
	c.Assert(b.Read(), DeepEquals, []*rfc5424.Message{first})

	// add duplicate
	b.Add(first)
	c.Assert(b.Read(), DeepEquals, []*rfc5424.Message{first})

	// add new, before head
	newHead := rfc5424.NewMessage(nil, []byte("msg2"))
	newHead.Timestamp = first.Timestamp.Add(-time.Second)
	b.Add(newHead)
	c.Assert(b.Read(), DeepEquals, []*rfc5424.Message{newHead, first})

	// add new, tail
	newTail := rfc5424.NewMessage(nil, []byte("msg3"))
	newTail.Timestamp = first.Timestamp.Add(2 * time.Second)
	b.Add(newTail)
	c.Assert(b.Read(), DeepEquals, []*rfc5424.Message{newHead, first, newTail})

	// add new between first and newTail
	between := rfc5424.NewMessage(nil, []byte("msg3"))
	between.Timestamp = first.Timestamp.Add(time.Second)
	b.Add(between)
	c.Assert(b.Read(), DeepEquals, []*rfc5424.Message{newHead, first, between, newTail})
}
Exemple #3
0
func (_ *SnapshotTestSuite) TestRoundtrip(c *C) {
	want := []*rfc5424.Message{}
	got := []*rfc5424.Message{}

	for i := 0; i < 100; i++ {
		key := fmt.Sprintf("app-%d", i)
		hdr := rfc5424.Header{AppName: []byte(key)}

		for j := 0; j < 100; j++ {
			line := []byte(fmt.Sprintf("line %d\n", j))
			want = append(want, rfc5424.NewMessage(&hdr, line))
		}
	}

	r, w := io.Pipe()
	errc := make(chan error)
	go func() {
		err := WriteTo([][]*rfc5424.Message{want}, w)
		w.Close()
		errc <- err

	}()

	s := NewScanner(r)
	for s.Scan() {
		got = append(got, s.Message)
	}
	c.Assert(s.Err(), IsNil)

	c.Assert(<-errc, IsNil)
	c.Assert(want, DeepEquals, got)
}
Exemple #4
0
func (s *S) SetUpTest(c *C) {
	hdr := &rfc5424.Header{}

	s.data = make([]*rfc5424.Message, DefaultCapacity*2)
	for i := 0; i < len(s.data); i++ {
		line := []byte(fmt.Sprintf("line %d\n", i))
		s.data[i] = rfc5424.NewMessage(hdr, line)
	}
}
Exemple #5
0
func newMessageForApp(appname, procID, msg string) *rfc5424.Message {
	return rfc5424.NewMessage(
		&rfc5424.Header{
			AppName: []byte(appname),
			ProcID:  []byte(procID),
		},
		[]byte(msg),
	)
}
Exemple #6
0
func newMessageForApp(appname, procID, msg string) *rfc5424.Message {
	m := rfc5424.NewMessage(
		&rfc5424.Header{
			AppName: []byte(appname),
			ProcID:  []byte(procID),
		},
		[]byte(msg),
	)
	m.StructuredData = []byte(`[flynn seq="1"]`)
	return m
}
Exemple #7
0
func newSeqMessage(hostname string, seq, timeDiff int) *rfc5424.Message {
	m := rfc5424.NewMessage(
		&rfc5424.Header{
			AppName:   []byte("foo"),
			ProcID:    []byte("bar"),
			Timestamp: time.Date(2013, 7, 17, 16, 43, 41, 0, time.UTC).Add(time.Duration(timeDiff) * time.Second),
			Hostname:  []byte(hostname),
		},
		[]byte("asdf"),
	)
	m.StructuredData = []byte(fmt.Sprintf(`[flynn seq="%d"]`, seq))
	return m
}
Exemple #8
0
func buildTestData(n int, hdr *rfc5424.Header) []*rfc5424.Message {
	data := make([]*rfc5424.Message, n)
	for i := range data {
		line := []byte(fmt.Sprintf("line %d\n", i))
		msg := rfc5424.NewMessage(hdr, line)
		msg.StructuredData = []byte(fmt.Sprintf(`[flynn seq="%d"]`, i))
		msg.Timestamp = timeNow

		data[i] = msg
	}

	return data
}
Exemple #9
0
func (s *LogStream) follow(r io.Reader, buffer, appID string, h *rfc5424.Header, wg *sync.WaitGroup) {
	defer wg.Done()
	defer close(s.done)
	l := s.m.appLog(appID)
	seqBuf := make([]byte, 10)
	sd := &rfc5424.StructuredData{
		ID:     []byte("flynn"),
		Params: []rfc5424.StructuredDataParam{{Name: []byte("seq")}},
	}

	br := bufio.NewReaderSize(io.MultiReader(strings.NewReader(buffer), r), 10000)
	for {
		line, err := br.ReadSlice('\n')
		if err != nil && err != bufio.ErrBufferFull {
			// if the log was explicitly closed (because an update
			// is in progress), store the buffer and return so it
			// can be passed to the new flynn-host daemon.
			if s.closed.Load().(bool) {
				s.buf = string(line)
				return
			}
			if len(line) == 0 {
				// only return if there is no final line to return
				return
			}
		}
		if line[len(line)-1] == '\n' {
			line = line[:len(line)-1]
		}

		msg := rfc5424.NewMessage(h, line)
		cursor := &utils.HostCursor{
			Time: msg.Timestamp,
			Seq:  uint64(atomic.AddUint32(&s.m.msgSeq, 1)),
		}
		sd.Params[0].Value = strconv.AppendUint(seqBuf[:0], cursor.Seq, 10)
		var sdBuf bytes.Buffer
		sd.Encode(&sdBuf)
		msg.StructuredData = sdBuf.Bytes()
		l.Write(message{cursor, msg})

		if err != nil && err != bufio.ErrBufferFull {
			return
		}
	}
}
Exemple #10
0
func (s *LogAggregatorTestSuite) TestNewMessageFromSyslog(c *C) {
	timestamp, err := time.Parse(time.RFC3339Nano, "2009-11-10T23:00:00.123450789Z")
	c.Assert(err, IsNil)
	m := NewMessageFromSyslog(rfc5424.NewMessage(
		&rfc5424.Header{
			Hostname:  []byte("a.b.flynn.local"),
			ProcID:    []byte("web.flynn-abcd1234"),
			MsgID:     []byte("ID1"),
			Timestamp: timestamp,
		},
		[]byte("testing message"),
	))

	c.Assert(m.HostID, Equals, "a.b.flynn.local")
	c.Assert(m.JobID, Equals, "flynn-abcd1234")
	c.Assert(m.ProcessType, Equals, "web")
	c.Assert(m.Source, Equals, "app")
	c.Assert(m.Stream, Equals, "stdout")
	c.Assert(m.Timestamp, Equals, timestamp)
}
Exemple #11
0
func (m *LogMux) follow(r io.Reader, hdr *rfc5424.Header) {
	defer m.producerwg.Done()

	g := grohl.NewContext(grohl.Data{"at": "logmux_follow"})
	s := bufio.NewScanner(r)

	for s.Scan() {
		msg := rfc5424.NewMessage(hdr, s.Bytes())

		select {
		case m.logc <- msg:
		default:
			// throw away msg if logc buffer is full
		}
	}

	if s.Err() != nil {
		g.Log(grohl.Data{"status": "error", "err": s.Err()})
	}
}
func (s *S) TestDurableWrite(c *C) {
	l, err := net.Listen("tcp", ":0")
	c.Assert(err, IsNil)

	msgc := make(chan *rfc5424.Message)
	handler := func(msg *rfc5424.Message) {
		msgc <- msg
	}

	go runServer(l, handler)

	donec := make(chan struct{})
	defer close(donec)

	sc, err := connect(s.discd, "test-broken", donec)
	c.Assert(err, IsNil)

	addr := l.Addr().String()
	_, err = s.discd.AddServiceAndRegister("test-broken", addr)
	c.Assert(err, IsNil)

	hdr := &rfc5424.Header{}
	for i := 0; i < 10; i++ {
		want := rfc5424.NewMessage(hdr, []byte(fmt.Sprintf("line %d", i+1)))

		_, err = sc.Write(rfc6587.Bytes(want))
		c.Assert(err, IsNil)

		if i%2 == 0 {
			// break the underlying connection before the next Write
			c.Assert(sc.Conn.Close(), IsNil)
		}

		got := <-msgc
		c.Assert(want, DeepEquals, got)
	}
}