Add logrus, prometheus client and matrix-org/util
This commit is contained in:
parent
41c6a3737e
commit
63d1bcd66a
313 changed files with 53958 additions and 1 deletions
14
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/CHANGELOG.md
vendored
Normal file
14
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# logrus-airbrake-hook Changelog
|
||||
|
||||
v2.1.1 - 2016-09-22
|
||||
|
||||
* Fix request deletion from the log entry
|
||||
|
||||
v2.1.0 - 2016-09-22
|
||||
|
||||
* Support ***`*http.Request` error reporting
|
||||
|
||||
v2.0.0 - 2015-10-05
|
||||
|
||||
* Support gobrake v2 api
|
||||
|
||||
21
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/LICENSE
vendored
Normal file
21
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Gemnasium
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
55
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/README.md
vendored
Normal file
55
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/README.md
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Airbrake Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" /> [](https://travis-ci.org/gemnasium/logrus-airbrake-hook) [](https://godoc.org/gopkg.in/gemnasium/logrus-airbrake-hook.v2)
|
||||
|
||||
Use this hook to send your errors to [Airbrake](https://airbrake.io/).
|
||||
This hook is using the [official airbrake go package](https://github.com/airbrake/gobrake), and will hit the api V3.
|
||||
The hook is synchronous and will send the error for `log.Error`, `log.Fatal` and `log.Panic` levels.
|
||||
|
||||
All logrus fields will be sent as context fields on Airbrake.
|
||||
|
||||
## Usage
|
||||
|
||||
The hook must be configured with:
|
||||
|
||||
* A project ID (found in your your Airbrake project settings)
|
||||
* An API key ID (found in your your Airbrake project settings)
|
||||
* The name of the current environment ("development", "staging", "production", ...)
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
log.AddHook(airbrake.NewHook(123, "xyz", "production"))
|
||||
log.Error("some logging message")
|
||||
}
|
||||
```
|
||||
|
||||
Note that if environment == "development", the hook will not send anything to airbrake.
|
||||
|
||||
### Reporting http request failure
|
||||
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
log.AddHook(airbrake.NewHook(123, "xyz", "production"))
|
||||
req, err := http.NewRequest("GET", "http://example.com", nil)
|
||||
log.WithField("request", req).Error("some logging message")
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
* the req will be removed from the log entry
|
||||
* the name of the field doesn't matter, since it's not logged
|
||||
* if more than one request is sent, only the first will be taken into account (and the others will be logged as strings)
|
||||
71
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/airbrake.go
vendored
Normal file
71
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/airbrake.go
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
package airbrake // import "gopkg.in/gemnasium/logrus-airbrake-hook.v2"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"gopkg.in/airbrake/gobrake.v2"
|
||||
)
|
||||
|
||||
// AirbrakeHook to send exceptions to an exception-tracking service compatible
|
||||
// with the Airbrake API.
|
||||
type airbrakeHook struct {
|
||||
Airbrake *gobrake.Notifier
|
||||
}
|
||||
|
||||
func NewHook(projectID int64, apiKey, env string) *airbrakeHook {
|
||||
airbrake := gobrake.NewNotifier(projectID, apiKey)
|
||||
airbrake.AddFilter(func(notice *gobrake.Notice) *gobrake.Notice {
|
||||
if env == "development" {
|
||||
return nil
|
||||
}
|
||||
notice.Context["environment"] = env
|
||||
return notice
|
||||
})
|
||||
hook := &airbrakeHook{
|
||||
Airbrake: airbrake,
|
||||
}
|
||||
return hook
|
||||
}
|
||||
|
||||
func (hook *airbrakeHook) Fire(entry *logrus.Entry) error {
|
||||
var notifyErr error
|
||||
err, ok := entry.Data["error"].(error)
|
||||
if ok {
|
||||
notifyErr = err
|
||||
} else {
|
||||
notifyErr = errors.New(entry.Message)
|
||||
}
|
||||
var req *http.Request
|
||||
for k, v := range entry.Data {
|
||||
if r, ok := v.(*http.Request); ok {
|
||||
req = r
|
||||
delete(entry.Data, k)
|
||||
break
|
||||
}
|
||||
}
|
||||
notice := hook.Airbrake.Notice(notifyErr, req, 3)
|
||||
for k, v := range entry.Data {
|
||||
notice.Context[k] = fmt.Sprintf("%s", v)
|
||||
}
|
||||
|
||||
hook.sendNotice(notice)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *airbrakeHook) sendNotice(notice *gobrake.Notice) {
|
||||
if _, err := hook.Airbrake.SendNotice(notice); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to send error to Airbrake: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (hook *airbrakeHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.PanicLevel,
|
||||
}
|
||||
}
|
||||
203
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/airbrake_test.go
vendored
Normal file
203
vendor/src/gopkg.in/gemnasium/logrus-airbrake-hook.v2/airbrake_test.go
vendored
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
package airbrake
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"gopkg.in/airbrake/gobrake.v2"
|
||||
)
|
||||
|
||||
type customErr struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e *customErr) Error() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
const (
|
||||
testAPIKey = "abcxyz"
|
||||
testEnv = "development"
|
||||
expectedClass = "*airbrake.customErr"
|
||||
expectedMsg = "foo"
|
||||
unintendedMsg = "Airbrake will not see this string"
|
||||
)
|
||||
|
||||
var (
|
||||
noticeChan = make(chan *gobrake.Notice, 1)
|
||||
)
|
||||
|
||||
// TestLogEntryMessageReceived checks if invoking Logrus' log.Error
|
||||
// method causes an XML payload containing the log entry message is received
|
||||
// by a HTTP server emulating an Airbrake-compatible endpoint.
|
||||
func TestLogEntryMessageReceived(t *testing.T) {
|
||||
log := logrus.New()
|
||||
hook := newTestHook()
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
log.Error(expectedMsg)
|
||||
|
||||
select {
|
||||
case received := <-noticeChan:
|
||||
receivedErr := received.Errors[0]
|
||||
if receivedErr.Message != expectedMsg {
|
||||
t.Errorf("Unexpected message received: %s", receivedErr.Message)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Airbrake API")
|
||||
}
|
||||
}
|
||||
|
||||
// TestLogEntryMessageReceived confirms that, when passing an error type using
|
||||
// logrus.Fields, a HTTP server emulating an Airbrake endpoint receives the
|
||||
// error message returned by the Error() method on the error interface
|
||||
// rather than the logrus.Entry.Message string.
|
||||
func TestLogEntryWithErrorReceived(t *testing.T) {
|
||||
log := logrus.New()
|
||||
hook := newTestHook()
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"error": &customErr{expectedMsg},
|
||||
}).Error(unintendedMsg)
|
||||
|
||||
select {
|
||||
case received := <-noticeChan:
|
||||
receivedErr := received.Errors[0]
|
||||
if receivedErr.Message != expectedMsg {
|
||||
t.Errorf("Unexpected message received: %s", receivedErr.Message)
|
||||
}
|
||||
if receivedErr.Type != expectedClass {
|
||||
t.Errorf("Unexpected error class: %s", receivedErr.Type)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Airbrake API")
|
||||
}
|
||||
}
|
||||
|
||||
// TestLogEntryWithNonErrorTypeNotReceived confirms that, when passing a
|
||||
// non-error type using logrus.Fields, a HTTP server emulating an Airbrake
|
||||
// endpoint receives the logrus.Entry.Message string.
|
||||
//
|
||||
// Only error types are supported when setting the 'error' field using
|
||||
// logrus.WithFields().
|
||||
func TestLogEntryWithNonErrorTypeNotReceived(t *testing.T) {
|
||||
log := logrus.New()
|
||||
hook := newTestHook()
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"error": expectedMsg,
|
||||
}).Error(unintendedMsg)
|
||||
|
||||
select {
|
||||
case received := <-noticeChan:
|
||||
receivedErr := received.Errors[0]
|
||||
if receivedErr.Message != unintendedMsg {
|
||||
t.Errorf("Unexpected message received: %s", receivedErr.Message)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Airbrake API")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogEntryWithCustomFields(t *testing.T) {
|
||||
log := logrus.New()
|
||||
hook := newTestHook()
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"user_id": "123",
|
||||
}).Error(unintendedMsg)
|
||||
|
||||
select {
|
||||
case received := <-noticeChan:
|
||||
receivedErr := received.Errors[0]
|
||||
if receivedErr.Message != unintendedMsg {
|
||||
t.Errorf("Unexpected message received: %s", receivedErr.Message)
|
||||
}
|
||||
if received.Context["user_id"] != "123" {
|
||||
t.Errorf("Expected message to contain Context[\"user_id\"] == \"123\" got %q", received.Context["user_id"])
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Airbrake API")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogEntryWithHTTPRequestFields(t *testing.T) {
|
||||
log := logrus.New()
|
||||
hook := newTestHook()
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
req, err := http.NewRequest("GET", "http://example.com", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"user_id": "123",
|
||||
"request": req,
|
||||
}).Error(unintendedMsg)
|
||||
|
||||
select {
|
||||
case received := <-noticeChan:
|
||||
receivedErr := received.Errors[0]
|
||||
if receivedErr.Message != unintendedMsg {
|
||||
t.Errorf("Unexpected message received: %s", receivedErr.Message)
|
||||
}
|
||||
if received.Context["user_id"] != "123" {
|
||||
t.Errorf("Expected message to contain Context[\"user_id\"] == \"123\" got %q", received.Context["user_id"])
|
||||
}
|
||||
if received.Context["url"] != "http://example.com" {
|
||||
t.Errorf("Expected message to contain Context[\"url\"] == \"http://example.com\" got %q", received.Context["url"])
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Airbrake API")
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a new airbrakeHook with the test server proxied
|
||||
func newTestHook() *airbrakeHook {
|
||||
// Make a http.Client with the transport
|
||||
httpClient := &http.Client{Transport: &FakeRoundTripper{}}
|
||||
|
||||
hook := NewHook(123, testAPIKey, "production")
|
||||
hook.Airbrake.Client = httpClient
|
||||
return hook
|
||||
}
|
||||
|
||||
// gobrake API doesn't allow to override endpoint, we need a http.Roundtripper
|
||||
type FakeRoundTripper struct {
|
||||
}
|
||||
|
||||
func (rt *FakeRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
b, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
notice := &gobrake.Notice{}
|
||||
err = json.Unmarshal(b, notice)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
noticeChan <- notice
|
||||
|
||||
jsonResponse := struct {
|
||||
Id string `json:"id"`
|
||||
}{"1"}
|
||||
|
||||
sendResponse, _ := json.Marshal(jsonResponse)
|
||||
res := &http.Response{
|
||||
StatusCode: http.StatusCreated,
|
||||
Body: ioutil.NopCloser(bytes.NewReader(sendResponse)),
|
||||
Header: make(http.Header),
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue