Add logging to handlers

This commit is contained in:
2024-12-17 23:28:01 +01:00
parent 54cefac4b7
commit 7ccd36f0e4
8 changed files with 739 additions and 56 deletions

View File

@@ -6,6 +6,7 @@ import (
"net/http"
"novamd/internal/context"
"novamd/internal/logging"
"novamd/internal/models"
)
@@ -19,6 +20,10 @@ type LastWorkspaceNameResponse struct {
LastWorkspaceName string `json:"lastWorkspaceName"`
}
func getWorkspaceLogger() logging.Logger {
return getHandlersLogger().WithGroup("workspace")
}
// ListWorkspaces godoc
// @Summary List workspaces
// @Description Lists all workspaces for the current user
@@ -35,13 +40,24 @@ func (h *Handler) ListWorkspaces() http.HandlerFunc {
if !ok {
return
}
log := getWorkspaceLogger().With(
"handler", "ListWorkspaces",
"userID", ctx.UserID,
"clientIP", r.RemoteAddr,
)
workspaces, err := h.DB.GetWorkspacesByUserID(ctx.UserID)
if err != nil {
log.Error("failed to fetch workspaces from database",
"error", err.Error(),
)
respondError(w, "Failed to list workspaces", http.StatusInternalServerError)
return
}
log.Debug("workspaces retrieved successfully",
"count", len(workspaces),
)
respondJSON(w, workspaces)
}
}
@@ -68,30 +84,54 @@ func (h *Handler) CreateWorkspace() http.HandlerFunc {
if !ok {
return
}
log := getWorkspaceLogger().With(
"handler", "CreateWorkspace",
"userID", ctx.UserID,
"clientIP", r.RemoteAddr,
)
var workspace models.Workspace
if err := json.NewDecoder(r.Body).Decode(&workspace); err != nil {
log.Debug("invalid request body received",
"error", err.Error(),
)
respondError(w, "Invalid request body", http.StatusBadRequest)
return
}
if err := workspace.ValidateGitSettings(); err != nil {
log.Debug("invalid git settings provided",
"error", err.Error(),
)
respondError(w, "Invalid workspace", http.StatusBadRequest)
return
}
workspace.UserID = ctx.UserID
if err := h.DB.CreateWorkspace(&workspace); err != nil {
log.Error("failed to create workspace in database",
"error", err.Error(),
"workspaceName", workspace.Name,
)
respondError(w, "Failed to create workspace", http.StatusInternalServerError)
return
}
if err := h.Storage.InitializeUserWorkspace(workspace.UserID, workspace.ID); err != nil {
log.Error("failed to initialize workspace directory",
"error", err.Error(),
"workspaceID", workspace.ID,
)
respondError(w, "Failed to initialize workspace directory", http.StatusInternalServerError)
return
}
if workspace.GitEnabled {
log.Debug("setting up git repository",
"workspaceID", workspace.ID,
"gitURL", workspace.GitURL,
)
if err := h.Storage.SetupGitRepo(
ctx.UserID,
workspace.ID,
@@ -101,11 +141,20 @@ func (h *Handler) CreateWorkspace() http.HandlerFunc {
workspace.GitCommitName,
workspace.GitCommitEmail,
); err != nil {
log.Error("failed to setup git repository",
"error", err.Error(),
"workspaceID", workspace.ID,
)
respondError(w, "Failed to setup git repo: "+err.Error(), http.StatusInternalServerError)
return
}
}
log.Info("workspace created",
"workspaceID", workspace.ID,
"workspaceName", workspace.Name,
"gitEnabled", workspace.GitEnabled,
)
respondJSON(w, workspace)
}
}
@@ -171,9 +220,18 @@ func (h *Handler) UpdateWorkspace() http.HandlerFunc {
if !ok {
return
}
log := getWorkspaceLogger().With(
"handler", "UpdateWorkspace",
"userID", ctx.UserID,
"workspaceID", ctx.Workspace.ID,
"clientIP", r.RemoteAddr,
)
var workspace models.Workspace
if err := json.NewDecoder(r.Body).Decode(&workspace); err != nil {
log.Debug("invalid request body received",
"error", err.Error(),
)
respondError(w, "Invalid request body", http.StatusBadRequest)
return
}
@@ -184,13 +242,28 @@ func (h *Handler) UpdateWorkspace() http.HandlerFunc {
// Validate the workspace
if err := workspace.Validate(); err != nil {
log.Debug("invalid workspace configuration",
"error", err.Error(),
)
respondError(w, err.Error(), http.StatusBadRequest)
return
}
// Track what's changed for logging
changes := map[string]bool{
"gitSettings": gitSettingsChanged(&workspace, ctx.Workspace),
"name": workspace.Name != ctx.Workspace.Name,
"theme": workspace.Theme != ctx.Workspace.Theme,
"autoSave": workspace.AutoSave != ctx.Workspace.AutoSave,
}
// Handle Git repository setup/teardown if Git settings changed
if gitSettingsChanged(&workspace, ctx.Workspace) {
if changes["gitSettings"] {
if workspace.GitEnabled {
log.Debug("updating git repository configuration",
"gitURL", workspace.GitURL,
)
if err := h.Storage.SetupGitRepo(
ctx.UserID,
ctx.Workspace.ID,
@@ -200,20 +273,29 @@ func (h *Handler) UpdateWorkspace() http.HandlerFunc {
workspace.GitCommitName,
workspace.GitCommitEmail,
); err != nil {
log.Error("failed to setup git repository",
"error", err.Error(),
)
respondError(w, "Failed to setup git repo: "+err.Error(), http.StatusInternalServerError)
return
}
} else {
log.Debug("disabling git repository")
h.Storage.DisableGitRepo(ctx.UserID, ctx.Workspace.ID)
}
}
if err := h.DB.UpdateWorkspace(&workspace); err != nil {
log.Error("failed to update workspace in database",
"error", err.Error(),
)
respondError(w, "Failed to update workspace", http.StatusInternalServerError)
return
}
log.Debug("workspace updated",
"changes", changes,
)
respondJSON(w, workspace)
}
}
@@ -241,15 +323,25 @@ func (h *Handler) DeleteWorkspace() http.HandlerFunc {
if !ok {
return
}
log := getWorkspaceLogger().With(
"handler", "DeleteWorkspace",
"userID", ctx.UserID,
"workspaceID", ctx.Workspace.ID,
"clientIP", r.RemoteAddr,
)
// Check if this is the user's last workspace
workspaces, err := h.DB.GetWorkspacesByUserID(ctx.UserID)
if err != nil {
log.Error("failed to fetch workspaces from database",
"error", err.Error(),
)
respondError(w, "Failed to get workspaces", http.StatusInternalServerError)
return
}
if len(workspaces) <= 1 {
log.Debug("attempted to delete last workspace")
respondError(w, "Cannot delete the last workspace", http.StatusBadRequest)
return
}
@@ -265,14 +357,19 @@ func (h *Handler) DeleteWorkspace() http.HandlerFunc {
}
}
// Start transaction
tx, err := h.DB.Begin()
if err != nil {
log.Error("failed to start database transaction",
"error", err.Error(),
)
respondError(w, "Failed to start transaction", http.StatusInternalServerError)
return
}
defer func() {
if err := tx.Rollback(); err != nil && err != sql.ErrTxDone {
log.Error("failed to rollback transaction",
"error", err.Error(),
)
respondError(w, "Failed to rollback transaction", http.StatusInternalServerError)
}
}()
@@ -280,6 +377,10 @@ func (h *Handler) DeleteWorkspace() http.HandlerFunc {
// Update last workspace ID first
err = h.DB.UpdateLastWorkspaceTx(tx, ctx.UserID, nextWorkspaceID)
if err != nil {
log.Error("failed to update last workspace reference",
"error", err.Error(),
"nextWorkspaceID", nextWorkspaceID,
)
respondError(w, "Failed to update last workspace", http.StatusInternalServerError)
return
}
@@ -287,16 +388,27 @@ func (h *Handler) DeleteWorkspace() http.HandlerFunc {
// Delete the workspace
err = h.DB.DeleteWorkspaceTx(tx, ctx.Workspace.ID)
if err != nil {
log.Error("failed to delete workspace from database",
"error", err.Error(),
)
respondError(w, "Failed to delete workspace", http.StatusInternalServerError)
return
}
// Commit transaction
if err = tx.Commit(); err != nil {
log.Error("failed to commit transaction",
"error", err.Error(),
)
respondError(w, "Failed to commit transaction", http.StatusInternalServerError)
return
}
log.Info("workspace deleted",
"workspaceName", ctx.Workspace.Name,
"nextWorkspaceName", nextWorkspaceName,
)
// Return the next workspace ID in the response so frontend knows where to redirect
respondJSON(w, &DeleteWorkspaceResponse{NextWorkspaceName: nextWorkspaceName})
}
@@ -318,13 +430,24 @@ func (h *Handler) GetLastWorkspaceName() http.HandlerFunc {
if !ok {
return
}
log := getWorkspaceLogger().With(
"handler", "GetLastWorkspaceName",
"userID", ctx.UserID,
"clientIP", r.RemoteAddr,
)
workspaceName, err := h.DB.GetLastWorkspaceName(ctx.UserID)
if err != nil {
log.Error("failed to fetch last workspace name",
"error", err.Error(),
)
respondError(w, "Failed to get last workspace", http.StatusInternalServerError)
return
}
log.Debug("last workspace name retrieved",
"workspaceName", workspaceName,
)
respondJSON(w, &LastWorkspaceNameResponse{LastWorkspaceName: workspaceName})
}
}
@@ -347,21 +470,36 @@ func (h *Handler) UpdateLastWorkspaceName() http.HandlerFunc {
if !ok {
return
}
log := getWorkspaceLogger().With(
"handler", "UpdateLastWorkspaceName",
"userID", ctx.UserID,
"clientIP", r.RemoteAddr,
)
var requestBody struct {
WorkspaceName string `json:"workspaceName"`
}
if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil {
log.Debug("invalid request body received",
"error", err.Error(),
)
respondError(w, "Invalid request body", http.StatusBadRequest)
return
}
if err := h.DB.UpdateLastWorkspace(ctx.UserID, requestBody.WorkspaceName); err != nil {
log.Error("failed to update last workspace",
"error", err.Error(),
"workspaceName", requestBody.WorkspaceName,
)
respondError(w, "Failed to update last workspace", http.StatusInternalServerError)
return
}
log.Debug("last workspace name updated",
"workspaceName", requestBody.WorkspaceName,
)
w.WriteHeader(http.StatusNoContent)
}
}