Skip to content

chore: rename startup logs to agent logs #8649

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

Merged
merged 16 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix naming
  • Loading branch information
kylecarbs committed Jul 21, 2023
commit 8e0f9ba624bd0a369d67f05505942fbd067e657c
2 changes: 1 addition & 1 deletion cli/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (r *RootCmd) ssh() *clibase.Cmd {
// This is required in "stdio" mode so a connecting indicator can be displayed.
err = cliui.Agent(ctx, inv.Stderr, workspaceAgent.ID, cliui.AgentOptions{
Fetch: client.WorkspaceAgent,
FetchLogs: client.WorkspaceAgentStartupLogsAfter,
FetchLogs: client.WorkspaceAgentLogsAfter,
Wait: wait,
})
if err != nil {
Expand Down
6 changes: 2 additions & 4 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -757,8 +757,7 @@ func New(options *Options) *API {
// New agents will use /me/manifest instead.
r.Get("/metadata", api.workspaceAgentManifest)
r.Post("/startup", api.postWorkspaceAgentStartup)
// /startup prefix is supported for backwards compatibility - remove in October, 2023.
r.Patch("/startup-logs", api.patchWorkspaceAgentLogs)
r.Patch("/startup-logs", api.patchWorkspaceAgentLogsDeprecated)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

r.Patch("/logs", api.patchWorkspaceAgentLogs)
r.Post("/app-health", api.postWorkspaceAppHealth)
r.Get("/gitauth", api.workspaceAgentsGitAuth)
Expand All @@ -783,8 +782,7 @@ func New(options *Options) *API {
)
r.Get("/", api.workspaceAgent)
r.Get("/watch-metadata", api.watchWorkspaceAgentMetadata)
// /startup prefix is supported for backwards compatibility - remove in October, 2023.
r.Get("/startup-logs", api.workspaceAgentLogs)
r.Get("/startup-logs", api.workspaceAgentLogsDeprecated)
r.Get("/logs", api.workspaceAgentLogs)
r.Get("/listening-ports", api.workspaceAgentListeningPorts)
r.Get("/connection", api.workspaceAgentConnection)
Expand Down
2 changes: 1 addition & 1 deletion coderd/database/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func TestGetDeploymentWorkspaceAgentStats(t *testing.T) {
})
}

func TestInsertWorkspaceAgentStartupLogs(t *testing.T) {
func TestInsertWorkspaceAgentLogs(t *testing.T) {
t.Parallel()
if testing.Short() {
t.SkipNow()
Expand Down
29 changes: 29 additions & 0 deletions coderd/deprecated.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,32 @@ func templateVersionParametersDeprecated(rw http.ResponseWriter, r *http.Request
func templateVersionSchemaDeprecated(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(r.Context(), rw, http.StatusOK, []struct{}{})
}

// @Summary Removed: Patch workspace agent logs
// @ID removed-patch-workspace-agent-logs
// @Security CoderSessionToken
// @Accept json
// @Produce json
// @Tags Agents
// @Param request body agentsdk.PatchLogs true "logs"
// @Success 200 {object} codersdk.Response
// @Router /workspaceagents/me/startup-logs [patch]
func (api *API) patchWorkspaceAgentLogsDeprecated(rw http.ResponseWriter, r *http.Request) {
api.patchWorkspaceAgentLogs(rw, r)
}

// @Summary Removed: Get logs by workspace agent
// @ID removed-get-logs-by-workspace-agent
// @Security CoderSessionToken
// @Produce json
// @Tags Agents
// @Param workspaceagent path string true "Workspace agent ID" format(uuid)
// @Param before query int false "Before log id"
// @Param after query int false "After log id"
// @Param follow query bool false "Follow log stream"
// @Param no_compression query bool false "Disable compression for WebSocket connection"
// @Success 200 {array} codersdk.WorkspaceAgentLog
// @Router /workspaceagents/{workspaceagent}/startup-logs [get]
func (api *API) workspaceAgentLogsDeprecated(rw http.ResponseWriter, r *http.Request) {
api.workspaceAgentLogs(rw, r)
}
2 changes: 1 addition & 1 deletion coderd/workspaceagents.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ func (api *API) patchWorkspaceAgentLogs(rw http.ResponseWriter, r *http.Request)

// Publish by the lowest log ID inserted so the
// log stream will fetch everything from that point.
api.publishWorkspaceAgentStartupLogsUpdate(ctx, workspaceAgent.ID, agentsdk.LogsNotifyMessage{
api.publishWorkspaceAgentLogsUpdate(ctx, workspaceAgent.ID, agentsdk.LogsNotifyMessage{
CreatedAfter: lowestLogID - 1,
})

Expand Down
2 changes: 1 addition & 1 deletion coderd/workspaceagents_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func TestWorkspaceAgentStartupLogs(t *testing.T) {
})
require.NoError(t, err)

logs, closer, err := client.WorkspaceAgentStartupLogsAfter(ctx, build.Resources[0].Agents[0].ID, 0, true)
logs, closer, err := client.WorkspaceAgentLogsAfter(ctx, build.Resources[0].Agents[0].ID, 0, true)
require.NoError(t, err)
defer func() {
_ = closer.Close()
Expand Down
6 changes: 3 additions & 3 deletions coderd/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -1251,13 +1251,13 @@ func (api *API) publishWorkspaceUpdate(ctx context.Context, workspaceID uuid.UUI
}
}

func (api *API) publishWorkspaceAgentStartupLogsUpdate(ctx context.Context, workspaceAgentID uuid.UUID, m agentsdk.LogsNotifyMessage) {
func (api *API) publishWorkspaceAgentLogsUpdate(ctx context.Context, workspaceAgentID uuid.UUID, m agentsdk.LogsNotifyMessage) {
b, err := json.Marshal(m)
if err != nil {
api.Logger.Warn(ctx, "failed to marshal startup logs notify message", slog.F("workspace_agent_id", workspaceAgentID), slog.Error(err))
api.Logger.Warn(ctx, "failed to marshal logs notify message", slog.F("workspace_agent_id", workspaceAgentID), slog.Error(err))
}
err = api.Pubsub.Publish(agentsdk.LogsNotifyChannel(workspaceAgentID), b)
if err != nil {
api.Logger.Warn(ctx, "failed to publish workspace agent startup logs update", slog.F("workspace_agent_id", workspaceAgentID), slog.Error(err))
api.Logger.Warn(ctx, "failed to publish workspace agent logs update", slog.F("workspace_agent_id", workspaceAgentID), slog.Error(err))
}
}
2 changes: 1 addition & 1 deletion codersdk/agentsdk/agentsdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ type PatchLogs struct {
// PatchLogs writes log messages to the agent startup script.
// Log messages are limited to 1MB in total.
func (c *Client) PatchLogs(ctx context.Context, req PatchLogs) error {
res, err := c.SDK.Request(ctx, http.MethodPatch, "/api/v2/workspaceagents/me/startup-logs", req)
res, err := c.SDK.Request(ctx, http.MethodPatch, "/api/v2/workspaceagents/me/logs", req)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions codersdk/workspaceagents.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ func (c *Client) WorkspaceAgentListeningPorts(ctx context.Context, agentID uuid.
}

//nolint:revive // Follow is a control flag on the server as well.
func (c *Client) WorkspaceAgentStartupLogsAfter(ctx context.Context, agentID uuid.UUID, after int64, follow bool) (<-chan []WorkspaceAgentLog, io.Closer, error) {
func (c *Client) WorkspaceAgentLogsAfter(ctx context.Context, agentID uuid.UUID, after int64, follow bool) (<-chan []WorkspaceAgentLog, io.Closer, error) {
var queryParams []string
if after != 0 {
queryParams = append(queryParams, fmt.Sprintf("after=%d", after))
Expand All @@ -569,7 +569,7 @@ func (c *Client) WorkspaceAgentStartupLogsAfter(ctx context.Context, agentID uui
if len(queryParams) > 0 {
query = "?" + strings.Join(queryParams, "&")
}
reqURL, err := c.URL.Parse(fmt.Sprintf("/api/v2/workspaceagents/%s/startup-logs%s", agentID, query))
reqURL, err := c.URL.Parse(fmt.Sprintf("/api/v2/workspaceagents/%s/logs%s", agentID, query))
if err != nil {
return nil, nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions docs/admin/automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ We strive to keep the following use cases up to date, but please note that chang

Workspace agents have a special token that can send logs, metrics, and workspace activity.

- [Custom workspace logs](../api/agents.md#patch-workspace-agent-startup-logs): Expose messages prior to the Coder init script running (e.g. pulling image, VM starting, restoring snapshot). [coder-logstream-kube](https://github.com/coder/coder-logstream-kube) uses this to show Kubernetes events, such as image pulls or ResourceQuota restrictions.
- [Custom workspace logs](../api/agents.md#patch-workspace-agent-logs): Expose messages prior to the Coder init script running (e.g. pulling image, VM starting, restoring snapshot). [coder-logstream-kube](https://github.com/coder/coder-logstream-kube) uses this to show Kubernetes events, such as image pulls or ResourceQuota restrictions.

```sh
curl -X PATCH https://coder.example.com/api/v2/workspaceagents/me/startup-logs \
curl -X PATCH https://coder.example.com/api/v2/workspaceagents/me/logs \
-H "Coder-Session-Token: $CODER_AGENT_TOKEN" \
-d "{
\"logs\": [
Expand Down
22 changes: 11 additions & 11 deletions site/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -775,11 +775,11 @@ export const getWorkspaceBuildLogs = async (
return response.data
}

export const getWorkspaceAgentStartupLogs = async (
export const getWorkspaceAgentLogs = async (
agentID: string,
): Promise<TypesGen.WorkspaceAgentStartupLog[]> => {
const response = await axios.get<TypesGen.WorkspaceAgentStartupLog[]>(
`/api/v2/workspaceagents/${agentID}/startup-logs`,
): Promise<TypesGen.WorkspaceAgentLog[]> => {
const response = await axios.get<TypesGen.WorkspaceAgentLog[]>(
`/api/v2/workspaceagents/${agentID}/logs`,
)
return response.data
}
Expand Down Expand Up @@ -1272,21 +1272,21 @@ export const watchBuildLogsByTemplateVersionId = (
return socket
}

type WatchStartupLogsOptions = {
type WatchWorkspaceAgentLogsOptions = {
after: number
onMessage: (logs: TypesGen.WorkspaceAgentStartupLog[]) => void
onMessage: (logs: TypesGen.WorkspaceAgentLog[]) => void
onDone: () => void
onError: (error: Error) => void
}

export const watchStartupLogs = (
export const watchWorkspaceAgentLogs = (
agentId: string,
{ after, onMessage, onDone, onError }: WatchStartupLogsOptions,
{ after, onMessage, onDone, onError }: WatchWorkspaceAgentLogsOptions,
) => {
// WebSocket compression in Safari (confirmed in 16.5) is broken when
// the server sends large messages. The following error is seen:
//
// WebSocket connection to 'wss://.../startup-logs?follow&after=0' failed: The operation couldn’t be completed. Protocol error
// WebSocket connection to 'wss://.../logs?follow&after=0' failed: The operation couldn’t be completed. Protocol error
//
const noCompression =
userAgentParser(navigator.userAgent).browser.name === "Safari"
Expand All @@ -1295,11 +1295,11 @@ export const watchStartupLogs = (

const proto = location.protocol === "https:" ? "wss:" : "ws:"
const socket = new WebSocket(
`${proto}//${location.host}/api/v2/workspaceagents/${agentId}/startup-logs?follow&after=${after}${noCompression}`,
`${proto}//${location.host}/api/v2/workspaceagents/${agentId}/logs?follow&after=${after}${noCompression}`,
)
socket.binaryType = "blob"
socket.addEventListener("message", (event) => {
const logs = JSON.parse(event.data) as TypesGen.WorkspaceAgentStartupLog[]
const logs = JSON.parse(event.data) as TypesGen.WorkspaceAgentLog[]
onMessage(logs)
})
socket.addEventListener("error", () => {
Expand Down
6 changes: 3 additions & 3 deletions site/src/testHelpers/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,8 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = {
lifecycle_state: "starting",
login_before_ready: false, // Deprecated.
startup_script_behavior: "blocking",
startup_logs_length: 0,
startup_logs_overflowed: false,
logs_length: 0,
logs_overflowed: false,
startup_script_timeout_seconds: 120,
shutdown_script_timeout_seconds: 120,
subsystem: "envbox",
Expand Down Expand Up @@ -1781,7 +1781,7 @@ export const MockDeploymentSSH: TypesGen.SSHConfigResponse = {
ssh_config_options: {},
}

export const MockStartupLogs: TypesGen.WorkspaceAgentStartupLog[] = [
export const MockWorkspaceAgentLogs: TypesGen.WorkspaceAgentLog[] = [
{
id: 166663,
created_at: "2023-05-04T11:30:41.402072Z",
Expand Down
4 changes: 2 additions & 2 deletions site/src/testHelpers/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ export const handlers = [
return res(ctx.status(200), ctx.json(M.MockDeploymentSSH))
}),

rest.get("/api/v2/workspaceagents/:agent/startup-logs", (_, res, ctx) => {
return res(ctx.status(200), ctx.json(M.MockStartupLogs))
rest.get("/api/v2/workspaceagents/:agent/logs", (_, res, ctx) => {
return res(ctx.status(200), ctx.json(M.MockWorkspaceAgentLogs))
}),
]
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const workspaceAgentLogsMachine = createMachine(
{
services: {
getStartupLogs: (ctx) =>
API.getWorkspaceAgentStartupLogs(ctx.agentID).then((data) =>
API.getWorkspaceAgentLogs(ctx.agentID).then((data) =>
data.map((log) => ({
id: log.id,
level: log.level || "info",
Expand All @@ -89,7 +89,7 @@ export const workspaceAgentLogsMachine = createMachine(
after = ctx.startupLogs[ctx.startupLogs.length - 1].id
}

const socket = API.watchStartupLogs(ctx.agentID, {
const socket = API.watchWorkspaceAgentLogs(ctx.agentID, {
after,
onMessage: (logs) => {
callback({
Expand Down
2 changes: 1 addition & 1 deletion site/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default defineConfig({
secure: process.env.NODE_ENV === "production",
configure: (proxy) => {
// Vite does not catch socket errors, and stops the webserver.
// As /startup-logs endpoint can return HTTP 4xx status, we need to embrace
// As /logs endpoint can return HTTP 4xx status, we need to embrace
// Vite with a custom error handler to prevent from quitting.
proxy.on("proxyReqWs", (proxyReq, req, socket) => {
if (process.env.NODE_ENV === "development") {
Expand Down