Skip to content

Commit

Permalink
Merge pull request #261 from melchiormoulin/analytics
Browse files Browse the repository at this point in the history
Analytics
  • Loading branch information
theckman committed Mar 9, 2021
2 parents 4d8ea2c + a757d33 commit 3366469
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 3 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ bin/*
*.swp
pd
vendor/
.vscode/
.vscode/
.idea/
65 changes: 65 additions & 0 deletions analytics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package pagerduty

import (
"context"
)

type AnalyticsRequest struct {
AnalyticsFilter *AnalyticsFilter `json:"filters,omitempty"`
AggregateUnit string `json:"aggregate_unit,omitempty"`
TimeZone string `json:"time_zone,omitempty"`
}
type AnalyticsResponse struct {
Data []AnalyticsData `json:"data,omitempty"`
AnalyticsFilter *AnalyticsFilter `json:"filters,omitempty"`
AggregateUnit string `json:"aggregate_unit,omitempty"`
TimeZone string `json:"time_zone,omitempty"`
}

type AnalyticsFilter struct {
CreatedAtStart string `json:"created_at_start,omitempty"`
CreatedAtEnd string `json:"created_at_end,omitempty"`
Urgency string `json:"urgency,omitempty"`
Major bool `json:"major,omitempty"`
ServiceIDs []string `json:"service_ids,omitempty"`
TeamIDs []string `json:"team_ids,omitempty"`
PriorityIDs []string `json:"priority_ids,omitempty"`
PriorityName []string `json:"priority_name,omitempty"`
}

type AnalyticsData struct {
ServiceID string `json:"service_id,omitempty"`
ServiceName string `json:"service_name,omitempty"`
TeamID string `json:"team_id,omitempty"`
TeamName string `json:"team_name,omitempty"`
MeanSecondsToResolve int `json:"mean_seconds_to_resolve,omitempty"`
MeanSecondsToFirstAck int `json:"mean_seconds_to_first_ack,omitempty"`
MeanSecondsToEngage int `json:"mean_seconds_to_engage,omitempty"`
MeanSecondsToMobilize int `json:"mean_seconds_to_mobilize,omitempty"`
MeanEngagedSeconds int `json:"mean_engaged_seconds,omitempty"`
MeanEngagedUserCount int `json:"mean_engaged_user_count,omitempty"`
TotalEscalationCount int `json:"total_escalation_count,omitempty"`
MeanAssignmentCount int `json:"mean_assignment_count,omitempty"`
TotalBusinessHourInterruptions int `json:"total_business_hour_interruptions,omitempty"`
TotalSleepHourInterruptions int `json:"total_sleep_hour_interruptions,omitempty"`
TotalOffHourInterruptions int `json:"total_off_hour_interruptions,omitempty"`
TotalSnoozedSeconds int `json:"total_snoozed_seconds,omitempty"`
TotalEngagedSeconds int `json:"total_engaged_seconds,omitempty"`
TotalIncidentCount int `json:"total_incident_count,omitempty"`
UpTimePct int `json:"up_time_pct,omitempty"`
UserDefinedEffortSeconds int `json:"user_defined_effort_seconds,omitempty"`
RangeStart string `json:"range_start,omitempty"`
}

func (c *Client) GetAggregatedIncidentData(ctx context.Context, analytics AnalyticsRequest) (AnalyticsResponse, error) {
var analyticsResponse AnalyticsResponse
headers := make(map[string]string)
headers["X-EARLY-ACCESS"] = "analytics-v2"

resp, err := c.post(ctx, "/analytics/metrics/incidents/all", analytics, headers)
if err != nil {
return analyticsResponse, err
}
err = c.decodeJSON(resp, &analyticsResponse)
return analyticsResponse, err
}
53 changes: 53 additions & 0 deletions analytics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package pagerduty

import (
"context"
"encoding/json"
"net/http"
"testing"
)

func TestAnalytics_GetAggregatedIncidentData(t *testing.T) {
setup()
defer teardown()

analyticsRequest := AnalyticsRequest{
AnalyticsFilter: &AnalyticsFilter{
CreatedAtStart: "2021-01-01T15:00:32Z",
CreatedAtEnd: "2021-01-08T15:00:32Z",
TeamIDs: []string{"PCDYDX0"},
},
AggregateUnit: "day",
TimeZone: "Etc/UTC",
}
analyticsDataWanted := AnalyticsData{MeanSecondsToResolve: 34550, MeanSecondsToFirstAck: 70, MeanEngagedSeconds: 502, MeanAssignmentCount: 1, TotalBusinessHourInterruptions: 1, TotalEngagedSeconds: 2514, TotalIncidentCount: 5, RangeStart: "2021-01-06T00:00:00.000000"}
analyticsFilterWanted := AnalyticsFilter{CreatedAtStart: "2021-01-06T09:21:41Z", CreatedAtEnd: "2021-01-13T09:21:41Z", TeamIDs: []string{"PCDYDX0"}}
analyticsResponse := AnalyticsResponse{
Data: []AnalyticsData{analyticsDataWanted},
AnalyticsFilter: &analyticsFilterWanted,
AggregateUnit: "day",
TimeZone: "Etc/UTC",
}
bytesAnalyticsResponse, err := json.Marshal(analyticsResponse)
mux.HandleFunc("/analytics/metrics/incidents/all", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
w.Write(bytesAnalyticsResponse)
})

client := &Client{apiEndpoint: server.URL,
authToken: "foo",
HTTPClient: defaultHTTPClient,
}

res, err := client.GetAggregatedIncidentData(context.Background(), analyticsRequest)
want := AnalyticsResponse{
Data: []AnalyticsData{analyticsDataWanted},
AnalyticsFilter: &analyticsFilterWanted,
AggregateUnit: "day",
TimeZone: "Etc/UTC",
}
if err != nil {
t.Fatal(err)
}
testEqual(t, want, res)
}
105 changes: 105 additions & 0 deletions command/analytics_show.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package main

import (
"context"
"encoding/json"
"fmt"
"github.com/PagerDuty/go-pagerduty"
"github.com/mitchellh/cli"
log "github.com/sirupsen/logrus"
"strings"
"time"
)

type AnalyticsShow struct {
Meta
}

func AnalyticsGetAggregatedIncidentDataCommand() (cli.Command, error) {
return &AnalyticsShow{}, nil
}

func (c *AnalyticsShow) Help() string {
helpText := `
analytics show
Options:
-(service_id|team_id) #MANDATORY provide service or team id to stats on.
-start #Optional RFC3339 format default : 7 days ago
-end #Optional RFC3339 format default : now
-urgency #Optional (high|low)
` + c.Meta.Help()
return strings.TrimSpace(helpText)
}

func (c *AnalyticsShow) Synopsis() string {
return "Get analytics aggregated incident data"
}

func (c *AnalyticsShow) Run(args []string) int {
flags := c.Meta.FlagSet("analytics show")
flags.Usage = func() { fmt.Println(c.Help()) }
servID := flags.String("service_id", "", "Service ID")
now := time.Now()
sevenDaysAgo := now.Add(time.Duration(-24*7) * time.Hour)
start := flags.String("start", sevenDaysAgo.Format(time.RFC3339), "start date")
end := flags.String("end", now.Format(time.RFC3339), "end date")
urgency := flags.String("urgency", "", "high|low")
teamID := flags.String("team_id", "", "team ID")

//log.SetLevel(log.DebugLevel)
if err := flags.Parse(args); err != nil {
log.Errorln(err)
return -1
}

if err := c.Meta.Setup(); err != nil {
log.Error(err)
return -1
}

client := c.Meta.Client()

serviceIds := make([]string, 1)
if *servID == "" {
serviceIds = nil
} else {
serviceIds[0] = *servID
}

teamIds := make([]string, 1)
if *teamID == "" {
teamIds = nil
} else {
teamIds[0] = *teamID
}

analyticsFilter := pagerduty.AnalyticsFilter{
CreatedAtStart: *start,
CreatedAtEnd: *end,
Urgency: *urgency,
ServiceIDs: serviceIds,
TeamIDs: teamIds,
}

analytics := pagerduty.AnalyticsRequest{
AnalyticsFilter: &analyticsFilter,
AggregateUnit: "day",
TimeZone: "Etc/UTC",
}

aggregatedIncidentData, err := client.GetAggregatedIncidentData(context.Background(), analytics)
if err != nil {
log.Error(err)
return -1
}

aggregatedIncidentDataBytes, err := json.Marshal(aggregatedIncidentData)
if err != nil {
log.Error(err)
return -1
}
fmt.Println(string(aggregatedIncidentDataBytes))
return 0
}
5 changes: 3 additions & 2 deletions command/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ func loadCommands() map[string]cli.CommandFactory {
"user notification-rule show": UserNotificationRuleShowCommand,
"user notification-rule update": UserNotificationRuleUpdateCommand,

"vendor list": VendorListCommand,
"vendor show": VendorShowCommand,
"vendor list": VendorListCommand,
"vendor show": VendorShowCommand,
"analyticsAggregatedIncidentData show": AnalyticsGetAggregatedIncidentDataCommand,
}
}

Expand Down

0 comments on commit 3366469

Please sign in to comment.