| OLD | NEW |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package cli | 5 package cli |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "io" | 8 "io" |
| 9 "os" | 9 "os" |
| 10 | 10 |
| 11 "github.com/luci/luci-go/common/clock" | 11 "github.com/luci/luci-go/common/clock" |
| 12 "github.com/luci/luci-go/common/errors" |
| 12 log "github.com/luci/luci-go/common/logging" | 13 log "github.com/luci/luci-go/common/logging" |
| 13 "github.com/luci/luci-go/logdog/api/logpb" | 14 "github.com/luci/luci-go/logdog/api/logpb" |
| 14 "github.com/luci/luci-go/logdog/client/coordinator" | 15 "github.com/luci/luci-go/logdog/client/coordinator" |
| 15 "github.com/luci/luci-go/logdog/common/renderer" | 16 "github.com/luci/luci-go/logdog/common/renderer" |
| 16 "github.com/luci/luci-go/logdog/common/types" | 17 "github.com/luci/luci-go/logdog/common/types" |
| 17 | 18 |
| 18 "github.com/maruel/subcommands" | 19 "github.com/maruel/subcommands" |
| 19 "golang.org/x/net/context" | 20 "golang.org/x/net/context" |
| 20 ) | 21 ) |
| 21 | 22 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 43 | 44 |
| 44 func (cmd *latestCommandRun) Run(scApp subcommands.Application, args []string, _
subcommands.Env) int { | 45 func (cmd *latestCommandRun) Run(scApp subcommands.Application, args []string, _
subcommands.Env) int { |
| 45 a := scApp.(*application) | 46 a := scApp.(*application) |
| 46 | 47 |
| 47 // User-friendly: trim any leading or trailing slashes from the path. | 48 // User-friendly: trim any leading or trailing slashes from the path. |
| 48 if len(args) != 1 { | 49 if len(args) != 1 { |
| 49 log.Errorf(a, "Exactly one argument, the stream path, must be su
pplied.") | 50 log.Errorf(a, "Exactly one argument, the stream path, must be su
pplied.") |
| 50 return 1 | 51 return 1 |
| 51 } | 52 } |
| 52 | 53 |
| 53 » project, path, _, err := a.splitPath(args[0]) | 54 » var addr *types.StreamAddr |
| 55 » var err error |
| 56 » if addr, err = types.ParseURL(args[0]); err != nil { |
| 57 » » // Not a log stream address. |
| 58 » » project, path, _, err := a.splitPath(args[0]) |
| 59 » » if err != nil { |
| 60 » » » log.WithError(err).Errorf(a, "Invalid path specifier.") |
| 61 » » » return 1 |
| 62 » » } |
| 63 |
| 64 » » addr = &types.StreamAddr{Project: project, Path: types.StreamPat
h(path)} |
| 65 » » if err := addr.Path.Validate(); err != nil { |
| 66 » » » log.Fields{ |
| 67 » » » » log.ErrorKey: err, |
| 68 » » » » "project": addr.Project, |
| 69 » » » » "path": addr.Path, |
| 70 » » » }.Errorf(a, "Invalid command-line stream path.") |
| 71 » » » return 1 |
| 72 » » } |
| 73 » } |
| 74 |
| 75 » coord, err := a.coordinatorClient(addr.Host) |
| 54 if err != nil { | 76 if err != nil { |
| 55 » » log.WithError(err).Errorf(a, "Invalid path specifier.") | 77 » » errors.Log(a, errors.Annotate(err).Reason("failed to create Coor
dinator client").Err()) |
| 56 return 1 | 78 return 1 |
| 57 } | 79 } |
| 58 | 80 |
| 59 » sp := streamPath{project, types.StreamPath(path)} | 81 » stream := coord.Stream(addr.Project, addr.Path) |
| 60 » if err := sp.path.Validate(); err != nil { | |
| 61 » » log.Fields{ | |
| 62 » » » log.ErrorKey: err, | |
| 63 » » » "project": sp.project, | |
| 64 » » » "path": sp.path, | |
| 65 » » }.Errorf(a, "Invalid command-line stream path.") | |
| 66 » » return 1 | |
| 67 » } | |
| 68 | |
| 69 » stream := a.coord.Stream(sp.project, sp.path) | |
| 70 | 82 |
| 71 tctx, _ := a.timeoutCtx(a) | 83 tctx, _ := a.timeoutCtx(a) |
| 72 le, st, err := cmd.getTailEntry(tctx, stream) | 84 le, st, err := cmd.getTailEntry(tctx, stream) |
| 73 if err != nil { | 85 if err != nil { |
| 74 log.Fields{ | 86 log.Fields{ |
| 75 log.ErrorKey: err, | 87 log.ErrorKey: err, |
| 76 » » » "project": sp.project, | 88 » » » "project": addr.Project, |
| 77 » » » "path": sp.path, | 89 » » » "path": addr.Path, |
| 78 }.Errorf(a, "Failed to load latest record.") | 90 }.Errorf(a, "Failed to load latest record.") |
| 79 | 91 |
| 80 if err == context.DeadlineExceeded { | 92 if err == context.DeadlineExceeded { |
| 81 return 2 | 93 return 2 |
| 82 } | 94 } |
| 83 return 1 | 95 return 1 |
| 84 } | 96 } |
| 85 | 97 |
| 86 // Render the entry. | 98 // Render the entry. |
| 87 r := renderer.Renderer{ | 99 r := renderer.Renderer{ |
| (...skipping 26 matching lines...) Expand all Loading... |
| 114 if ar := <-clock.After(c, noStreamDelay); ar.Incomplete(
) { | 126 if ar := <-clock.After(c, noStreamDelay); ar.Incomplete(
) { |
| 115 // Timer stopped prematurely. | 127 // Timer stopped prematurely. |
| 116 return nil, nil, ar.Err | 128 return nil, nil, ar.Err |
| 117 } | 129 } |
| 118 | 130 |
| 119 default: | 131 default: |
| 120 return nil, nil, err | 132 return nil, nil, err |
| 121 } | 133 } |
| 122 } | 134 } |
| 123 } | 135 } |
| OLD | NEW |