1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View 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

View 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)
}
}

View 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,
}
}

View file

@ -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"
}`
}

View 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)
}
}