未验证 提交 b6b0c00c 编写于 作者: U Utsav Oza 提交者: GitHub

Merge pull request #119 from palash25/analytics-switch

app command: Add anayltics switch
package app
import (
"encoding/json"
"fmt"
"io"
"os"
"github.com/appbaseio/abc/appbase/common"
"github.com/olekukonko/tablewriter"
)
type analyticsResults struct {
Count json.Number `json:"count"`
Key string `json:"key"`
}
type analyticsVolumeResults struct {
Count json.Number `json:"count"`
Key json.Number `json:"key"`
DateAsStr string `json:"key_as_string"`
}
type overviewAnalyticsBody struct {
NoResultSearches []analyticsResults `json:"noResultSearches"`
PopularSearches []analyticsResults `json:"popularSearches"`
SearchVolume []analyticsVolumeResults `json:"searchVolume"`
}
//ShowOverview .......
func ShowOverview(body io.ReadCloser) error {
var res overviewAnalyticsBody
dec := json.NewDecoder(body)
err := dec.Decode(&res)
if err != nil {
fmt.Println(err)
return err
}
// Display the overview results
fmt.Println("Analytics(Overview) Results:")
// Display NoResultSearches results
noResultTable := tablewriter.NewWriter(os.Stdout)
noResultTable.SetHeader([]string{"Count", "Key"})
for _, elements := range res.NoResultSearches {
noResultTable.Append([]string{common.JSONNumberToString(elements.Count), elements.Key})
}
noResultTable.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("No Result Searches")
noResultTable.Render()
// Display PopularSearches results
popularSearchesTable := tablewriter.NewWriter(os.Stdout)
popularSearchesTable.SetHeader([]string{"Count", "Key"})
for _, elements := range res.PopularSearches {
popularSearchesTable.Append([]string{common.JSONNumberToString(elements.Count), elements.Key})
}
popularSearchesTable.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("No Result Searches")
popularSearchesTable.Render()
// Display SearcheVolume results
searchVolumeTable := tablewriter.NewWriter(os.Stdout)
searchVolumeTable.SetHeader([]string{"Count", "Key", "Date-As-Str"})
for _, elements := range res.SearchVolume {
searchVolumeTable.Append([]string{common.JSONNumberToString(elements.Count), common.JSONNumberToString(elements.Key), elements.DateAsStr})
}
searchVolumeTable.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("Search Volume Results")
searchVolumeTable.Render()
return nil
}
type latencyResults struct {
Count json.Number `json:"count"`
Key json.Number `json:"key"`
}
type latency struct {
Latency []latencyResults `json:"latency"`
}
//ShowLatency .......
func ShowLatency(body io.ReadCloser) error {
var res latency
dec := json.NewDecoder(body)
err := dec.Decode(&res)
if err != nil {
fmt.Println(err)
return err
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Count", "Key"})
for _, elements := range res.Latency {
table.Append([]string{common.JSONNumberToString(elements.Count), common.JSONNumberToString(elements.Key)})
}
table.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("Analytics(Latency) Results:")
table.Render()
return nil
}
type geoIP struct {
GeoIP []analyticsResults `json:"aggrByCountry"`
}
//ShowGeoIP .......
func ShowGeoIP(body io.ReadCloser) error {
var res geoIP
dec := json.NewDecoder(body)
err := dec.Decode(&res)
if err != nil {
fmt.Println(err)
return err
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Count", "Key"})
for _, elements := range res.GeoIP {
table.Append([]string{common.JSONNumberToString(elements.Count), elements.Key})
}
table.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("Analytics(GeoIP) Results:")
table.Render()
return nil
}
type analyticsPopularResults struct {
Count json.Number `json:"count"`
Key string `json:"key"`
Source string `json:"source"`
}
type popularResults struct {
PopularResults []analyticsPopularResults `json:"popularResults"`
}
//ShowPopularResults .......
func ShowPopularResults(body io.ReadCloser) error {
var res popularResults
dec := json.NewDecoder(body)
err := dec.Decode(&res)
if err != nil {
fmt.Println(err)
return err
}
// TODO refine output
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Count", "Key", "Source"})
for _, elements := range res.PopularResults {
table.Append([]string{common.JSONNumberToString(elements.Count), elements.Key, elements.Source})
}
table.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("Analytics(Popular) Results:")
table.Render()
return nil
}
type popularSearches struct {
Results []analyticsResults `json:"popularSearches"`
}
//ShowPopularSearches .......
func ShowPopularSearches(body io.ReadCloser) error {
var res popularSearches
dec := json.NewDecoder(body)
err := dec.Decode(&res)
if err != nil {
fmt.Println(err)
return err
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Count", "Key"})
for _, elements := range res.Results {
table.Append([]string{common.JSONNumberToString(elements.Count), elements.Key})
}
table.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("Analytics Popular Searches:")
table.Render()
return nil
}
type noResultSearches struct {
Results []analyticsResults `json:"noResultSearches"`
}
//ShowNoResultSearches .......
func ShowNoResultSearches(body io.ReadCloser) error {
var res noResultSearches
dec := json.NewDecoder(body)
err := dec.Decode(&res)
if err != nil {
fmt.Println(err)
return err
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Count", "Key"})
for _, elements := range res.Results {
table.Append([]string{common.JSONNumberToString(elements.Count), elements.Key})
}
table.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("Analytics No Result Searches:")
table.Render()
return nil
}
type analyticsPopularFilters struct {
Count json.Number `json:"count"`
Key string `json:"key"`
Value string `json:"value"`
}
type popularFilters struct {
Results []analyticsPopularFilters `json:"popularFilters"`
}
//ShowPopularFilters .......
func ShowPopularFilters(body io.ReadCloser) error {
var res popularFilters
dec := json.NewDecoder(body)
err := dec.Decode(&res)
if err != nil {
fmt.Println(err)
return err
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Count", "Key", "Value"})
for _, elements := range res.Results {
table.Append([]string{common.JSONNumberToString(elements.Count), elements.Key, elements.Value})
}
table.SetAlignment(tablewriter.ALIGN_CENTER)
fmt.Println("Analytics Popular Filters:")
table.Render()
return nil
}
......@@ -3,14 +3,15 @@ package app
import (
"encoding/json"
"fmt"
"github.com/appbaseio/abc/appbase/common"
"github.com/appbaseio/abc/appbase/session"
"github.com/appbaseio/abc/appbase/spinner"
"github.com/olekukonko/tablewriter"
"net/http"
"os"
"strconv"
"time"
"github.com/appbaseio/abc/appbase/common"
"github.com/appbaseio/abc/appbase/session"
"github.com/appbaseio/abc/appbase/spinner"
"github.com/olekukonko/tablewriter"
)
// Permission represents an app permission object
......@@ -95,6 +96,42 @@ func ShowAppMetrics(app string) error {
return nil
}
// ShowAppAnalytics fetches analytics for an app
func ShowAppAnalytics(app string, endpoint string) error {
spinner.StartText("Fetching app analytics")
defer spinner.Stop()
// show analytics
fmt.Println()
req, err := http.NewRequest("GET", common.AccAPIURL+"/analytics/"+app+"/"+endpoint, nil)
if err != nil {
return err
}
resp, err := session.SendRequest(req)
if err != nil {
return err
}
spinner.Stop()
switch endpoint {
case "latency":
ShowLatency(resp.Body)
case "geoip":
ShowGeoIP(resp.Body)
case "overview":
ShowOverview(resp.Body)
case "popularresults":
ShowPopularResults(resp.Body)
case "popularsearches":
ShowPopularSearches(resp.Body)
case "popularfilters":
ShowPopularFilters(resp.Body)
case "noresultsearches":
ShowNoResultSearches(resp.Body)
}
return nil
}
// ShowAppPerms ...
func ShowAppPerms(app string) error {
spinner.StartText("Fetching app credentials")
......
......@@ -2,6 +2,7 @@ package main
import (
"fmt"
"github.com/appbaseio/abc/appbase/app"
"github.com/appbaseio/abc/appbase/common"
)
......@@ -32,8 +33,10 @@ func runApps(args []string) error {
// runApp runs `app` command
func runApp(args []string) error {
flagset := baseFlagSet("app")
basicUsage := "abc app [-c|--creds] [-m|--metrics] [--data-view] [ID|Appname]"
basicUsage := "abc app [-c|--creds] [-m|--metrics] [--data-view] [-a| --analytics] [ID|Appname]"
flagset.Usage = usageFor(flagset, basicUsage)
analytics := flagset.BoolP("analytics", "a", false, "show app analytics")
analyticsEndpoint := flagset.String("endpoint", "overview", "the analytics endpoint to be queried")
creds := flagset.BoolP("creds", "c", false, "show app credentials")
metrics := flagset.BoolP("metrics", "m", false, "show app metrics")
dataView := flagset.Bool("data-view", false, "open app data view using Dejavu")
......@@ -48,6 +51,8 @@ func runApp(args []string) error {
return app.OpenAppDataView(args[0])
} else if *queryView {
return app.OpenAppQueryView(args[0])
} else if *analytics {
return app.ShowAppAnalytics(args[0], *analyticsEndpoint)
}
return app.ShowAppDetails(args[0], *creds, *metrics)
}
......
......@@ -19,7 +19,7 @@ The above commands will only give basic details of the app such as its name, ID,
If you want more details such as credentials and metrics, you can pass in defined switches. The full version of `app` command looks like-
```sh
abc app [-c|--creds] [-m|--metrics] [ID|Appname]
abc app [-c|--creds] [-m|--metrics] [-a| --analytics] [ID|Appname]
```
#### Example
......@@ -48,3 +48,62 @@ Records: 42
```
⭐️ It shows API calls and number of records created on a per day basis (just like the graph you see on dashboard.appbase.io).
### Accessing app analytics (only for paid users)
Paid users can access analytics data for a particular app. Currently the following analytics endpoints are supported:
- overview
- noresultsearches
- popularresults
- popularsearches
- popularfilters
- geoip
- latency
#### Example
By default the command will ping the overview endpoint
```sh
> abc app -a MyCoolApp
Analytics(Overview) Results:
No Result Searches
+-------+------+
| COUNT | KEY |
+-------+------+
| 1 | blah |
| 1 | gurr |
+-------+------+
No Result Searches
+-------+--------------+
| COUNT | KEY |
+-------+--------------+
| 1 | gru |
| ... | ... |
| 1 | wonder woman |
| 1 | wonderland |
+-------+--------------+
Search Volume Results
+-------+---------------+---------------------+
| COUNT | KEY | DATE-AS-STR |
+-------+---------------+---------------------+
| 7 | 1540512000000 | 2018/10/26 00:00:00 |
+-------+---------------+---------------------+
```
To ping other analytics endpoints the `endpoint` flag can be used. For example
```sh
> abc app -a --endpoint=latency MyCoolApp
Analytics(Latency) Results:
+-------+-----+
| COUNT | KEY |
+-------+-----+
| 2 | 0 |
| .. | .. |
| 0 | 10 |
+-------+-----+
```
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册