8000 Basic support for historical & realtime stats by pteichman · Pull Request #66 · fastly/cli · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Basic support for historical & realtime stats #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
May 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
github.com/mholt/archiver v3.1.1+incompatible
github.com/mholt/archiver/v3 v3.3.0
github.com/mitchellh/go-wordwrap v1.0.0
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/mitchellh/mapstructure v1.1.2
github.com/nicksnyder/go-i18n v1.10.1 // indirect
github.com/pierrec/lz4 v2.3.0+incompatible // indirect
github.com/segmentio/textio v1.2.0
Expand Down
13 changes: 12 additions & 1 deletion pkg/api/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,18 @@ type Interface interface {
DeleteGCS(*fastly.DeleteGCSInput) error

GetUser(*fastly.GetUserInput) (*fastly.User, error)

GetRegions() (*fastly.RegionsResponse, error)
GetStatsJSON(*fastly.GetStatsInput, interface{}) error
}

// RealtimeStatsInterface is the subset of go-fastly's realtime stats API used here.
type RealtimeStatsInterface interface {
GetRealtimeStatsJSON(*fastly.GetRealtimeStatsInput, interface{}) error
}

// Interface assertion, to catch mismatches early.
// Ensure that fastly.Client satisfies Interface.
var _ Interface = (*fastly.Client)(nil)

// Ensure that fastly.RTSClient satisfies RealtimeStatsInterface.
var _ RealtimeStatsInterface = (*fastly.RTSClient)(nil)
16 changes: 16 additions & 0 deletions pkg/app/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/fastly/cli/pkg/logging/syslog"
"github.com/fastly/cli/pkg/service"
"github.com/fastly/cli/pkg/serviceversion"
"github.com/fastly/cli/pkg/stats"
"github.com/fastly/cli/pkg/text"
"github.com/fastly/cli/pkg/update"
"github.com/fastly/cli/pkg/version"
Expand Down Expand Up @@ -174,6 +175,11 @@ func Run(args []string, env config.Environment, file config.File, configFilePath
gcsUpdate := gcs.NewUpdateCommand(gcsRoot.CmdClause, &globals)
gcsDelete := gcs.NewDeleteCommand(gcsRoot.CmdClause, &globals)

statsRoot := stats.NewRootCommand(app, &globals)
statsRegions := stats.NewRegionsCommand(statsRoot.CmdClause, &globals)
statsHistorical := stats.NewHistoricalCommand(statsRoot.CmdClause, &globals)
statsRealtime := stats.NewRealtimeCommand(statsRoot.CmdClause, &globals)

commands := []common.Command{
configureRoot,
whoamiRoot,
Expand Down Expand Up @@ -273,6 +279,11 @@ func Run(args []string, env config.Environment, file config.File, configFilePath
gcsDescribe,
gcsUpdate,
gcsDelete,

statsRoot,
statsRegions,
statsHistorical,
statsRealtime,
}

// Handle parse errors and display contextal usage if possible. Due to bugs
Expand Down Expand Up @@ -363,6 +374,11 @@ func Run(args []string, env config.Environment, file config.File, configFilePath
return fmt.Errorf("error constructing Fastly API client: %w", err)
}

globals.RTSClient, err = fastly.NewRealtimeStatsClientForEndpoint(token, fastly.DefaultRealtimeStatsEndpoint)
if err != nil {
return fmt.Errorf("error constructing Fastly realtime stats client: %w", err)
}

command, found := common.SelectCommand(name, commands)
if !found {
usage := Usage(args, app, out, ioutil.Discard)
Expand Down
94 changes: 64 additions & 30 deletions pkg/app/run_test.go
F438
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app_test

import (
"bufio"
"bytes"
"io"
"strings"
Expand Down Expand Up @@ -29,12 +30,12 @@ func TestApplication(t *testing.T) {
{
name: "no args",
args: nil,
wantErr: helpDefault + "\nERROR: error parsing arguments: command not specified.\n\n",
wantErr: helpDefault + "\nERROR: error parsing arguments: command not specified.\n",
},
{
name: "help flag only",
args: []string{"--help"},
wantErr: helpDefault + "\nERROR: error parsing arguments: command not specified.\n\n",
wantErr: helpDefault + "\nERROR: error parsing arguments: command not specified.\n",
},
{
name: "help argument only",
Expand Down Expand Up @@ -65,16 +66,26 @@ func TestApplication(t *testing.T) {
errors.Deduce(err).Print(&stderr)
}

testutil.AssertString(t, testcase.wantOut, stdout.String())
// Our flag package creates trailing space on
// some lines. Strip what we get so we don't
// need to maintain invisible spaces in
// wantOut/wantErr below.
testutil.AssertString(t, testcase.wantOut, stripTrailingSpace(stdout.String()))
testutil.AssertString(t, testcase.wantErr, stripTrailingSpace(stderr.String()))
})
}
}

wantErrLines := strings.Split(testcase.wantErr, "\n")
outputErrLines := strings.Split(stderr.String(), "\n")
// stripTrailingSpace removes any trailing spaces from the multiline str.
func stripTrailingSpace(str string) string {
buf := bytes.NewBuffer(nil)

for i, line := range outputErrLines {
testutil.AssertString(t, strings.TrimSpace(wantErrLines[i]), strings.TrimSpace(line))
}
})
scan := bufio.NewScanner(strings.NewReader(str))
for scan.Scan() {
buf.WriteString(strings.TrimRight(scan.Text(), " \t\r\n"))
buf.WriteString("\n")
}
return buf.String()
}

