Skip to content
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

CLI: ability to check health of all projects for support users #3725

8 changes: 4 additions & 4 deletions cli/cmd/devtool/data/cloud-deps.docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ services:
otel-collector:
image: otel/opentelemetry-collector:latest
restart: always
command: ["--config=/etc/otel-collector-config.yaml"]
command: [ "--config=/etc/otel-collector-config.yaml" ]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "1888:1888" # pprof extension
- "8889:8889" # Prometheus exporter metrics
- "1888:1888" # pprof extension
- "8889:8889" # Prometheus exporter metrics
- "13133:13133" # health_check extension
- "4317:4317" # OTLP gRPC receiver
- "4317:4317" # OTLP gRPC receiver
- "55679:55679" # zpages extension
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved
depends_on:
- zipkin
101 changes: 101 additions & 0 deletions cli/cmd/sudo/project/search.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package project

import (
"fmt"
"strings"

"github.com/rilldata/rill/cli/pkg/cmdutil"
adminv1 "github.com/rilldata/rill/proto/gen/rill/admin/v1"
runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1"
"github.com/rilldata/rill/runtime"
runtimeclient "github.com/rilldata/rill/runtime/client"
"github.com/spf13/cobra"
)

func SearchCmd(ch *cmdutil.Helper) *cobra.Command {
var pageSize uint32
var pageToken string
var tags []string
var status bool

searchCmd := &cobra.Command{
Use: "search [<pattern>]",
Expand Down Expand Up @@ -50,6 +57,89 @@ func SearchCmd(ch *cmdutil.Helper) *cobra.Command {
return err
}

if status {
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved
var table []*projectStatusTableRow
ch.Printer.Println()
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved
for _, name := range res.Names {
org := strings.Split(name, "/")[0]
project := strings.Split(name, "/")[1]

proj, err := client.GetProject(ctx, &adminv1.GetProjectRequest{
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved
OrganizationName: org,
Name: project,
})
if err != nil {
return err
}

depl := proj.ProdDeployment
if depl == nil {
continue
}

rt, err := runtimeclient.New(depl.RuntimeHost, proj.Jwt)
if err != nil {
return fmt.Errorf("failed to connect to runtime: %w", err)
}

res, err := rt.ListResources(cmd.Context(), &runtimev1.ListResourcesRequest{InstanceId: depl.RuntimeInstanceId})
if err != nil {
return fmt.Errorf("failed to list resources: %w", err)
}

var parser *runtimev1.ProjectParser
var ParserErrorCount int32
var IdleCount int32
var IdleWithErrorsCount int32
var PendingCount int32
var RunningCount int32
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved

for _, r := range res.Resources {
if r.Meta.Name.Kind == runtime.ResourceKindProjectParser {
parser = r.GetProjectParser()
}
if r.Meta.Hidden {
continue
}

switch r.Meta.ReconcileStatus {
case runtimev1.ReconcileStatus_RECONCILE_STATUS_IDLE:
// if it is idle, check if there are any errors
if r.Meta.GetReconcileError() != "" {
IdleWithErrorsCount++
} else {
IdleCount++
}
case runtimev1.ReconcileStatus_RECONCILE_STATUS_PENDING:
PendingCount++
case runtimev1.ReconcileStatus_RECONCILE_STATUS_RUNNING:
RunningCount++
}
}

// check if there are any parser errors
if parser.State != nil && len(parser.State.ParseErrors) != 0 {
ParserErrorCount++
}

table = append(table, &projectStatusTableRow{
Name: name,
Organization: org,
IdelCount: IdleCount,
IdelWithErrorsCount: IdleWithErrorsCount,
PendingCount: PendingCount,
RunningCount: RunningCount,
ParserErrorCount: ParserErrorCount,
})
}

ch.Printer.PrintlnSuccess("\nProject status\n")
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved
err = ch.Printer.PrintResource(table)
if err != nil {
return err
}
}

if res.NextPageToken != "" {
cmd.Println()
cmd.Printf("Next page token: %s\n", res.NextPageToken)
Expand All @@ -58,9 +148,20 @@ func SearchCmd(ch *cmdutil.Helper) *cobra.Command {
return nil
},
}
searchCmd.Flags().BoolVar(&status, "status", false, "Include project status")
searchCmd.Flags().StringSliceVar(&tags, "tag", []string{}, "Tags to filter projects by")
searchCmd.Flags().Uint32Var(&pageSize, "page-size", 50, "Number of projects to return per page")
searchCmd.Flags().StringVar(&pageToken, "page-token", "", "Pagination token")

return searchCmd
}

type projectStatusTableRow struct {
Name string `header:"name"`
Organization string `header:"organization"`
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved
IdelCount int32 `header:"idle"`
IdelWithErrorsCount int32 `header:"idle with errors"`
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved
PendingCount int32 `header:"pending"`
RunningCount int32 `header:"running"`
ParserErrorCount int32 `header:"parser error"`
rakeshsharma14317 marked this conversation as resolved.
Show resolved Hide resolved
}