MCPcopy Index your code
hub / github.com/coder/coder / provisionerJobLogs

Method provisionerJobLogs

coderd/provisionerjobs.go:154–211  ·  view source on GitHub ↗

Returns provisioner logs based on query parameters. The intended usage for a client to stream all logs (with JS API): GET /logs GET /logs?after= &follow The combination of these responses should provide all current logs to the consumer, and future logs are streamed in the follow request.

(rw http.ResponseWriter, r *http.Request, job database.ProvisionerJob)

Source from the content-addressed store, hash-verified

152// The combination of these responses should provide all current logs
153// to the consumer, and future logs are streamed in the follow request.
154func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job database.ProvisionerJob) {
155 var (
156 ctx = r.Context()
157 logger = api.Logger.With(slog.F("job_id", job.ID))
158 follow = r.URL.Query().Has("follow")
159 afterRaw = r.URL.Query().Get("after")
160 format = r.URL.Query().Get("format")
161 )
162
163 // Validate format parameter.
164 if format == "" {
165 format = "json"
166 }
167 if format != "json" && format != "text" {
168 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
169 Message: "Invalid format parameter.",
170 Detail: "Allowed values are \"json\" and \"text\".",
171 })
172 return
173 }
174
175 // Text format is not supported with streaming.
176 if format == "text" && follow {
177 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
178 Message: "Text format is not supported with follow mode.",
179 Detail: "Use format=json or omit the follow parameter.",
180 })
181 return
182 }
183
184 var after int64
185 // Only fetch logs created after the time provided.
186 if afterRaw != "" {
187 var err error
188 after, err = strconv.ParseInt(afterRaw, 10, 64)
189 if err != nil {
190 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
191 Message: "Query param \"after\" must be an integer.",
192 Validations: []codersdk.ValidationError{
193 {Field: "after", Detail: "Must be an integer"},
194 },
195 })
196 return
197 }
198 }
199
200 if !follow {
201 fetchAndWriteLogs(ctx, api.Database, job.ID, after, rw, format)
202 return
203 }
204
205 follower := newLogFollower(ctx, logger, api.Database, api.Pubsub, rw, r, job, after)
206 api.WebsocketWaitMutex.Lock()
207 api.WebsocketWaitGroup.Add(1)
208 api.WebsocketWaitMutex.Unlock()
209 defer api.WebsocketWaitGroup.Done()
210 follower.follow()
211}

Callers 3

templateVersionLogsMethod · 0.95
workspaceBuildLogsMethod · 0.95

Calls 11

WriteFunction · 0.92
fetchAndWriteLogsFunction · 0.85
newLogFollowerFunction · 0.85
followMethod · 0.80
ContextMethod · 0.65
GetMethod · 0.65
AddMethod · 0.65
HasMethod · 0.45
LockMethod · 0.45
UnlockMethod · 0.45
DoneMethod · 0.45

Tested by

no test coverage detected