Add new webhooks plugin that superseed github and rollbar plugins.
closes #1289 Signed-off-by: François de Metz <francois@stormz.me> Signed-off-by: Cyril Duez <cyril@stormz.me> Rename internals struct. Signed-off-by: François de Metz <francois@stormz.me> Signed-off-by: Cyril Duez <cyril@stormz.me> Update changelog. Signed-off-by: François de Metz <francois@stormz.me> Signed-off-by: Cyril Duez <cyril@stormz.me> Update READMEs and CHANGELOG. Signed-off-by: François de Metz <francois@stormz.me> Signed-off-by: Cyril Duez <cyril@stormz.me> Update SampleConfig. Update the config format. Update telegraf config. Update the webhooks README. Update changelog. Update the changelog with an upgrade path. Update default ports. Fix indent. Check for nil value on AvailableWebhooks. Check for CanInterface.
This commit is contained in:
committed by
Cameron Sparr
parent
e3448153e1
commit
e603825e37
38
plugins/inputs/webhooks/rollbar/README.md
Normal file
38
plugins/inputs/webhooks/rollbar/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# rollbar webhooks
|
||||
|
||||
You should configure your Rollbar's Webhooks to point at the `webhooks` service. To do this go to `rollbar.com/` and click `Settings > Notifications > Webhook`. In the resulting page set `URL` to `http://<my_ip>:1619/rollbar`, and click on `Enable Webhook Integration`.
|
||||
|
||||
## Events
|
||||
|
||||
The titles of the following sections are links to the full payloads and details for each event. The body contains what information from the event is persisted. The format is as follows:
|
||||
```
|
||||
# TAGS
|
||||
* 'tagKey' = `tagValue` type
|
||||
# FIELDS
|
||||
* 'fieldKey' = `fieldValue` type
|
||||
```
|
||||
The tag values and field values show the place on the incoming JSON object where the data is sourced from.
|
||||
|
||||
See [webhook doc](https://rollbar.com/docs/webhooks/)
|
||||
|
||||
#### `new_item` event
|
||||
|
||||
**Tags:**
|
||||
* 'event' = `event.event_name` string
|
||||
* 'environment' = `event.data.item.environment` string
|
||||
* 'project_id = `event.data.item.project_id` int
|
||||
* 'language' = `event.data.item.last_occurence.language` string
|
||||
* 'level' = `event.data.item.last_occurence.level` string
|
||||
|
||||
**Fields:**
|
||||
* 'id' = `event.data.item.id` int
|
||||
|
||||
#### `deploy` event
|
||||
|
||||
**Tags:**
|
||||
* 'event' = `event.event_name` string
|
||||
* 'environment' = `event.data.deploy.environment` string
|
||||
* 'project_id = `event.data.deploy.project_id` int
|
||||
|
||||
**Fields:**
|
||||
* 'id' = `event.data.item.id` int
|
||||
69
plugins/inputs/webhooks/rollbar/rollbar_webhooks.go
Normal file
69
plugins/inputs/webhooks/rollbar/rollbar_webhooks.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package rollbar
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/influxdata/telegraf"
|
||||
)
|
||||
|
||||
type RollbarWebhook struct {
|
||||
Path string
|
||||
acc telegraf.Accumulator
|
||||
}
|
||||
|
||||
func (rb *RollbarWebhook) Register(router *mux.Router, acc telegraf.Accumulator) {
|
||||
router.HandleFunc(rb.Path, rb.eventHandler).Methods("POST")
|
||||
log.Printf("Started the webhooks_rollbar on %s\n", rb.Path)
|
||||
rb.acc = acc
|
||||
}
|
||||
|
||||
func (rb *RollbarWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
dummyEvent := &DummyEvent{}
|
||||
err = json.Unmarshal(data, dummyEvent)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
event, err := NewEvent(dummyEvent, data)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
rb.acc.AddFields("rollbar_webhooks", event.Fields(), event.Tags(), time.Now())
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func generateEvent(event Event, data []byte) (Event, error) {
|
||||
err := json.Unmarshal(data, event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return event, nil
|
||||
}
|
||||
|
||||
func NewEvent(dummyEvent *DummyEvent, data []byte) (Event, error) {
|
||||
switch dummyEvent.EventName {
|
||||
case "new_item":
|
||||
return generateEvent(&NewItem{}, data)
|
||||
case "deploy":
|
||||
return generateEvent(&Deploy{}, data)
|
||||
default:
|
||||
return nil, errors.New("Not implemented type: " + dummyEvent.EventName)
|
||||
}
|
||||
}
|
||||
78
plugins/inputs/webhooks/rollbar/rollbar_webhooks_events.go
Normal file
78
plugins/inputs/webhooks/rollbar/rollbar_webhooks_events.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package rollbar
|
||||
|
||||
import "strconv"
|
||||
|
||||
type Event interface {
|
||||
Tags() map[string]string
|
||||
Fields() map[string]interface{}
|
||||
}
|
||||
|
||||
type DummyEvent struct {
|
||||
EventName string `json:"event_name"`
|
||||
}
|
||||
|
||||
type NewItemDataItemLastOccurence struct {
|
||||
Language string `json:"language"`
|
||||
Level string `json:"level"`
|
||||
}
|
||||
|
||||
type NewItemDataItem struct {
|
||||
Id int `json:"id"`
|
||||
Environment string `json:"environment"`
|
||||
ProjectId int `json:"project_id"`
|
||||
LastOccurence NewItemDataItemLastOccurence `json:"last_occurrence"`
|
||||
}
|
||||
|
||||
type NewItemData struct {
|
||||
Item NewItemDataItem `json:"item"`
|
||||
}
|
||||
|
||||
type NewItem struct {
|
||||
EventName string `json:"event_name"`
|
||||
Data NewItemData `json:"data"`
|
||||
}
|
||||
|
||||
func (ni *NewItem) Tags() map[string]string {
|
||||
return map[string]string{
|
||||
"event": ni.EventName,
|
||||
"environment": ni.Data.Item.Environment,
|
||||
"project_id": strconv.Itoa(ni.Data.Item.ProjectId),
|
||||
"language": ni.Data.Item.LastOccurence.Language,
|
||||
"level": ni.Data.Item.LastOccurence.Level,
|
||||
}
|
||||
}
|
||||
|
||||
func (ni *NewItem) Fields() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"id": ni.Data.Item.Id,
|
||||
}
|
||||
}
|
||||
|
||||
type DeployDataDeploy struct {
|
||||
Id int `json:"id"`
|
||||
Environment string `json:"environment"`
|
||||
ProjectId int `json:"project_id"`
|
||||
}
|
||||
|
||||
type DeployData struct {
|
||||
Deploy DeployDataDeploy `json:"deploy"`
|
||||
}
|
||||
|
||||
type Deploy struct {
|
||||
EventName string `json:"event_name"`
|
||||
Data DeployData `json:"data"`
|
||||
}
|
||||
|
||||
func (ni *Deploy) Tags() map[string]string {
|
||||
return map[string]string{
|
||||
"event": ni.EventName,
|
||||
"environment": ni.Data.Deploy.Environment,
|
||||
"project_id": strconv.Itoa(ni.Data.Deploy.ProjectId),
|
||||
}
|
||||
}
|
||||
|
||||
func (ni *Deploy) Fields() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"id": ni.Data.Deploy.Id,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package rollbar
|
||||
|
||||
func NewItemJSON() string {
|
||||
return `
|
||||
{
|
||||
"event_name": "new_item",
|
||||
"data": {
|
||||
"item": {
|
||||
"public_item_id": null,
|
||||
"integrations_data": {},
|
||||
"last_activated_timestamp": 1382655421,
|
||||
"unique_occurrences": null,
|
||||
"id": 272716944,
|
||||
"environment": "production",
|
||||
"title": "testing aobg98wrwe",
|
||||
"last_occurrence_id": 481761639,
|
||||
"last_occurrence_timestamp": 1382655421,
|
||||
"platform": 0,
|
||||
"first_occurrence_timestamp": 1382655421,
|
||||
"project_id": 90,
|
||||
"resolved_in_version": null,
|
||||
"status": 1,
|
||||
"hash": "c595b2ae0af9b397bb6bdafd57104ac4d5f6b382",
|
||||
"last_occurrence": {
|
||||
"body": {
|
||||
"message": {
|
||||
"body": "testing aobg98wrwe"
|
||||
}
|
||||
},
|
||||
"uuid": "d2036647-e0b7-4cad-bc98-934831b9b6d1",
|
||||
"language": "python",
|
||||
"level": "error",
|
||||
"timestamp": 1382655421,
|
||||
"server": {
|
||||
"host": "dev",
|
||||
"argv": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"environment": "production",
|
||||
"framework": "unknown",
|
||||
"notifier": {
|
||||
"version": "0.5.12",
|
||||
"name": "pyrollbar"
|
||||
},
|
||||
"metadata": {
|
||||
"access_token": "",
|
||||
"debug": {
|
||||
"routes": {
|
||||
"start_time": 1382212080401,
|
||||
"counters": {
|
||||
"post_item": 3274122
|
||||
}
|
||||
}
|
||||
},
|
||||
"customer_timestamp": 1382655421,
|
||||
"api_server_hostname": "web6"
|
||||
}
|
||||
},
|
||||
"framework": 0,
|
||||
"total_occurrences": 1,
|
||||
"level": 40,
|
||||
"counter": 4,
|
||||
"first_occurrence_id": 481761639,
|
||||
"activating_occurrence_id": 481761639
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
func DeployJSON() string {
|
||||
return `
|
||||
{
|
||||
"event_name": "deploy",
|
||||
"data": {
|
||||
"deploy": {
|
||||
"comment": "deploying webs",
|
||||
"user_id": 1,
|
||||
"finish_time": 1382656039,
|
||||
"start_time": 1382656038,
|
||||
"id": 187585,
|
||||
"environment": "production",
|
||||
"project_id": 90,
|
||||
"local_username": "brian",
|
||||
"revision": "e4b9b7db860b2e5ac799f8c06b9498b71ab270bb"
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
func UnknowJSON() string {
|
||||
return `
|
||||
{
|
||||
"event_name": "roger"
|
||||
}`
|
||||
}
|
||||
72
plugins/inputs/webhooks/rollbar/rollbar_webhooks_test.go
Normal file
72
plugins/inputs/webhooks/rollbar/rollbar_webhooks_test.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package rollbar
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func postWebhooks(rb *RollbarWebhook, eventBody string) *httptest.ResponseRecorder {
|
||||
req, _ := http.NewRequest("POST", "/", strings.NewReader(eventBody))
|
||||
w := httptest.NewRecorder()
|
||||
w.Code = 500
|
||||
|
||||
rb.eventHandler(w, req)
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
func TestNewItem(t *testing.T) {
|
||||
var acc testutil.Accumulator
|
||||
rb := &RollbarWebhook{Path: "/rollbar", acc: &acc}
|
||||
resp := postWebhooks(rb, NewItemJSON())
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Errorf("POST new_item returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusOK)
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"id": 272716944,
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"event": "new_item",
|
||||
"environment": "production",
|
||||
"project_id": "90",
|
||||
"language": "python",
|
||||
"level": "error",
|
||||
}
|
||||
|
||||
acc.AssertContainsTaggedFields(t, "rollbar_webhooks", fields, tags)
|
||||
}
|
||||
|
||||
func TestDeploy(t *testing.T) {
|
||||
var acc testutil.Accumulator
|
||||
rb := &RollbarWebhook{Path: "/rollbar", acc: &acc}
|
||||
resp := postWebhooks(rb, DeployJSON())
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Errorf("POST deploy returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusOK)
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"id": 187585,
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"event": "deploy",
|
||||
"environment": "production",
|
||||
"project_id": "90",
|
||||
}
|
||||
|
||||
acc.AssertContainsTaggedFields(t, "rollbar_webhooks", fields, tags)
|
||||
}
|
||||
|
||||
func TestUnknowItem(t *testing.T) {
|
||||
rb := &RollbarWebhook{Path: "/rollbar"}
|
||||
resp := postWebhooks(rb, UnknowJSON())
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Errorf("POST unknow returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusOK)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user