diff --git a/.mise.toml b/.mise.toml index 5510561..d486777 100644 --- a/.mise.toml +++ b/.mise.toml @@ -10,6 +10,8 @@ LGFLAGS="-extldflags '-static'" SKPR_API="localhost:50051?insecure=true" SKPR_SSH="localhost:2222" SKPR_PROJECT="drupal" +SKPR_USERNAME="local" +SKPR_PASSWORD="local" [tasks.vendor] description = "Vendor resets the main module's vendor directory to include all packages needed to build the application" diff --git a/cmd/skpr/events/command.go b/cmd/skpr/events/command.go new file mode 100644 index 0000000..c2a59cb --- /dev/null +++ b/cmd/skpr/events/command.go @@ -0,0 +1,37 @@ +package events + +import ( + "github.com/spf13/cobra" + + skprcommand "github.com/skpr/cli/internal/command" + v1events "github.com/skpr/cli/internal/command/events" +) + +var ( + cmdLong = `List events for a specific environment.` + + cmdExample = ` + # List events for the dev environment + skpr events dev` +) + +// NewCommand creates a new cobra.Command for 'events' sub command +func NewCommand() *cobra.Command { + command := v1events.Command{} + + cmd := &cobra.Command{ + Use: "events ", + Args: cobra.MatchAll(cobra.ExactArgs(1)), + DisableFlagsInUseLine: true, + Short: "List events for an environment", + Long: cmdLong, + Example: cmdExample, + GroupID: skprcommand.GroupDebug, + RunE: func(cmd *cobra.Command, args []string) error { + command.Environment = args[0] + return command.Run(cmd.Context()) + }, + } + + return cmd +} diff --git a/cmd/skpr/main.go b/cmd/skpr/main.go index 72485b8..d3e5d20 100644 --- a/cmd/skpr/main.go +++ b/cmd/skpr/main.go @@ -20,6 +20,7 @@ import ( "github.com/skpr/cli/cmd/skpr/dashboard" deletecmd "github.com/skpr/cli/cmd/skpr/delete" "github.com/skpr/cli/cmd/skpr/deploy" + eventscmd "github.com/skpr/cli/cmd/skpr/events" execcmd "github.com/skpr/cli/cmd/skpr/exec" "github.com/skpr/cli/cmd/skpr/filesystem" "github.com/skpr/cli/cmd/skpr/info" @@ -90,6 +91,7 @@ func main() { cmd.AddCommand(dashboard.NewCommand()) cmd.AddCommand(deploy.NewCommand()) cmd.AddCommand(deletecmd.NewCommand()) + cmd.AddCommand(eventscmd.NewCommand()) cmd.AddCommand(execcmd.NewCommand()) cmd.AddCommand(filesystem.NewCommand()) cmd.AddCommand(info.NewCommand()) diff --git a/go.mod b/go.mod index 721fb5b..a469a21 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/notaryproject/notation-go v1.3.2 github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 github.com/pkg/errors v0.9.1 - github.com/skpr/api v1.2.0 + github.com/skpr/api v1.3.1 github.com/skpr/compass v1.7.0 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/spf13/cobra v1.10.1 @@ -120,6 +120,6 @@ require ( golang.org/x/sys v0.37.0 // indirect golang.org/x/text v0.30.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect - google.golang.org/protobuf v1.36.8 // indirect + google.golang.org/protobuf v1.36.10 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e84633b..ce98d9b 100644 --- a/go.sum +++ b/go.sum @@ -237,8 +237,8 @@ github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skpr/api v1.2.0 h1:Z+lECTWW1yeYkEbk7yVBW6cVoeEuKJWILh5Kr4CSHNU= -github.com/skpr/api v1.2.0/go.mod h1:uGWYjmTlQXp/7cuRBnUIqF8UlhqX0XkQK0sC473NAEs= +github.com/skpr/api v1.3.1 h1:SOl+xpRr7dp/86kaf0U4B/vORcPDJ63aSco3nX2AcTI= +github.com/skpr/api v1.3.1/go.mod h1:orpdYF4fvxAt3zQ5xfC3Oy33bKbAwE1hy+/wsF7+RlE= github.com/skpr/compass v1.7.0 h1:pYt+SBqeBxopQgoOtafu4s/ODdpHeza7WGJeHzbILiQ= github.com/skpr/compass v1.7.0/go.mod h1:zWfGSZLjGZ5PokG0n0FhFW3bvtP4bjS587/wlJOgT8U= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= @@ -397,8 +397,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/client/client.go b/internal/client/client.go index 8031961..49b8a48 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -166,3 +166,8 @@ func (c Client) Daemon() pb.DaemonClient { func (c Client) Trace() pb.TraceClient { return pb.NewTraceClient(c.conn) } + +// Events client operations. +func (c Client) Events() pb.EventsClient { + return pb.NewEventsClient(c.conn) +} diff --git a/internal/color/status.go b/internal/color/status.go index 7553f48..e629f7a 100644 --- a/internal/color/status.go +++ b/internal/color/status.go @@ -24,6 +24,11 @@ func ApplyColorToString(orig string) string { return gchalk.WithHex(HexGreen).Sprintf("%s", orig) case "Overridden": return gchalk.WithHex(HexYellow).Sprintf("%s", orig) + // Events. + case "Warning": + return gchalk.WithHex(HexYellow).Sprintf("%s", orig) + case "Error": + return gchalk.WithHex(HexRed).Sprintf("%s", orig) } return orig diff --git a/internal/command/events/command.go b/internal/command/events/command.go new file mode 100644 index 0000000..682348c --- /dev/null +++ b/internal/command/events/command.go @@ -0,0 +1,71 @@ +package events + +import ( + "context" + "fmt" + "io" + "os" + "sort" + "time" + + "github.com/skpr/api/pb" + + "github.com/skpr/cli/internal/client" + "github.com/skpr/cli/internal/color" + "github.com/skpr/cli/internal/table" +) + +// Command to delete the environment. +type Command struct { + Environment string +} + +// Run the command. +func (cmd *Command) Run(ctx context.Context) error { + ctx, client, err := client.New(ctx) + if err != nil { + return err + } + + list, err := client.Events().List(ctx, &pb.EventsListRequest{ + Environment: cmd.Environment, + }) + if err != nil { + return err + } + + return Print(os.Stdout, list.Events) +} + +// Print the table... +func Print(w io.Writer, list []*pb.Event) error { + if len(list) == 0 { + fmt.Fprintln(w, "No events found") + return nil + } + + // Sort by date descending + sort.SliceStable(list, func(i, j int) bool { + return list[i].Timestamp.AsTime().After(list[j].Timestamp.AsTime()) + }) + + header := []string{ + "Date", + "Severity", + "Type", + "Message", + } + + var rows [][]string + + for _, item := range list { + rows = append(rows, []string{ + item.Timestamp.AsTime().Local().Format(time.RFC1123), + color.ApplyColorToString(item.Severity.String()), + item.Type, + item.Message, + }) + } + + return table.Print(w, header, rows) +} diff --git a/internal/command/trace/command.go b/internal/command/trace/command.go index 1ac6ba5..0b326c6 100644 --- a/internal/command/trace/command.go +++ b/internal/command/trace/command.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "time" tea "github.com/charmbracelet/bubbletea" "github.com/skpr/api/pb" @@ -70,20 +69,20 @@ func (cmd *Command) Run(ctx context.Context) error { for _, f := range t.FunctionCalls { fcalls = append(fcalls, trace.FunctionCall{ Name: f.Name, - StartTime: f.StartTime, - Elapsed: f.ElapsedTime, + StartTime: int64(f.StartTime.Nanos), + Elapsed: int64(f.Elapsed.Nanos), }) } p.Send(events.Trace{ - IngestionTime: time.Unix(t.Metadata.StartTime, 0), + IngestionTime: t.Metadata.StartTime.AsTime(), Trace: trace.Trace{ Metadata: trace.Metadata{ RequestID: t.Metadata.RequestId, URI: t.Metadata.Uri, Method: t.Metadata.Method, - StartTime: t.Metadata.StartTime, - EndTime: t.Metadata.EndTime, + StartTime: int64(t.Metadata.StartTime.Nanos), + EndTime: int64(t.Metadata.EndTime.Nanos), }, FunctionCalls: fcalls, },