(ctx context.Context, argsJSON string, deps ToolDeps)
| 23 | } |
| 24 | |
| 25 | func executeFetchContainerLogs(ctx context.Context, argsJSON string, deps ToolDeps) (*pb.CallToolResponse, error) { |
| 26 | var args fetchLogsArgs |
| 27 | if err := json.Unmarshal([]byte(argsJSON), &args); err != nil { |
| 28 | return nil, fmt.Errorf("failed to parse arguments: %w", err) |
| 29 | } |
| 30 | hostID, containerID, note, err := resolveContainerRefRead(args.ContainerID, args.Host, deps) |
| 31 | if err != nil { |
| 32 | return nil, err |
| 33 | } |
| 34 | |
| 35 | cs, err := deps.HostService.FindContainer(hostID, containerID, deps.Labels) |
| 36 | if err != nil { |
| 37 | return nil, fmt.Errorf("container not found: %w", err) |
| 38 | } |
| 39 | |
| 40 | start := time.Now().Add(-1 * time.Hour) |
| 41 | end := time.Now() |
| 42 | if args.Start != "" { |
| 43 | t, err := time.Parse(time.RFC3339, args.Start) |
| 44 | if err != nil { |
| 45 | return nil, fmt.Errorf("invalid start time format (expected RFC3339): %w", err) |
| 46 | } |
| 47 | start = t |
| 48 | } |
| 49 | if args.End != "" { |
| 50 | t, err := time.Parse(time.RFC3339, args.End) |
| 51 | if err != nil { |
| 52 | return nil, fmt.Errorf("invalid end time format (expected RFC3339): %w", err) |
| 53 | } |
| 54 | end = t |
| 55 | } |
| 56 | |
| 57 | var re *regexp.Regexp |
| 58 | if args.Regex != "" { |
| 59 | var err error |
| 60 | re, err = regexp.Compile(args.Regex) |
| 61 | if err != nil { |
| 62 | return nil, fmt.Errorf("invalid regex pattern: %w", err) |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | ctx, cancel := context.WithCancel(ctx) |
| 67 | defer cancel() |
| 68 | |
| 69 | logCh, err := cs.LogsBetweenDates(ctx, start, end, container.STDOUT|container.STDERR) |
| 70 | if err != nil { |
| 71 | return nil, fmt.Errorf("failed to fetch logs: %w", err) |
| 72 | } |
| 73 | |
| 74 | const maxLines = 100 |
| 75 | entries := make([]*pb.LogEntry, 0, maxLines) |
| 76 | for event := range logCh { |
| 77 | msg, matches := matchesFilters(event, &args, re) |
| 78 | if !matches { |
| 79 | continue |
| 80 | } |
| 81 | |
| 82 | entries = append(entries, &pb.LogEntry{ |
no test coverage detected