var helpDefault = strings.TrimSpace(`
Expand All @@ -101,6 +112,8 @@ COMMANDS
backend Manipulate Fastly service version backends
healthcheck Manipulate Fastly service version healthchecks
logging Manipulate Fastly service version logging endpoints
stats View statistics (historical and realtime) for a Fastly
service
`) + "\n\n"

var helpService = strings.TrimSpace(`
Expand Down Expand Up @@ -844,15 +857,15 @@ COMMANDS
--auth-token=AUTH-TOKEN Use token based authentication
(https://logentries.com/doc/input-token/)
--format=FORMAT Apache style log formatting
--format-version=FORMAT-VERSION
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(the default, version 2 log format) or 1 (the
version 1 log format). The logging call gets
placed by default in vcl_log if format_version
is set to 2 and in vcl_deliver if
format_version is set to 1
--response-condition=RESPONSE-CONDITION
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
Expand Down Expand Up @@ -888,15 +901,15 @@ COMMANDS
--auth-token=AUTH-TOKEN Use token based authentication
(https://logentries.com/doc/input-token/)
--format=FORMAT Apache style log formatting
--format-version=FORMAT-VERSION
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(the default, version 2 log format) or 1 (the
version 1 log format). The logging call gets
placed by default in vcl_log if format_version
is set to 2 and in vcl_deliver if
format_version is set to 1
--response-condition=RESPONSE-CONDITION
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
Expand All @@ -921,7 +934,7 @@ COMMANDS
--version=VERSION Number of service version
--address=ADDRESS A hostname or IPv4 address
--port=PORT The port number
--format-version=FORMAT-VERSION
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(the default, version 2 log format) or 1 (the
Expand All @@ -930,7 +943,7 @@ COMMANDS
is set to 2 and in vcl_deliver if
format_version is set to 1
--format=FORMAT Apache style log formatting
--response-condition=RESPONSE-CONDITION
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
Expand Down Expand Up @@ -962,7 +975,7 @@ COMMANDS
--new-name=NEW-NAME New name of the Papertrail logging object
--address=ADDRESS A hostname or IPv4 address
--port=PORT The port number
--format-version=FORMAT-VERSION
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(the default, version 2 log format) or 1 (the
Expand All @@ -971,7 +984,7 @@ COMMANDS
is set to 2 and in vcl_deliver if
format_version is set to 1
--format=FORMAT Apache style log formatting
--response-condition=RESPONSE-CONDITION
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
Expand All @@ -996,19 +1009,19 @@ COMMANDS
--version=VERSION Number of service version
--url=URL The URL to POST to
--format=FORMAT Apache style log formatting
--format-version=FORMAT-VERSION
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(the default, version 2 log format) or 1 (the
version 1 log format). The logging call gets
placed by default in vcl_log if format_version
is set to 2 and in vcl_deliver if
format_version is set to 1
--response-condition=RESPONSE-CONDITION
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
--message-type=MESSAGE-TYPE
--message-type=MESSAGE-TYPE
How the message should be formatted. One of:
classic (default), loggly, logplex or blank
--placement=PLACEMENT Where in the generated VCL the logging call
Expand Down Expand Up @@ -1039,19 +1052,19 @@ COMMANDS
--new-name=NEW-NAME New name of the Sumologic logging object
--url=URL The URL to POST to
--format=FORMAT Apache style log formatting
--format-version=FORMAT-VERSION
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(the default, version 2 log format) or 1 (the
version 1 log format). The logging call gets
placed by default in vcl_log if format_version
is set to 2 and in vcl_deliver if
format_version is set to 1
--response-condition=RESPONSE-CONDITION
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
--message-type=MESSAGE-TYPE
10000 --message-type=MESSAGE-TYPE
How the message should be formatted. One of:
classic (default), loggly, logplex or blank
--placement=PLACEMENT Where in the generated VCL the logging call
Expand Down Expand Up @@ -1087,22 +1100,22 @@ COMMANDS
--gzip-level=GZIP-LEVEL What level of GZIP encoding to have when
dumping logs (default 0, no compression)
--format=FORMAT Apache style log formatting
--format-version=FORMAT-VERSION
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(the default, version 2 log format) or 1 (the
version 1 log format). The logging call gets
placed by default in vcl_log if format_version
is set to 2 and in vcl_deliver if
format_version is set to 1
--message-type=MESSAGE-TYPE
--message-type=MESSAGE-TYPE
How the message should be formatted. One of:
classic (default), loggly, logplex or blank
--response-condition=RESPONSE-CONDITION
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
--timestamp-format=TIMESTAMP-FORMAT
--timestamp-format=TIMESTAMP-FORMAT
strftime specified timestamp formatting
(default "%Y-%m-%dT%H:%M:%S.000")
--placement=PLACEMENT Where in the generated VCL the logging call
Expand Down Expand Up @@ -1141,7 +1154,7 @@ COMMANDS
--period=PERIOD How frequently log files are finalized so they
can be available for reading (in seconds,
default 3600)
--format-version=FORMAT-VERSION
--format-version=FORMAT-VERSION
The version of the custom logging format used
for the configured endpoint. Can be either 2
(the default, version 2 log format) or 1 (the
Expand All @@ -1152,11 +1165,11 @@ COMMANDS
--gzip-level=GZIP-LEVEL What level of GZIP encoding to have when
dumping logs (default 0, no compression)
--format=FORMAT Apache style log formatting
--response-condition=RESPONSE-CONDITION
--response-condition=RESPONSE-CONDITION
The name of an existing condition in the
configured endpoint, or leave blank to always
execute
--timestamp-format=TIMESTAMP-FORMAT
--timestamp-format=TIMESTAMP-FORMAT
strftime specified timestamp formatting
(default "%Y-%m-%dT%H:%M:%S.000")
--placement=PLACEMENT Where in the generated VCL the logging call
Expand All @@ -1170,6 +1183,27 @@ COMMANDS
--version=VERSION Number of service version
-n, --name=NAME The name of the GCS logging object

stats regions
List stats regions


stats historical --service-id=SERVICE-ID [<flags>]
View historical stats for a Fastly service

-s, --service-id=SERVICE-ID Service ID
--from=FROM From time, accepted formats at
https://docs.fastly.com/api/stats#Range
--to=TO To time
--by=BY Aggregation period (minute/hour/day)
--region=REGION Filter by region ('stats regions' to list)
--format=FORMAT Output format (json)

stats realtime --service-id=SERVICE-ID [<flags>]
View realtime stats for a Fastly service

-s, --service-id=SERVICE-ID Service ID
--format=FORMAT Output format (json)

For help on a specific command, try e.g.

fastly help configure
Expand Down
3 changes: 2 additions & 1 deletion pkg/config/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ type Data struct {
Env Environment
Flag Flag

Client api.Interface // set by Run after parse
Client api.Interface
RTSClient api.RealtimeStatsInterface
}

// Token yields the Fastly API token.
Expand Down
13 changes: 13 additions & 0 deletions pkg/mock/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ type API struct {
DeleteGCSFn func(*fastly.DeleteGCSInput) error

GetUserFn func(*fastly.GetUserInput) (*fastly.User, error)

GetRegionsFn func() (*fastly.RegionsResponse, error)
GetStatsJSONFn func(i *fastly.GetStatsInput, dst interface{}) error
}

// GetTokenSelf implements Interface.
Expand Down Expand Up @@ -412,3 +415,13 @@ func (m API) DeleteGCS(i *fastly.DeleteGCSInput) error {
func (m API) GetUser(i *fastly.GetUserInput) (*fastly.User, error) {
return m.GetUserFn(i)
}

// GetRegions implements Interface.
func (m API) GetRegions() (*fastly.RegionsResponse, error) {
return m.GetRegionsFn()
}

// GetStatsJSON implements Interface.
func (m API) GetStatsJSON(i *fastly.GetStatsInput, dst interface{}) error {
return m.GetStatsJSONFn(i, dst)
}
Loading
0