Skip to content

Commit

Permalink
chore: code grooming
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasmalkmus committed Nov 23, 2022
1 parent 0ad7db0 commit 8729f3e
Show file tree
Hide file tree
Showing 15 changed files with 1,505 additions and 469 deletions.
12 changes: 12 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ linters-settings:
allow-leading-space: false
require-explanation: true
require-specific: true

issues:
exclude-rules:
- linters:
- staticcheck
text: "SA1019: res.BlocksDeleted"
- linters:
- staticcheck
text: "SA1019: client.Datasets.QueryLegacy"
- linters:
- staticcheck
text: 'SA1019: "github.com/axiomhq/axiom-go/axiom/querylegacy"'
228 changes: 122 additions & 106 deletions go.mod

Large diffs are not rendered by default.

1,552 changes: 1,275 additions & 277 deletions go.sum

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ func New(ctx context.Context, baseURL, accessToken, orgID string, insecure bool)
options = append(options, axiom.SetURL(baseURL))
}
if accessToken != "" {
options = append(options, axiom.SetAccessToken(accessToken))
options = append(options, axiom.SetToken(accessToken))
}
if orgID != "" {
options = append(options, axiom.SetOrgID(orgID))
options = append(options, axiom.SetOrganizationID(orgID))
}

client, err := axiom.NewClient(options...)
Expand Down
12 changes: 9 additions & 3 deletions internal/client/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package client
import (
"net/url"
"strings"

"github.com/axiomhq/axiom-go/axiom"
)

// CloudURL is the Axiom Cloud URL.
const CloudURL = "https://cloud.axiom.co"

