From bf9336d35a5bdc1e7c509a5b1f996154c546a36a Mon Sep 17 00:00:00 2001 From: valitovgaziz Date: Thu, 16 Oct 2025 10:15:03 +0500 Subject: [PATCH] modified: serv_nginx/api_bb/internal/handlers/news_handler.go add full of logs into newsHandler --- .../api_bb/internal/handlers/news_handler.go | 156 +++++++++++++++++- 1 file changed, 150 insertions(+), 6 deletions(-) diff --git a/serv_nginx/api_bb/internal/handlers/news_handler.go b/serv_nginx/api_bb/internal/handlers/news_handler.go index fbf697c..5edc473 100644 --- a/serv_nginx/api_bb/internal/handlers/news_handler.go +++ b/serv_nginx/api_bb/internal/handlers/news_handler.go @@ -30,10 +30,18 @@ func NewNewsHandler(newsService service.NewsService, log logger.LoggerInterface) // GetNews возвращает список новостей с пагинацией и фильтрацией func (h *NewsHandler) GetNews(w http.ResponseWriter, r *http.Request) { + h.logger.Debug("Start GetNews Method") + limit, _ := strconv.Atoi(r.URL.Query().Get("limit")) offset, _ := strconv.Atoi(r.URL.Query().Get("offset")) category := r.URL.Query().Get("category") + h.logger.Debug("GetNews parameters", + zap.Int("limit", limit), + zap.Int("offset", offset), + zap.String("category", category), + ) + if limit == 0 { limit = 10 } @@ -48,6 +56,12 @@ func (h *NewsHandler) GetNews(w http.ResponseWriter, r *http.Request) { return } + h.logger.Debug("Successfully retrieved news", + zap.Int("count", len(news)), + zap.Int("total", int(total)), + ) + + h.logger.Debug("End GetNews Method") utils.RespondWithJSON(w, http.StatusOK, map[string]interface{}{ "news": news, "total": total, @@ -58,33 +72,42 @@ func (h *NewsHandler) GetNews(w http.ResponseWriter, r *http.Request) { // GetNewsByID возвращает конкретную новость func (h *NewsHandler) GetNewsByID(w http.ResponseWriter, r *http.Request) { + h.logger.Debug("Start GetNewsByID Method") + idStr := chi.URLParam(r, "id") + h.logger.Debug("GetNewsByID parameters", zap.String("id", idStr)) + id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { + h.logger.Warn("Invalid news ID", zap.String("id", idStr), zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid news ID") return } news, err := h.newsService.GetNewsByID(uint(id)) if err != nil { + h.logger.Warn("News not found", zap.Uint("id", uint(id)), zap.Error(err)) utils.RespondWithError(w, http.StatusNotFound, "News not found") return } + h.logger.Debug("Successfully retrieved news by ID", zap.Uint("id", uint(id))) + h.logger.Debug("End GetNewsByID Method") utils.RespondWithJSON(w, http.StatusOK, news) } // CreateNews создает новую новость func (h *NewsHandler) CreateNews(w http.ResponseWriter, r *http.Request) { - logger.Get().Debug("Start CreateNews Method") + h.logger.Debug("Start CreateNews Method") + userID, ok := r.Context().Value(middleware.UserIDKey).(uint) - logger.Get().Info("userID", zap.Uint("userID", userID)) + h.logger.Debug("CreateNews user context", zap.Uint("userID", userID), zap.Bool("ok", ok)) + if !ok { - h.logger.Warn("Failed to get userID from context in CreateReview", + h.logger.Warn("Failed to get userID from context in CreateNews", zap.String("path", r.URL.Path), zap.String("method", r.Method), zap.String("remote_addr", r.RemoteAddr), - zap.Uint("userID", userID), ) utils.RespondWithError(w, http.StatusUnauthorized, "Unauthorized") return @@ -92,11 +115,18 @@ func (h *NewsHandler) CreateNews(w http.ResponseWriter, r *http.Request) { var req models.CreateNewsRequest if err := utils.DecodeJSONBody(w, r, &req); err != nil { + h.logger.Warn("Invalid request body in CreateNews", zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid request body") return } + h.logger.Debug("CreateNews request data", + zap.String("title", req.Title), + zap.String("category", string(req.Category)), + ) + if err := h.validator.Struct(req); err != nil { + h.logger.Warn("Validation failed in CreateNews", zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Validation failed: "+err.Error()) return } @@ -108,31 +138,51 @@ func (h *NewsHandler) CreateNews(w http.ResponseWriter, r *http.Request) { return } + h.logger.Info("Successfully created news", + zap.Uint("newsID", news.ID), + zap.Uint("userID", userID), + ) + h.logger.Debug("End CreateNews Method") utils.RespondWithJSON(w, http.StatusCreated, news) } // UpdateNews обновляет новость func (h *NewsHandler) UpdateNews(w http.ResponseWriter, r *http.Request) { + h.logger.Debug("Start UpdateNews Method") + userID, ok := r.Context().Value(middleware.UserIDKey).(uint) + h.logger.Debug("UpdateNews user context", zap.Uint("userID", userID), zap.Bool("ok", ok)) + if !ok { + h.logger.Warn("Failed to get userID from context in UpdateNews") utils.RespondWithError(w, http.StatusUnauthorized, "Unauthorized") return } idStr := chi.URLParam(r, "id") + h.logger.Debug("UpdateNews parameters", zap.String("id", idStr)) + id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { + h.logger.Warn("Invalid news ID in UpdateNews", zap.String("id", idStr), zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid news ID") return } var req models.UpdateNewsRequest if err := utils.DecodeJSONBody(w, r, &req); err != nil { + h.logger.Warn("Invalid request body in UpdateNews", zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid request body") return } + h.logger.Debug("UpdateNews request data", + zap.String("title", req.Title), + zap.String("category", string(req.Category)), + ) + if err := h.validator.Struct(req); err != nil { + h.logger.Warn("Validation failed in UpdateNews", zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Validation failed: "+err.Error()) return } @@ -140,28 +190,45 @@ func (h *NewsHandler) UpdateNews(w http.ResponseWriter, r *http.Request) { news, err := h.newsService.UpdateNews(uint(id), req, userID) if err != nil { if err.Error() == "access denied" { + h.logger.Warn("Access denied in UpdateNews", + zap.Uint("userID", userID), + zap.Uint("newsID", uint(id)), + ) utils.RespondWithError(w, http.StatusForbidden, "Access denied") return } + h.logger.Error("Failed to update news", zap.Error(err)) utils.RespondWithError(w, http.StatusInternalServerError, "Failed to update news") return } - logger.Get().Debug("End CreateNews Method") + h.logger.Info("Successfully updated news", + zap.Uint("newsID", uint(id)), + zap.Uint("userID", userID), + ) + h.logger.Debug("End UpdateNews Method") utils.RespondWithJSON(w, http.StatusOK, news) } // DeleteNews удаляет новость func (h *NewsHandler) DeleteNews(w http.ResponseWriter, r *http.Request) { + h.logger.Debug("Start DeleteNews Method") + userID, ok := r.Context().Value(middleware.UserIDKey).(uint) + h.logger.Debug("DeleteNews user context", zap.Uint("userID", userID), zap.Bool("ok", ok)) + if !ok { + h.logger.Warn("Failed to get userID from context in DeleteNews") utils.RespondWithError(w, http.StatusUnauthorized, "Unauthorized") return } idStr := chi.URLParam(r, "id") + h.logger.Debug("DeleteNews parameters", zap.String("id", idStr)) + id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { + h.logger.Warn("Invalid news ID in DeleteNews", zap.String("id", idStr), zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid news ID") return } @@ -169,80 +236,130 @@ func (h *NewsHandler) DeleteNews(w http.ResponseWriter, r *http.Request) { err = h.newsService.DeleteNews(uint(id), userID) if err != nil { if err.Error() == "access denied" { + h.logger.Warn("Access denied in DeleteNews", + zap.Uint("userID", userID), + zap.Uint("newsID", uint(id)), + ) utils.RespondWithError(w, http.StatusForbidden, "Access denied") return } + h.logger.Error("Failed to delete news", zap.Error(err)) utils.RespondWithError(w, http.StatusInternalServerError, "Failed to delete news") return } + h.logger.Info("Successfully deleted news", + zap.Uint("newsID", uint(id)), + zap.Uint("userID", userID), + ) + h.logger.Debug("End DeleteNews Method") utils.RespondWithJSON(w, http.StatusOK, map[string]string{"message": "News deleted successfully"}) } // CreateComment создает комментарий к новости func (h *NewsHandler) CreateComment(w http.ResponseWriter, r *http.Request) { + h.logger.Debug("Start CreateComment Method") + userID, ok := r.Context().Value(middleware.UserIDKey).(uint) + h.logger.Debug("CreateComment user context", zap.Uint("userID", userID), zap.Bool("ok", ok)) + if !ok { + h.logger.Warn("Failed to get userID from context in CreateComment") utils.RespondWithError(w, http.StatusUnauthorized, "Unauthorized") return } newsIDStr := chi.URLParam(r, "id") + h.logger.Debug("CreateComment parameters", zap.String("newsID", newsIDStr)) + newsID, err := strconv.ParseUint(newsIDStr, 10, 32) if err != nil { + h.logger.Warn("Invalid news ID in CreateComment", zap.String("newsID", newsIDStr), zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid news ID") return } var req models.CreateCommentRequest if err := utils.DecodeJSONBody(w, r, &req); err != nil { + h.logger.Warn("Invalid request body in CreateComment", zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid request body") return } + h.logger.Debug("CreateComment request data", + zap.String("content", req.Content), + ) + if err := h.validator.Struct(req); err != nil { + h.logger.Warn("Validation failed in CreateComment", zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Validation failed: "+err.Error()) return } comment, err := h.newsService.CreateComment(uint(newsID), req, userID) if err != nil { + h.logger.Error("Failed to create comment", zap.Error(err)) utils.RespondWithError(w, http.StatusInternalServerError, "Failed to create comment") return } + h.logger.Info("Successfully created comment", + zap.Uint("commentID", comment.ID), + zap.Uint("newsID", uint(newsID)), + zap.Uint("userID", userID), + ) + h.logger.Debug("End CreateComment Method") utils.RespondWithJSON(w, http.StatusCreated, comment) } // GetComments возвращает комментарии к новости func (h *NewsHandler) GetComments(w http.ResponseWriter, r *http.Request) { + h.logger.Debug("Start GetComments Method") + newsIDStr := chi.URLParam(r, "id") + h.logger.Debug("GetComments parameters", zap.String("newsID", newsIDStr)) + newsID, err := strconv.ParseUint(newsIDStr, 10, 32) if err != nil { + h.logger.Warn("Invalid news ID in GetComments", zap.String("newsID", newsIDStr), zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid news ID") return } comments, err := h.newsService.GetCommentsByNewsID(uint(newsID)) if err != nil { + h.logger.Error("Failed to get comments", zap.Error(err)) utils.RespondWithError(w, http.StatusInternalServerError, "Failed to get comments") return } + h.logger.Debug("Successfully retrieved comments", + zap.Uint("newsID", uint(newsID)), + zap.Int("count", len(comments)), + ) + h.logger.Debug("End GetComments Method") utils.RespondWithJSON(w, http.StatusOK, comments) } // DeleteComment удаляет комментарий func (h *NewsHandler) DeleteComment(w http.ResponseWriter, r *http.Request) { + h.logger.Debug("Start DeleteComment Method") + userID, ok := r.Context().Value(middleware.UserIDKey).(uint) + h.logger.Debug("DeleteComment user context", zap.Uint("userID", userID), zap.Bool("ok", ok)) + if !ok { + h.logger.Warn("Failed to get userID from context in DeleteComment") utils.RespondWithError(w, http.StatusUnauthorized, "Unauthorized") return } commentIDStr := chi.URLParam(r, "commentId") + h.logger.Debug("DeleteComment parameters", zap.String("commentID", commentIDStr)) + commentID, err := strconv.ParseUint(commentIDStr, 10, 32) if err != nil { + h.logger.Warn("Invalid comment ID in DeleteComment", zap.String("commentID", commentIDStr), zap.Error(err)) utils.RespondWithError(w, http.StatusBadRequest, "Invalid comment ID") return } @@ -250,20 +367,35 @@ func (h *NewsHandler) DeleteComment(w http.ResponseWriter, r *http.Request) { err = h.newsService.DeleteComment(uint(commentID), userID) if err != nil { if err.Error() == "access denied" { + h.logger.Warn("Access denied in DeleteComment", + zap.Uint("userID", userID), + zap.Uint("commentID", uint(commentID)), + ) utils.RespondWithError(w, http.StatusForbidden, "Access denied") return } + h.logger.Error("Failed to delete comment", zap.Error(err)) utils.RespondWithError(w, http.StatusInternalServerError, "Failed to delete comment") return } + h.logger.Info("Successfully deleted comment", + zap.Uint("commentID", uint(commentID)), + zap.Uint("userID", userID), + ) + h.logger.Debug("End DeleteComment Method") utils.RespondWithJSON(w, http.StatusOK, map[string]string{"message": "Comment deleted successfully"}) } // GetUserNews возвращает новости конкретного пользователя func (h *NewsHandler) GetUserNews(w http.ResponseWriter, r *http.Request) { + h.logger.Debug("Start GetUserNews Method") + userID, ok := r.Context().Value(middleware.UserIDKey).(uint) + h.logger.Debug("GetUserNews user context", zap.Uint("userID", userID), zap.Bool("ok", ok)) + if !ok { + h.logger.Warn("Failed to get userID from context in GetUserNews") utils.RespondWithError(w, http.StatusUnauthorized, "Unauthorized") return } @@ -271,18 +403,30 @@ func (h *NewsHandler) GetUserNews(w http.ResponseWriter, r *http.Request) { limit, _ := strconv.Atoi(r.URL.Query().Get("limit")) offset, _ := strconv.Atoi(r.URL.Query().Get("offset")) + h.logger.Debug("GetUserNews parameters", + zap.Int("limit", limit), + zap.Int("offset", offset), + ) + if limit == 0 { limit = 10 } news, total, err := h.newsService.GetUserNews(userID, limit, offset) if err != nil { + h.logger.Error("Failed to get user news", zap.Error(err)) utils.RespondWithError(w, http.StatusInternalServerError, "Failed to get user news") return } + h.logger.Debug("Successfully retrieved user news", + zap.Uint("userID", userID), + zap.Int("count", len(news)), + zap.Int("total", int(total)), + ) + h.logger.Debug("End GetUserNews Method") utils.RespondWithJSON(w, http.StatusOK, map[string]interface{}{ "news": news, "total": total, }) -} +} \ No newline at end of file