Beispiel #1
0
// Dedup adds a canned filter to the handler which suppresses duplicate
// messages.
//
// When an event is received that contains the same message & fields as a
// previous message, the message is not sent on to the next handler. Once a
// different message is received, the filter generates a summary message
// indicating how many duplicates were suppressed.
//
// The return value is the handler itself. This is to allow chaining multiple operations together.
func (filterHandler *FilterHandler) Dedup() *FilterHandler {
	var lastLogEvent *event.Event
	var dups int
	filterFunc := func(logEvent *event.Event) bool {
		if lastLogEvent == nil {
			lastLogEvent = logEvent
			return true
		}

		if lastLogEvent.Message == logEvent.Message && reflect.DeepEqual(lastLogEvent.FlatFields, logEvent.FlatFields) {
			dups++
			lastLogEvent = logEvent
			return false
		}

		if dups > 0 {
			dupEvent := event.New(
				lastLogEvent.Id,
				event.Notice,
				"duplicates of last log event suppressed",
				map[string]int{"count": dups},
				false,
			)
			filterHandler.nextHandler.Event(dupEvent)
		}

		dups = 0
		lastLogEvent = logEvent
		return true
	}

	return filterHandler.Filter(filterFunc)
}
Beispiel #2
0
func TestAirbrakeHandler(t *testing.T) {
	ah := New(123456, "0123456789abcdef0123456789abcdef", "testing")

	ah.Context.URL = "http://example.com/airbrake"
	ah.Context.UserId = "johndoe"
	ah.Context.UserName = "******"
	ah.Context.UserEmail = "*****@*****.**"

	logEvent := event.New(1, event.Warning, "test AirbrakeHandler", map[string]interface{}{"foo": "bar"}, true)
	err := ah.Event(logEvent)
	require.NoError(t, err)

	notice := testAirbrakeServer.notices[len(testAirbrakeServer.notices)-1]

	nNotifier := notice["notifier"].(map[string]interface{})
	assert.Equal(t, notifier.Name, nNotifier["name"])
	assert.Equal(t, notifier.Version, nNotifier["version"])
	assert.Equal(t, notifier.Url, nNotifier["url"])

	_, selfFile, _, _ := runtime.Caller(0)
	nErrors := notice["errors"].([]interface{})
	nError := nErrors[0].(map[string]interface{})
	nBacktrace := nError["backtrace"].([]interface{})
	nBacktrace0 := nBacktrace[0].(map[string]interface{})
	assert.Equal(t, "warning", nError["type"])
	assert.Equal(t, "test AirbrakeHandler", nError["message"])
	assert.Equal(t, selfFile, nBacktrace0["file"])
	assert.NotEmpty(t, nBacktrace0["line"])
	assert.Equal(t, "TestAirbrakeHandler", nBacktrace0["function"])

	var repoVersion string
	execCmd := exec.Command("git", "describe", "--dirty", "--tags", "--always")
	output, err := execCmd.Output()
	if err == nil {
		repoVersion = string(bytes.TrimRight(output, "\n"))
	}
	nContext := notice["context"].(map[string]interface{})
	assert.Equal(t, runtime.GOOS+" "+runtime.GOARCH, nContext["os"])
	assert.Equal(t, "go "+runtime.Version(), nContext["language"])
	assert.Equal(t, "testing", nContext["environment"])
	assert.Equal(t, repoVersion, nContext["version"])
	assert.Equal(t, "http://example.com/airbrake", nContext["url"])
	assert.Equal(t, "johndoe", nContext["userId"])
	assert.Equal(t, "john doe", nContext["userName"])
	assert.Equal(t, "*****@*****.**", nContext["userEmail"])

	hostname, _ := os.Hostname()
	nEnvironment := notice["environment"].(map[string]interface{})
	assert.Equal(t, fmt.Sprintf("%d", runtime.GOMAXPROCS(0)), nEnvironment["GOMAXPROCS"])
	assert.Equal(t, runtime.Version(), nEnvironment["GOVERSION"])
	assert.Equal(t, runtime.GOROOT(), nEnvironment["GOROOT"])
	assert.Equal(t, hostname, nEnvironment["HOSTNAME"])

	nParams := notice["params"].(map[string]interface{})
	assert.Equal(t, "bar", nParams["foo"])
}
Beispiel #3
0
func TestAppend(t *testing.T) {
	td, err := ioutil.TempDir("", "")
	require.NoError(t, err)
	defer os.RemoveAll(td)

	fp := filepath.Join(td, "TestAppend")
	wh, err := Append(fp, 0600, "")
	require.NoError(t, err)

	f, err := os.Open(fp)
	require.NoError(t, err)

	stat, err := f.Stat()
	require.NoError(t, err)
	assert.Equal(t, os.FileMode(0600), stat.Mode())

	e := event.New(0, event.Info, "TestAppend message 1", nil, false)
	err = wh.Event(e)
	require.NoError(t, err)

	buf := make([]byte, 128)
	_, err = f.Read(buf)
	assert.NoError(t, err)
	assert.Contains(t, string(buf), "TestAppend message 1")

	// create a new appender and make sure it appends

	wh, err = Append(fp, 0600, "")
	require.NoError(t, err)

	_, err = f.Seek(0, 0)
	require.NoError(t, err)

	e = event.New(0, event.Info, "TestAppend message 2", nil, false)
	err = wh.Event(e)
	require.NoError(t, err)

	_, err = f.Read(buf)
	assert.NoError(t, err)
	assert.Contains(t, string(buf), "TestAppend message 1")
	assert.Contains(t, string(buf), "TestAppend message 2")
}
Beispiel #4
0
func makeEvent(level event.Level) *event.Event {
	eventCounter++

	callerPC, _, _, _ := runtime.Caller(1)
	callerFunc := runtime.FuncForPC(callerPC)
	callerName := callerFunc.Name()

	message := "testing " + callerName + "()"
	data := map[string]interface{}{"test": callerName}

	return event.New(eventCounter, level, message, data, false)
}
Beispiel #5
0
func TestSentryHandler(t *testing.T) {
	st := &sentryTransport{
		user:      "******",
		pass:      "******",
		projectID: "12345",
	}

	dsn := fmt.Sprintf("http://%s:%s@%s/%s", "0123456789abcdef0123456789abcdef", "fedcba9876543210fedcba9876543210", "localhost:2", "12345")
	handler, err := New(dsn)
	handler.Tag("abcd", "1234")
	require.NoError(t, err)
	handler.client.Transport = st

	logEvent := event.New(1, event.Warning, "test SentryHandler", map[string]interface{}{"error": errors.New("foo"), "foo": "bar", "breakfast": map[string]interface{}{"pop": "tart"}}, true)
	err = handler.Event(logEvent)
	require.NoError(t, err)

	packet := st.packets[len(st.packets)-1]
	assert.Equal(t, "test SentryHandler: foo", packet.Message)
	assert.Equal(t, handler.idPrefix+"1", packet.EventID)
	assert.WithinDuration(t, time.Now(), time.Time(packet.Timestamp), time.Second)
	assert.Equal(t, raven.WARNING, packet.Level)
	assert.Equal(t, "sentry.TestSentryHandler", packet.Culprit)
	assert.Equal(t, "sawmill", packet.Logger)
	assert.Equal(t, "go", packet.Platform)
	assert.NotEmpty(t, packet.Release)
	assert.Equal(t, "bar", packet.Extra["foo"])
	assert.Equal(t, "tart", packet.Extra["breakfast.pop"])
	assert.Contains(t, packet.Tags, raven.Tag{Key: "abcd", Value: "1234"})

	haveStacktrace := false
	for _, iface := range packet.Interfaces {
		switch iface := iface.(type) {
		case *raven.Stacktrace:
			haveStacktrace = true
			frame := iface.Frames[len(iface.Frames)-1]
			assert.Equal(t, "handler/sentry/sentry_test.go", frame.Filename)
			assert.Equal(t, "TestSentryHandler", frame.Function)
			assert.Equal(t, "sentry", frame.Module)
			assert.NotEmpty(t, frame.Lineno)
			assert.Equal(t, uint8('/'), frame.AbsolutePath[0])
			assert.Contains(t, frame.AbsolutePath, "/handler/sentry/sentry_test.go")
			assert.Equal(t, true, frame.InApp)
			assert.Equal(t, "	handler.client.Transport = st", frame.PreContext[1])
			assert.Equal(t, `	logEvent := event.New(1, event.Warning, "test SentryHandler", map[string]interface{}{"error": errors.New("foo"), "foo": "bar", "breakfast": map[string]interface{}{"pop": "tart"}}, true)`, frame.ContextLine)
		}
	}
	assert.True(t, haveStacktrace)

	handler.Stop()
}
func TestStandardStreamsHandler_Event(t *testing.T) {
	wg := sync.WaitGroup{}

	pipeOutR, pipeOutW, err := os.Pipe()
	defer pipeOutW.Close()
	require.NoError(t, err)
	defer func(f *os.File) { os.Stdout = f }(os.Stdout)
	os.Stdout = pipeOutW
	outbuf := bytes.NewBuffer(nil)
	wg.Add(1)
	go func() { io.Copy(outbuf, pipeOutR); wg.Done() }()

	pipeErrR, pipeErrW, err := os.Pipe()
	defer pipeErrW.Close()
	require.NoError(t, err)
	defer func(f *os.File) { os.Stderr = f }(os.Stderr)
	os.Stderr = pipeErrW
	errbuf := bytes.NewBuffer(nil)
	wg.Add(1)
	go func() { io.Copy(errbuf, pipeErrR); wg.Done() }()

	h := NewStandardStreamsHandler()
	e := event.New(0, event.Info, "TestStandardStreamsHandler_Event info", nil, false)
	err = h.Event(e)
	assert.NoError(t, err)

	e = event.New(0, event.Error, "TestStandardStreamsHandler_Event error", nil, false)
	err = h.Event(e)
	assert.NoError(t, err)

	pipeOutW.Close()
	pipeErrW.Close()
	wg.Wait()

	assert.Contains(t, outbuf.String(), "TestStandardStreamsHandler_Event info")
	assert.Contains(t, errbuf.String(), "TestStandardStreamsHandler_Event error")
}
Beispiel #7
0
func TestEvent(t *testing.T) {
	l, err := newUNIXListener()
	require.NoError(t, err)
	defer l.Close()

	handler, err := New("", l.Addr, DAEMON, "")
	require.NoError(t, err)

	logEvent := event.New(1, event.Warning, "testing Event()", map[string]interface{}{"test": "TestEvent"}, false)
	err = handler.Event(logEvent)
	require.NoError(t, err)

	msg := <-l.MsgChan
	assert.Equal(t, "<28>"+logEvent.Time.Format(time.StampMilli)+" syslog.test["+fmt.Sprintf("%d", os.Getpid())+"]: testing Event() -- test=TestEvent", msg)
}
Beispiel #8
0
// Event queues a message at the given level.
// Additional fields may be provided, which will be recursively copied at the time of the function call, and provided to the destination output handler.
// It returns an event Id that can be used with Sync().
func (logger *Logger) Event(level event.Level, message string, fields ...interface{}) uint64 {
	var eventFields interface{}
	if len(fields) > 1 {
		eventFields = fields
	} else if len(fields) == 1 {
		eventFields = fields[0]
	} else if len(fields) == 0 {
		eventFields = nil
	}

	getStack := int32(level) >= atomic.LoadInt32(&logger.stackMinLevel)
	//TODO do we want to just remove the id param from event.New()?
	logEvent := event.New(0, level, message, eventFields, getStack)

	return logger.SendEvent(logEvent)
}
Beispiel #9
0
func TestEvent(t *testing.T) {
	sw, err := New(splunkHttpsURL)
	require.NoError(t, err)

	logEvent := event.New(1, event.Warning, "testing Event()", map[string]interface{}{"test": "TestEvent"}, false)
	err = sw.Event(logEvent)
	assert.NoError(t, err)

	serverEvent := splunkSvr.events[len(splunkSvr.events)-1]

	assert.Equal(t, sw.Index, serverEvent.index)
	assert.Equal(t, sw.Hostname, serverEvent.host)
	assert.Equal(t, sw.Source, serverEvent.source)
	assert.Equal(t, sw.SourceType, serverEvent.sourcetype)
	assert.Contains(t, serverEvent.message, "warning(3)")
	assert.Contains(t, serverEvent.message, logEvent.Message)
	assert.Contains(t, serverEvent.message, "test=TestEvent")
}