// IsCloudURL returns true if the given URL is an Axiom Cloud URL.
func IsCloudURL(s string) bool {
if s != "" && !strings.HasPrefix(s, "http://") && !strings.HasPrefix(s, "https://") {
Expand All @@ -18,10 +19,15 @@ func IsCloudURL(s string) bool {
return false
}

cu, err := url.ParseRequestURI(axiom.CloudURL)
cu, err := url.ParseRequestURI(CloudURL)
if err != nil {
return false
}

return u.Host == cu.Host
}

// IsPersonalToken returns true if the given token is a personal token.
func IsPersonalToken(token string) bool {
return strings.HasPrefix(token, "xapt-")
}
9 changes: 4 additions & 5 deletions internal/cmd/auth/auth_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/axiomhq/axiom-go/axiom"
"github.com/axiomhq/axiom-go/axiom/auth"
"github.com/pkg/browser"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -102,7 +101,7 @@ func NewLoginCmd(f *cmdutil.Factory) *cobra.Command {

cmd.Flags().BoolVar(&opts.AutoLogin, "auto-login", true, "Login through the Axiom UI")
cmd.Flags().StringVarP(&opts.Type, "type", "t", strings.ToLower(typeCloud), "Type of the deployment")
cmd.Flags().StringVarP(&opts.URL, "url", "u", axiom.CloudURL, "Url of the deployment")
cmd.Flags().StringVarP(&opts.URL, "url", "u", client.CloudURL, "Url of the deployment")
cmd.Flags().StringVarP(&opts.Alias, "alias", "a", "", "Alias of the deployment")
cmd.Flags().StringVarP(&opts.OrganizationID, "org-id", "o", "", "Organization ID")
cmd.Flags().BoolVarP(&opts.Force, "force", "f", false, "Skip the confirmation prompt")
Expand Down Expand Up @@ -140,7 +139,7 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
// 2. If Cloud mode but no URL, set the correct URL instead of asking the
// user for it.
if opts.Type == strings.ToLower(typeCloud) && opts.URL == "" {
opts.URL = axiom.CloudURL
opts.URL = client.CloudURL
} else if opts.URL == "" {
if err := survey.AskOne(&survey.Input{
Message: "What is the url of the deployment?",
Expand Down Expand Up @@ -266,7 +265,7 @@ func autoLogin(ctx context.Context, opts *loginOptions) error {
// 1. If Cloud mode but no URL, set the correct URL instead of asking the
// user for it.
if opts.Type == strings.ToLower(typeCloud) && opts.URL == "" {
opts.URL = axiom.CloudURL
opts.URL = client.CloudURL
} else if opts.URL == "" {
if err := survey.AskOne(&survey.Input{
Message: "What is the url of the deployment?",
Expand Down Expand Up @@ -409,7 +408,7 @@ func runLogin(ctx context.Context, opts *loginOptions) error {
cs := opts.IO.ColorScheme()

if user != nil {
if (client.IsCloudURL(opts.URL) || opts.Config.ForceCloud) && axiom.IsPersonalToken(opts.Token) {
if (client.IsCloudURL(opts.URL) || opts.Config.ForceCloud) && client.IsPersonalToken(opts.Token) {
organization, err := axiomClient.Organizations.Get(ctx, opts.OrganizationID)
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/auth/auth_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (

"github.com/MakeNowJust/heredoc"
"github.com/axiomhq/axiom-go/axiom"
"github.com/muesli/reflow/dedent"
"github.com/spf13/cobra"

"github.com/axiomhq/cli/internal/client"
"github.com/axiomhq/cli/internal/cmdutil"
"github.com/axiomhq/cli/pkg/utils"
)

type statusOptions struct {
Expand Down Expand Up @@ -123,7 +123,7 @@ func runStatus(ctx context.Context, opts *statusOptions) error {
fmt.Fprintf(&buf, " %s\n", line)
}
}
fmt.Fprint(opts.IO.ErrOut(), dedent.String(buf.String()))
fmt.Fprint(opts.IO.ErrOut(), utils.Dedent(buf.String()))
}

if failed {
Expand Down
53 changes: 21 additions & 32 deletions internal/cmd/ingest/ingest.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import (
"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/axiomhq/axiom-go/axiom"
"github.com/axiomhq/axiom-go/axiom/ingest"
"github.com/dustin/go-humanize"
"github.com/spf13/cobra"

"github.com/axiomhq/cli/internal/client"
"github.com/axiomhq/cli/internal/cmd/auth"
"github.com/axiomhq/cli/internal/cmdutil"
"github.com/axiomhq/cli/pkg/utils"
Expand Down Expand Up @@ -191,7 +193,7 @@ func complete(ctx context.Context, opts *options) error {
// Just fetch a list of available datasets if a Personal Access Token is
// used.
var datasetNames []string
if dep, ok := opts.Config.GetActiveDeployment(); ok && axiom.IsPersonalToken(dep.Token) {
if dep, ok := opts.Config.GetActiveDeployment(); ok && client.IsPersonalToken(dep.Token) {
client, err := opts.Client(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -234,7 +236,7 @@ func run(ctx context.Context, opts *options, flushEverySet bool) error {
defer stop()

var (
res = new(axiom.IngestStatus)
res = new(ingest.Status)
lastErr error
)
for _, filename := range opts.Filenames {
Expand Down Expand Up @@ -271,13 +273,13 @@ func run(ctx context.Context, opts *options, flushEverySet bool) error {
return cmdutil.NewFlagErrorf("--delimier/-d not valid when content type is not CSV")
}

var ingestRes *axiom.IngestStatus
var ingestRes *ingest.Status
if filename == "stdin" && typ == axiom.NDJSON {
ingestRes, err = ingestEvery(ctx, client, r, opts)
} else {
ingestRes, err = ingest(ctx, client, r, typ, opts)
ingestRes, err = ingestReader(ctx, client, r, typ, opts)
}
mergeIngestStatuses(res, ingestRes)
res.Add(ingestRes)

if err != nil && !errors.Is(err, context.Canceled) {
_ = rc.Close()
Expand Down Expand Up @@ -322,7 +324,7 @@ func run(ctx context.Context, opts *options, flushEverySet bool) error {
return lastErr
}

func ingestEvery(ctx context.Context, client *axiom.Client, r io.Reader, opts *options) (*axiom.IngestStatus, error) {
func ingestEvery(ctx context.Context, client *axiom.Client, r io.Reader, opts *options) (*ingest.Status, error) {
t := time.NewTicker(opts.FlushEvery)
defer t.Stop()

Expand All @@ -335,8 +337,8 @@ func ingestEvery(ctx context.Context, client *axiom.Client, r io.Reader, opts *o
pr, pw := io.Pipe()
readers <- pr

scanner := bufio.NewScanner(r)
// Start with a 64 byte buffer, check up until 1 MB per line.
scanner := bufio.NewScanner(r)
scanner.Buffer(make([]byte, 64), 1024*1024)
scanner.Split(splitLinesMulti)

Expand Down Expand Up @@ -389,56 +391,43 @@ func ingestEvery(ctx context.Context, client *axiom.Client, r io.Reader, opts *o
}
}()

res := new(axiom.IngestStatus)
var res ingest.Status
for r := range readers {
ingestRes, err := ingest(ctx, client, r, axiom.NDJSON, opts)
ingestRes, err := ingestReader(ctx, client, r, axiom.NDJSON, opts)
if err != nil {
return res, err
return &res, err
}
mergeIngestStatuses(res, ingestRes)
res.Add(ingestRes)
}

return res, nil
return &res, nil
}

func ingest(ctx context.Context, client *axiom.Client, r io.Reader, typ axiom.ContentType, opts *options) (*axiom.IngestStatus, error) {
func ingestReader(ctx context.Context, client *axiom.Client, r io.Reader, typ axiom.ContentType, opts *options) (*ingest.Status, error) {
// If the data to ingest is not compressed, it gets zstd compressed.
enc := opts.ContentEncoding
if enc == axiom.Identity {
var err error
if r, err = axiom.ZstdEncoder(r); err != nil {
if r, err = axiom.ZstdEncoder()(r); err != nil {
return nil, err
}
enc = axiom.Zstd
} else {
r = io.NopCloser(r)
}

res, err := client.Datasets.Ingest(ctx, opts.Dataset, r, typ, enc, axiom.IngestOptions{
TimestampField: opts.TimestampField,
TimestampFormat: opts.TimestampFormat,
CSVDelimiter: opts.Delimiter,
})
res, err := client.Datasets.Ingest(ctx, opts.Dataset, r, typ, enc,
ingest.SetTimestampField(opts.TimestampField),
ingest.SetTimestampFormat(opts.TimestampFormat),
ingest.SetCSVDelimiter(opts.Delimiter),
)
if err != nil {
return nil, err
}

return res, nil
}

func mergeIngestStatuses(base, add *axiom.IngestStatus) {
if base == nil || add == nil {
return
}

base.Ingested += add.Ingested
base.Failed += add.Failed
base.Failures = append(base.Failures, add.Failures...)
base.ProcessedBytes += add.ProcessedBytes
base.BlocksCreated += add.BlocksCreated
base.WALLength += add.WALLength
}

// splitLinesMulti is like bufio.SplitLines, but returns multiple lines
// including the newline char.
func splitLinesMulti(data []byte, atEOF bool) (advance int, token []byte, err error) {
Expand Down
37 changes: 11 additions & 26 deletions internal/cmd/query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/araddon/dateparse"
"github.com/axiomhq/axiom-go/axiom/apl"
"github.com/axiomhq/axiom-go/axiom/query"
"github.com/nwidger/jsoncolor"
"github.com/spf13/cobra"

Expand All @@ -34,10 +34,6 @@ type options struct {
TimestampFormat string
// Format to output data in. Defaults to tabular output.
Format string
// NoCache disables cache usage for the query.
NoCache bool
// Save the query on the server.
Save bool

startTime time.Time
endTime time.Time
Expand All @@ -50,7 +46,7 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command {
}

cmd := &cobra.Command{
Use: "query [<apl-query>] [(-f|--format)=json|table] [--start-time <start-time>] [--end-time <end-time>] [--timestamp-format <timestamp-format>] [-c|--no-cache] [-s|--save]",
Use: "query [<apl-query>] [(-f|--format)=json|table] [--start-time <start-time>] [--end-time <end-time>] [--timestamp-format <timestamp-format>]",
Short: "Query data using APL",
Long: heredoc.Doc(`
Query data from an Axiom dataset using APL, the Axiom Processing
Expand All @@ -75,13 +71,8 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command {
# Query the "nginx-logs" dataset for logs with a 304 status code:
$ axiom query "['nginx-logs'] | where response == 304"
# Query all logs of the "http" dataset and save the query in the
# history. The histories entry ID is returned with the result. The
# history query can also be viewed in the web UI.
$ axiom query -s "['http']"
# Count all events in the "http" dataset with a 404 status code:
$ axiom query "['http'] | where response == 404 | count"
# Count all events in the "nginx-logs" dataset with a 404 status code:
$ axiom query "['nginx-logs'] | where response == 404 | count"
`),

Annotations: map[string]string{
Expand All @@ -106,15 +97,11 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command {
cmd.Flags().StringVar(&opts.StartTime, "start-time", "", "Start time of the query - may also be a relative time eg: -24h, -20m")
cmd.Flags().StringVar(&opts.EndTime, "end-time", "", "End time of the query - may also be a relative time eg: -24h, -20m")
cmd.Flags().StringVar(&opts.TimestampFormat, "timestamp-format", "", "Format used in the the timestamp field. Default uses a heuristic parser. Must be expressed using the reference time 'Mon Jan 2 15:04:05 -0700 MST 2006'")
cmd.Flags().BoolVarP(&opts.NoCache, "no-cache", "c", false, "Disable cache usage")
cmd.Flags().BoolVarP(&opts.Save, "save", "s", false, "Save query on the server side")

_ = cmd.RegisterFlagCompletionFunc("format", cmdutil.FormatCompletion)
_ = cmd.RegisterFlagCompletionFunc("start-time", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("end-time", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("timestamp-format", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("no-cache", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("save", cmdutil.NoCompletion)

return cmd
}
Expand Down Expand Up @@ -168,12 +155,10 @@ func run(ctx context.Context, opts *options) error {
progStop := opts.IO.StartActivityIndicator()
defer progStop()

res, err := client.Datasets.APLQuery(ctx, apl.Query(opts.Query), apl.Options{
StartTime: opts.startTime,
EndTime: opts.endTime,
NoCache: opts.NoCache,
Save: opts.Save,
})
res, err := client.Datasets.Query(ctx, opts.Query,
query.SetStartTime(opts.startTime),
query.SetEndTime(opts.endTime),
)
if err != nil {
return err
} else if len(res.Matches) == 0 && len(res.Buckets.Totals) == 0 {
Expand Down Expand Up @@ -210,7 +195,7 @@ func run(ctx context.Context, opts *options) error {
if res.SavedQueryID != "" {
headerText += fmt.Sprintf(" (saved as %s)", cs.Bold(res.SavedQueryID))
}
headerText += cs.Gray(fmt.Sprintf(" processed in %s", res.Status.ElapsedTime))
headerText += fmt.Sprintf(" processed in %s", cs.Gray(res.Status.ElapsedTime.String()))
headerText = fmt.Sprintf("Result of query %s:\n\n", headerText)

// Deal with table output format for matches.
Expand Down Expand Up @@ -267,7 +252,7 @@ func run(ctx context.Context, opts *options) error {
// aggregated totals as rows.
var (
header iofmt.HeaderBuilderFunc
columnNames = res.Request.GroupBy
columnNames = res.GroupBy
)
if opts.IO.IsStdoutTTY() {
header = func(w io.Writer, trb iofmt.TableRowBuilder) {
Expand All @@ -284,7 +269,7 @@ func run(ctx context.Context, opts *options) error {
aggValue, _ := json.Marshal(total.Aggregations[0].Value)

for _, name := range columnNames {
trb.AddField(total.Group[name].(string), nil)
trb.AddField(fmt.Sprint(total.Group[name]), nil)
}
trb.AddField(string(aggValue), nil)
}
Expand Down
Loading

0 comments on commit 8729f3e

Please sign in to comment.