Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
64
plugins/inputs/webhooks/rollbar/README.md
Normal file
64
plugins/inputs/webhooks/rollbar/README.md
Normal file
|
@ -0,0 +1,64 @@
|
|||
# rollbar webhooks
|
||||
|
||||
You should configure your Rollbar's Webhooks to point at the `webhooks` service.
|
||||
To do this go to [rollbar.com](https://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:
|
||||
|
||||
```toml
|
||||
# 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_occurrence.language` string
|
||||
* 'level' = `event.data.item.last_occurrence.level` string
|
||||
|
||||
**Fields:**
|
||||
|
||||
* 'id' = `event.data.item.id` int
|
||||
|
||||
### `occurrence` event
|
||||
|
||||
**Tags:**
|
||||
|
||||
* 'event' = `event.event_name` string
|
||||
* 'environment' = `event.data.item.environment` string
|
||||
* 'project_id = `event.data.item.project_id` int
|
||||
* 'language' = `event.data.occurrence.language` string
|
||||
* 'level' = `event.data.occurrence.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
|
82
plugins/inputs/webhooks/rollbar/rollbar_webhooks.go
Normal file
82
plugins/inputs/webhooks/rollbar/rollbar_webhooks.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package rollbar
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/common/auth"
|
||||
)
|
||||
|
||||
type Webhook struct {
|
||||
Path string
|
||||
acc telegraf.Accumulator
|
||||
log telegraf.Logger
|
||||
auth.BasicAuth
|
||||
}
|
||||
|
||||
// Register registers the webhook with the provided router
|
||||
func (rb *Webhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
|
||||
router.HandleFunc(rb.Path, rb.eventHandler).Methods("POST")
|
||||
rb.log = log
|
||||
rb.log.Infof("Started the webhooks_rollbar on %s", rb.Path)
|
||||
rb.acc = acc
|
||||
}
|
||||
|
||||
func (rb *Webhook) eventHandler(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
if !rb.Verify(r) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := io.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 "occurrence":
|
||||
return generateEvent(&occurrence{}, data)
|
||||
case "deploy":
|
||||
return generateEvent(&deploy{}, data)
|
||||
default:
|
||||
return nil, errors.New("Not implemented type: " + dummyEvent.EventName)
|
||||
}
|
||||
}
|
115
plugins/inputs/webhooks/rollbar/rollbar_webhooks_events.go
Normal file
115
plugins/inputs/webhooks/rollbar/rollbar_webhooks_events.go
Normal file
|
@ -0,0 +1,115 @@
|
|||
package rollbar
|
||||
|
||||
import "strconv"
|
||||
|
||||
type event interface {
|
||||
tags() map[string]string
|
||||
fields() map[string]interface{}
|
||||
}
|
||||
|
||||
type dummyEvent struct {
|
||||
EventName string `json:"event_name"`
|
||||
}
|
||||
|
||||
type newItemDataItemLastOccurrence 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"`
|
||||
LastOccurrence newItemDataItemLastOccurrence `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.LastOccurrence.Language,
|
||||
"level": ni.Data.Item.LastOccurrence.Level,
|
||||
}
|
||||
}
|
||||
|
||||
func (ni *newItem) fields() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"id": ni.Data.Item.ID,
|
||||
}
|
||||
}
|
||||
|
||||
type occurrenceDataOccurrence struct {
|
||||
Language string `json:"language"`
|
||||
Level string `json:"level"`
|
||||
}
|
||||
|
||||
type occurrenceDataItem struct {
|
||||
ID int `json:"id"`
|
||||
Environment string `json:"environment"`
|
||||
ProjectID int `json:"project_id"`
|
||||
}
|
||||
|
||||
type occurrenceData struct {
|
||||
Item occurrenceDataItem `json:"item"`
|
||||
Occurrence occurrenceDataOccurrence `json:"occurrence"`
|
||||
}
|
||||
|
||||
type occurrence struct {
|
||||
EventName string `json:"event_name"`
|
||||
Data occurrenceData `json:"data"`
|
||||
}
|
||||
|
||||
func (o *occurrence) tags() map[string]string {
|
||||
return map[string]string{
|
||||
"event": o.EventName,
|
||||
"environment": o.Data.Item.Environment,
|
||||
"project_id": strconv.Itoa(o.Data.Item.ProjectID),
|
||||
"language": o.Data.Occurrence.Language,
|
||||
"level": o.Data.Occurrence.Level,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *occurrence) fields() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"id": o.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,160 @@
|
|||
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 occurrenceJSON() string {
|
||||
return `
|
||||
{
|
||||
"event_name": "occurrence",
|
||||
"data": {
|
||||
"item": {
|
||||
"public_item_id": null,
|
||||
"integrations_data": {},
|
||||
"level_lock": 0,
|
||||
"last_activated_timestamp": 1471624512,
|
||||
"assigned_user_id": null,
|
||||
"hash": "188fc37fa6e641a4d4a3d0198938a1937d31ddbe",
|
||||
"id": 402860571,
|
||||
"environment": "production",
|
||||
"title": "Exception: test exception",
|
||||
"last_occurrence_id": 16298872829,
|
||||
"last_occurrence_timestamp": 1472226345,
|
||||
"platform": 0,
|
||||
"first_occurrence_timestamp": 1471624512,
|
||||
"project_id": 78234,
|
||||
"resolved_in_version": null,
|
||||
"status": 1,
|
||||
"unique_occurrences": null,
|
||||
"title_lock": 0,
|
||||
"framework": 6,
|
||||
"total_occurrences": 8,
|
||||
"level": 40,
|
||||
"counter": 2,
|
||||
"last_modified_by": 8247,
|
||||
"first_occurrence_id": 16103102935,
|
||||
"activating_occurrence_id": 16103102935
|
||||
},
|
||||
"occurrence": {
|
||||
"body": {
|
||||
"trace": {
|
||||
"frames": [{"method": "<main>", "lineno": 27, "filename": "/Users/rebeccastandig/Desktop/Dev/php-rollbar-app/index.php"}], "exception": {
|
||||
"message": "test 2",
|
||||
"class": "Exception"}
|
||||
}
|
||||
},
|
||||
"uuid": "84d4eccd-b24d-47ae-a42b-1a2f9a82fb82",
|
||||
"language": "php",
|
||||
"level": "error",
|
||||
"timestamp": 1472226345,
|
||||
"php_context": "cli",
|
||||
"environment": "production",
|
||||
"framework": "php",
|
||||
"person": null,
|
||||
"server": {
|
||||
"host": "Rebeccas-MacBook-Pro.local",
|
||||
"argv": ["index.php"]
|
||||
},
|
||||
"notifier": {
|
||||
"version": "0.18.2",
|
||||
"name": "rollbar-php"
|
||||
},
|
||||
"metadata": {
|
||||
"customer_timestamp": 1472226359
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
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 unknownJSON() string {
|
||||
return `
|
||||
{
|
||||
"event_name": "roger"
|
||||
}`
|
||||
}
|
98
plugins/inputs/webhooks/rollbar/rollbar_webhooks_test.go
Normal file
98
plugins/inputs/webhooks/rollbar/rollbar_webhooks_test.go
Normal file
|
@ -0,0 +1,98 @@
|
|||
package rollbar
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func postWebhooks(t *testing.T, rb *Webhook, eventBody string) *httptest.ResponseRecorder {
|
||||
req, err := http.NewRequest("POST", "/", strings.NewReader(eventBody))
|
||||
require.NoError(t, err)
|
||||
w := httptest.NewRecorder()
|
||||
w.Code = 500
|
||||
|
||||
rb.eventHandler(w, req)
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
func TestNewItem(t *testing.T) {
|
||||
var acc testutil.Accumulator
|
||||
rb := &Webhook{Path: "/rollbar", acc: &acc}
|
||||
resp := postWebhooks(t, 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 TestOccurrence(t *testing.T) {
|
||||
var acc testutil.Accumulator
|
||||
rb := &Webhook{Path: "/rollbar", acc: &acc}
|
||||
resp := postWebhooks(t, rb, occurrenceJSON())
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Errorf("POST occurrence returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusOK)
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"id": 402860571,
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"event": "occurrence",
|
||||
"environment": "production",
|
||||
"project_id": "78234",
|
||||
"language": "php",
|
||||
"level": "error",
|
||||
}
|
||||
|
||||
acc.AssertContainsTaggedFields(t, "rollbar_webhooks", fields, tags)
|
||||
}
|
||||
|
||||
func TestDeploy(t *testing.T) {
|
||||
var acc testutil.Accumulator
|
||||
rb := &Webhook{Path: "/rollbar", acc: &acc}
|
||||
resp := postWebhooks(t, 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 := &Webhook{Path: "/rollbar"}
|
||||
resp := postWebhooks(t, rb, unknownJSON())
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Errorf("POST unknow returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusOK)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue