diff --git a/src/pkg/cli/client/byoc/aws/byoc.go b/src/pkg/cli/client/byoc/aws/byoc.go index be5f7de4d..d9e57c38c 100644 --- a/src/pkg/cli/client/byoc/aws/byoc.go +++ b/src/pkg/cli/client/byoc/aws/byoc.go @@ -10,7 +10,6 @@ import ( "io" "iter" "os" - "slices" "strconv" "strings" "sync" @@ -677,93 +676,6 @@ func (b *ByocAws) CreateUploadURL(ctx context.Context, req *defangv1.UploadURLRe }, nil } -func (b *ByocAws) QueryForDebug(ctx context.Context, req *defangv1.DebugRequest) error { - // tailRequest := &defangv1.TailRequest{ - // Etag: req.Etag, - // Project: req.Project, - // Services: req.Services, - // Since: req.Since, - // Until: req.Until, - // } - - // The LogStreamNamePrefix filter can only be used with one service name - var service string - if len(req.Services) == 1 { - service = req.Services[0] - } - - start := b.cdStart // TODO: get start time from req.Etag - if req.Since.IsValid() { - start = req.Since.AsTime() - } else if start.IsZero() { - start = time.Now().Add(-time.Hour) - } - - end := time.Now() - if req.Until.IsValid() { - end = req.Until.AsTime() - } - - // get stack information (for CD log group ARN) - err := b.driver.FillOutputs(ctx) - if err != nil { - return AnnotateAwsError(err) - } - - cwClient, err := cw.NewCloudWatchLogsClient(ctx, b.driver.Region) // assume all log groups are in the same region - if err != nil { - return err - } - - // Gather logs from the CD task, builds, ECS events, and all services - evtsChan, errsChan := cw.QueryLogGroups(ctx, cwClient, start, end, 0, b.getLogGroupInputs(req.Etag, req.Project, service, "", logs.LogTypeAll)...) - if evtsChan == nil { - return <-errsChan // TODO: there could be multiple errors - } - - const maxQuerySizePerLogGroup = 128 * 1024 // 128KB per LogGroup (to stay well below the 1MB gRPC payload limit) - - sb := strings.Builder{} -loop: - for { - select { - case event, ok := <-evtsChan: - if !ok { - break loop - } - parseECSEventRecords := strings.HasSuffix(*event.LogGroupIdentifier, "/ecs") - if parseECSEventRecords { - if event, err := ecs.ParseECSEvent([]byte(*event.Message)); err == nil { - // TODO: once we know the AWS deploymentId from TaskStateChangeEvent detail.startedBy, we can do a 2nd query to filter by deploymentId - if event.Etag() != "" && req.Etag != "" && event.Etag() != req.Etag { - continue - } - if event.Service() != "" && len(req.Services) > 0 && !slices.Contains(req.Services, event.Service()) { - continue - } - // This matches the status messages in the Defang Playground Loki logs - sb.WriteString("status=") - sb.WriteString(event.Status()) - sb.WriteByte('\n') - continue - } - } - msg := term.StripAnsi(*event.Message) - sb.WriteString(msg) - sb.WriteByte('\n') - if sb.Len() > maxQuerySizePerLogGroup { // FIXME: this limit was supposed to be per LogGroup - term.Warn("Query result was truncated") - break loop - } - case err := <-errsChan: - term.Warn("CloudWatch query error:", AnnotateAwsError(err)) - // continue reading other log groups - } - } - req.Logs = sb.String() - return nil -} - func (b *ByocAws) QueryLogs(ctx context.Context, req *defangv1.TailRequest) (client.ServerStream[defangv1.TailResponse], error) { // FillOutputs is needed to get the CD task ARN or the LogGroup ARNs // if the cloud formation stack has been destroyed, we can still query diff --git a/src/pkg/cli/client/byoc/do/byoc.go b/src/pkg/cli/client/byoc/do/byoc.go index 886446a3e..7a1f5cb42 100644 --- a/src/pkg/cli/client/byoc/do/byoc.go +++ b/src/pkg/cli/client/byoc/do/byoc.go @@ -596,10 +596,6 @@ func (s *subscribeStream) Close() error { return nil } -func (b *ByocDo) QueryForDebug(ctx context.Context, req *defangv1.DebugRequest) error { - return client.ErrNotImplemented("AI debugging is not yet supported for DO BYOC") -} - func (b *ByocDo) PrepareDomainDelegation(ctx context.Context, req client.PrepareDomainDelegationRequest) (*client.PrepareDomainDelegationResponse, error) { return nil, nil // TODO: implement domain delegation for DO } diff --git a/src/pkg/cli/client/byoc/gcp/byoc.go b/src/pkg/cli/client/byoc/gcp/byoc.go index c6ae5c95d..7f62878eb 100644 --- a/src/pkg/cli/client/byoc/gcp/byoc.go +++ b/src/pkg/cli/client/byoc/gcp/byoc.go @@ -6,7 +6,6 @@ import ( "encoding/base64" "errors" "fmt" - "io" "iter" "os" "path" @@ -742,30 +741,6 @@ func (b *ByocGcp) PutConfig(ctx context.Context, req *defangv1.PutConfigRequest) return nil } -func (b *ByocGcp) createDeploymentLogQuery(req *defangv1.DebugRequest) string { - var since, until time.Time - if req.Since.IsValid() { - since = req.Since.AsTime() - } - if req.Until.IsValid() { - until = req.Until.AsTime() - } - query := NewLogQuery(b.driver.GetProjectID()) - query.AddSince(since) - query.AddUntil(until) - - // Logs - query.AddCloudBuildLogQuery(b.PulumiStack, req.Project, req.Etag, req.Services) // CloudBuild logs for CD and image builds - query.AddServiceLogQuery(b.PulumiStack, req.Project, req.Etag, req.Services) // Cloudrun service logs - query.AddComputeEngineLogQuery(b.PulumiStack, req.Project, req.Etag, req.Services) // Compute Engine logs - // Status Updates - query.AddServiceStatusRequestUpdate(b.PulumiStack, req.Project, req.Etag, req.Services) - query.AddServiceStatusReponseUpdate(b.PulumiStack, req.Project, req.Etag, req.Services) - query.AddComputeEngineInstanceGroupInsertOrPatch(b.PulumiStack, req.Project, req.Etag, req.Services) - - return query.GetQuery() -} - func LogEntryToString(logEntry *loggingpb.LogEntry) (string, string, error) { result := "" emptySpace := strings.Repeat(" ", len(time.RFC3339)+1) // length of what a time stampe would be @@ -810,39 +785,6 @@ func LogEntriesToString(logEntries []*loggingpb.LogEntry) string { return result.String() } -func (b *ByocGcp) query(ctx context.Context, query string) ([]*loggingpb.LogEntry, error) { - term.Debugf("Querying logs with filter: \n %s", query) - var entries []*loggingpb.LogEntry - lister, err := b.driver.ListLogEntries(ctx, query, gcp.OrderAscending) - if err != nil { - return nil, err - } - - for { - entry, err := lister.Next() - if errors.Is(err, io.EOF) { - break - } - if err != nil { - return nil, err - } - entries = append(entries, entry) - } - - return entries, nil -} - -func (b *ByocGcp) QueryForDebug(ctx context.Context, req *defangv1.DebugRequest) error { - logEntries, err := b.query(ctx, b.createDeploymentLogQuery(req)) - if err != nil { - return annotateGcpError(err) - } - req.Logs = LogEntriesToString(logEntries) - term.Debug(req.Logs) - - return nil -} - func (b *ByocGcp) TearDownCD(ctx context.Context) error { // FIXME: implement return client.ErrNotImplemented("GCP TearDown") diff --git a/src/pkg/cli/client/playground.go b/src/pkg/cli/client/playground.go index b0cd5c7a7..8b161bfd9 100644 --- a/src/pkg/cli/client/playground.go +++ b/src/pkg/cli/client/playground.go @@ -149,10 +149,6 @@ func (g *PlaygroundProvider) AccountInfo(ctx context.Context) (*AccountInfo, err }, nil } -func (g *PlaygroundProvider) QueryForDebug(ctx context.Context, req *defangv1.DebugRequest) error { - return nil -} - func (g *PlaygroundProvider) PrepareDomainDelegation(ctx context.Context, req PrepareDomainDelegationRequest) (*PrepareDomainDelegationResponse, error) { return nil, nil // Playground does not support delegate domains } diff --git a/src/pkg/cli/client/provider.go b/src/pkg/cli/client/provider.go index 59e239638..55ddeb36e 100644 --- a/src/pkg/cli/client/provider.go +++ b/src/pkg/cli/client/provider.go @@ -81,7 +81,6 @@ type Provider interface { PrepareDomainDelegation(context.Context, PrepareDomainDelegationRequest) (*PrepareDomainDelegationResponse, error) Preview(context.Context, *DeployRequest) (*defangv1.DeployResponse, error) PutConfig(context.Context, *defangv1.PutConfigRequest) error - QueryForDebug(context.Context, *defangv1.DebugRequest) error QueryLogs(context.Context, *defangv1.TailRequest) (ServerStream[defangv1.TailResponse], error) RemoteProjectName(context.Context) (string, error) SetCanIUseConfig(*defangv1.CanIUseResponse)