Skip to content

feat: add logging when create channel index #1460

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 5 commits into from
Apr 14, 2025
Merged

Conversation

jihun
Copy link
Contributor

@jihun jihun commented Apr 11, 2025

  • Added logging when create/put channel index

Summary by CodeRabbit

  • New Features
    • Improved operational reliability with enhanced error management during core processes, ensuring smoother performance and more effective troubleshooting.
    • Added logging mechanisms to track index creation and mapping processes, providing better visibility into successful and failed operations.
    • Updated module system to ECMAScript modules (ESM) for improved module handling and syntax.

@jihun jihun requested a review from chiol April 11, 2025 02:10
Copy link

coderabbitai bot commented Apr 11, 2025

Walkthrough

The changes introduce logging and error handling to the OpensearchRepository class in the API. A private Logger instance is added to track operations. The createIndex method is modified to include a try-catch block that logs a success message upon successful index creation and logs detailed error information if the operation fails. The putMappings method is similarly updated to include error handling and logging, capturing and returning the response. These modifications enhance the robustness of both methods by providing runtime feedback through the logger.

Changes

File(s) Change Summary
apps/api/src/common/repositories/opensearch.repository.ts - Added a private Logger instance to the class.
- Modified the createIndex method to include a try-catch block for error handling and logging.
- Updated the putMappings method to include error handling and logging, capturing and returning the response.
apps/api/package.json - Added property "type": "module" to indicate the use of ECMAScript modules (ESM).

Sequence Diagram(s)

sequenceDiagram
    participant Repo as OpensearchRepository
    participant OS as OpenSearch
    participant Log as Logger

    Repo->>OS: Attempt index creation (createIndex)
    alt Successful Creation
        OS-->>Repo: Return success response
        Repo->>Log: Log success message with response details
    else Error Occurred
        OS-->>Repo: Return error response
        Repo->>Log: Log error message with details
    end

    Repo->>OS: Attempt to put mappings (putMappings)
    alt Successful Mapping
        OS-->>Repo: Return success response
        Repo->>Log: Log success message with response details
    else Error Occurred
        OS-->>Repo: Return error response
        Repo->>Log: Log error message with details
    end
Loading

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@jihun jihun changed the title add logging when create channel index feat: add logging when create channel index Apr 11, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/api/src/common/repositories/opensearch.repository.ts (1)

76-78: Consider adding structured logging

While the current logging approach works, consider using a more structured approach for better searchability and filtering in log aggregation tools.

-     this.logger.log(
-       `Index created successfully: ${JSON.stringify(response.body, null, 2)}`,
-     );
+     this.logger.log({
+       message: 'Index created successfully',
+       indexName,
+       responseBody: response.body,
+     });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bbf0c6f and 80930b4.

📒 Files selected for processing (1)
  • apps/api/src/common/repositories/opensearch.repository.ts (2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
apps/api/src/common/repositories/opensearch.repository.ts

[error] 81-81: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🪛 GitHub Check: lint
apps/api/src/common/repositories/opensearch.repository.ts

[failure] 81-81:
Prefer using an optional chain expression instead, as it's more concise and easier to read

🪛 GitHub Actions: CI
apps/api/src/common/repositories/opensearch.repository.ts

[error] 81-81: Prefer using an optional chain expression instead, as it's more concise and easier to read @typescript-eslint/prefer-optional-chain

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (2)
apps/api/src/common/repositories/opensearch.repository.ts (2)

24-24: Great addition of logging capabilities!

Adding the Logger import and instantiating it with the class name follows NestJS best practices. This will help with observability and debugging.

Also applies to: 42-42


50-79: Well-structured try-catch implementation for error handling

The addition of a try-catch block with proper logging of the operation's success is a good improvement to the codebase's observability.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/api/src/common/repositories/opensearch.repository.ts (1)

89-92: 🛠️ Refactor suggestion

Consider moving putAlias into the try-catch block

The putAlias operation is outside the try-catch block, which means if index creation succeeds but alias creation fails, the error wouldn't be logged with the same detail as index creation errors.

    try {
      const response = await this.opensearchClient.indices.create({
        index: indexName,
        body: {
          settings: {
            // ...existing settings...
          },
        },
      });
      this.logger.log(
        `Index created successfully: ${JSON.stringify(response.body, null, 2)}`,
      );
+     
+     await this.opensearchClient.indices.putAlias({
+       index: indexName,
+       name: index,
+     });
+     this.logger.log(`Alias created successfully for index: ${indexName}, alias: ${index}`);
    } catch (error) {
      this.logger.error(`Error creating index: ${error}`);
      if (error?.meta?.body) {
        this.logger.error(
          `OpenSearch error details:${JSON.stringify(error.meta.body, null, 2)}`,
        );
      }
      throw error;
    }
-   await this.opensearchClient.indices.putAlias({
-     index: indexName,
-     name: index,
-   });
🧹 Nitpick comments (3)
apps/api/src/common/repositories/opensearch.repository.ts (3)

51-88: Comprehensive error handling for index creation, but consider log levels

The try-catch implementation properly logs both successful operations and errors, but consider using logger.error() instead of logger.log() for error conditions to improve log filtering and visibility.

    } catch (error) {
-     this.logger.log(`Error creating index: ${error}`);
+     this.logger.error(`Error creating index: ${error}`);
      if (error?.meta?.body) {
-       this.logger.log(
+       this.logger.error(
          `OpenSearch error details:${JSON.stringify(error.meta.body, null, 2)}`,
        );
      }
      throw error;
    }

101-117: Good implementation of error handling for putMappings

The putMappings method now properly captures the response, handles errors with appropriate logging, and returns the response to the caller. However, similar to the createIndex method, consider using logger.error for error conditions.

    try {
      response = await this.opensearchClient.indices.putMapping({
        index,
        body: { properties: mappings },
      });
    } catch (error) {
-     this.logger.log(`Error put mapping: ${error}`);
+     this.logger.error(`Error put mapping: ${error}`);
      if (error?.meta?.body) {
-       this.logger.log(
+       this.logger.error(
          `OpenSearch error details:${JSON.stringify(error.meta.body, null, 2)}`,
        );
      }
      throw error;
    }

120-248: Consider adding similar error handling to other methods

For consistency, consider adding similar try-catch blocks with logging to other methods that interact with OpenSearch, such as createData, updateData, deleteIndex, etc. This would provide a more comprehensive logging solution across the repository.

For example, for the createData method:

  async createData({ id, index, data }: CreateDataDto) {
    const indexName = 'channel_' + index;
-   const existence = await this.opensearchClient.indices.exists({
-     index: indexName,
-   });
-   if (existence.statusCode !== 200)
-     throw new NotFoundException('index is not found');
-
-   const response = await this.opensearchClient.indices.getMapping({
-     index: indexName,
-   });
+   try {
+     const existence = await this.opensearchClient.indices.exists({
+       index: indexName,
+     });
+     if (existence.statusCode !== 200)
+       throw new NotFoundException('index is not found');
+
+     const response = await this.opensearchClient.indices.getMapping({
+       index: indexName,
+     });
+
+     const mappingKeys = Object.keys(
+       response.body[indexName].mappings.properties as object,
+     );
+     const dataKeys = Object.keys(data);
+     if (!dataKeys.every((v) => mappingKeys.includes(v))) {
+       throw new InternalServerErrorException('error!!!');
+     }
+
+     const { body } = await this.opensearchClient.index({
+       id,
+       index: indexName,
+       body: data,
+       refresh: true,
+     });
+
+     this.logger.log(`Data created successfully for index: ${indexName}, id: ${id}`);
+     return { id: body._id as unknown as number };
+   } catch (error) {
+     this.logger.error(`Error creating data: ${error}`);
+     if (error?.meta?.body) {
+       this.logger.error(
+         `OpenSearch error details:${JSON.stringify(error.meta.body, null, 2)}`,
+       );
+     }
+     throw error;
+   }
-   const mappingKeys = Object.keys(
-     response.body[indexName].mappings.properties as object,
-   );
-   const dataKeys = Object.keys(data);
-   if (!dataKeys.every((v) => mappingKeys.includes(v))) {
-     throw new InternalServerErrorException('error!!!');
-   }
-
-   const { body } = await this.opensearchClient.index({
-     id,
-     index: indexName,
-     body: data,
-     refresh: true,
-   });
-
-   return { id: body._id as unknown as number };
  }

Apply similar patterns to other methods that interact with OpenSearch for consistency.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80930b4 and 50a1a1a.

📒 Files selected for processing (1)
  • apps/api/src/common/repositories/opensearch.repository.ts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (3)
apps/api/src/common/repositories/opensearch.repository.ts (3)

24-24: Appropriate imports added for new functionality

The added imports for Logger and Indices_PutMapping_Response are correctly implemented to support the new logging functionality and type safety.

Also applies to: 28-28


43-43: Good implementation of the Logger

The private logger instance is properly initialized with the class name as context, following NestJS best practices for logging.


82-82: Great use of optional chaining

The implementation now uses optional chaining for checking error metadata, which improves code readability and addresses previous review comments.

Also applies to: 109-109

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/api/src/common/repositories/opensearch.repository.ts (1)

91-94: Consider adding try-catch for putAlias operation.

For consistency with the error handling pattern implemented for index creation and mapping operations, consider wrapping the putAlias operation in a try-catch block with similar logging.

-    await this.opensearchClient.indices.putAlias({
-      index: indexName,
-      name: index,
-    });
+    try {
+      await this.opensearchClient.indices.putAlias({
+        index: indexName,
+        name: index,
+      });
+      this.logger.log(`Alias created successfully for index: ${indexName}, alias: ${index}`);
+    } catch (error) {
+      this.logger.log(`Error creating alias: ${error}`);
+      if (error?.meta?.body) {
+        this.logger.log(
+          `OpenSearch error details:${JSON.stringify(error.meta.body, null, 2)}`,
+        );
+      }
+      throw error;
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50a1a1a and 0625ac2.

📒 Files selected for processing (1)
  • apps/api/src/common/repositories/opensearch.repository.ts (3 hunks)
🧰 Additional context used
🪛 GitHub Check: lint
apps/api/src/common/repositories/opensearch.repository.ts

[failure] 77-77:
Unnecessary conditional, value is always truthy

🪛 GitHub Actions: CI
apps/api/src/common/repositories/opensearch.repository.ts

[error] 77-77: Unnecessary conditional, value is always truthy @typescript-eslint/no-unnecessary-condition

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (8)
apps/api/src/common/repositories/opensearch.repository.ts (8)

24-24: Good import addition for logging functionality.

Adding the Logger import is essential for enabling logging capabilities in the repository.


28-28: Good type import for better type safety.

Using the specific Indices_PutMapping_Response type enhances type safety when working with OpenSearch responses.


43-43: Proper logger initialization with class context.

Initializing the logger with the class name follows NestJS best practices and helps with log filtering and organization.


51-76: Well-structured try-catch block with detailed logging.

The implementation properly wraps the index creation operation in a try-catch block with comprehensive logging.


82-90: Comprehensive error logging with proper error propagation.

The error logging captures both the error message and detailed OpenSearch error information. Re-throwing the error after logging is the correct approach to allow proper error handling up the call stack.


103-108: Well-typed response variable with proper try-catch structure.

The response variable is properly typed with Indices_PutMapping_Response and the mapping operation is correctly wrapped in a try block.


109-117: Good error handling with detailed logging.

The catch block provides comprehensive error logging for putMapping failures, capturing both the error message and detailed error information from OpenSearch.


119-119: Good improvement to return the response.

Returning the response from the putMappings method allows callers to access the operation results if needed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/api/src/common/repositories/opensearch.repository.ts (1)

51-96: 🛠️ Refactor suggestion

Consider consistent error handling across the repository

You've added error handling for createIndex and putMappings, but other methods like createData, getData, scroll, etc. don't have similar error handling patterns with logging.

Consider adding similar try-catch blocks with logging to all operations that interact with OpenSearch for consistency and better observability.

What are best practices for error handling in NestJS applications?
♻️ Duplicate comments (1)
apps/api/src/common/repositories/opensearch.repository.ts (1)

51-91: ⚠️ Potential issue

Error handling still has an issue with control flow

While you've correctly added try-catch with proper logging and error re-throwing, the putAlias operation (lines 92-95) remains outside the try-catch block. If index creation fails, the code will still attempt to execute putAlias and likely fail again.

Consider one of these approaches:

  async createIndex({ index }: CreateIndexDto) {
    const indexName = 'channel_' + index;
    try {
      const response = await this.opensearchClient.indices.create({
        index: indexName,
        body: {
          // ... existing settings ...
        },
      });
      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
      if (response) {
        this.logger.log(
          `Index created successfully: ${JSON.stringify(response.body, null, 2)}`,
        );
      }
+     
+     await this.opensearchClient.indices.putAlias({
+       index: indexName,
+       name: index,
+     });
+     this.logger.log(`Alias created successfully for index: ${indexName}, alias: ${index}`);
    } catch (error) {
      this.logger.log(`Error creating index: ${error}`);
      if (error?.meta?.body) {
        this.logger.log(
          `OpenSearch error details:${JSON.stringify(error.meta.body, null, 2)}`,
        );
      }
      throw error;
    }
-   await this.opensearchClient.indices.putAlias({
-     index: indexName,
-     name: index,
-   });
  }
🧹 Nitpick comments (2)
apps/api/src/common/repositories/opensearch.repository.ts (2)

78-82: Remove unnecessary conditional check

The condition if (response) is redundant. If the OpenSearch operation fails, it will throw an exception caught by the catch block. The response will always be truthy at this point.

-      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
-      if (response) {
        this.logger.log(
          `Index created successfully: ${JSON.stringify(response.body, null, 2)}`,
        );
-      }

92-95: Add logging for putAlias operation

Currently, you've added logging for index creation but not for the alias creation. For consistency, you should also log the result of the putAlias operation.

  await this.opensearchClient.indices.putAlias({
    index: indexName,
    name: index,
  });
+ this.logger.log(`Alias created successfully for index: ${indexName}, alias: ${index}`);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0625ac2 and 0848f49.

📒 Files selected for processing (2)
  • apps/api/package.json (1 hunks)
  • apps/api/src/common/repositories/opensearch.repository.ts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (4)
apps/api/package.json (1)

4-4:

❓ Verification inconclusive

Project type updated to ESM: Consider the implications

Adding "type": "module" changes the project from CommonJS to ECMAScript Modules. This is a significant architectural change that affects how modules are imported and exported throughout the codebase.


🏁 Script executed:

#!/bin/bash
# Check for potential ESM compatibility issues by looking for CommonJS patterns
echo "Checking for CommonJS require statements that need to be converted to import..."
rg "require\(" --type ts

echo "Checking for module.exports patterns that need to be converted to export..."
rg "module\.exports" --type ts

echo "Checking for dynamic imports that might need special handling in ESM..."
rg "require\.resolve" --type ts

Length of output: 850


ESM Transition: Verify and Update CommonJS Usage

The addition of "type": "module" in apps/api/package.json clearly marks the project as ESM, which impacts how modules are imported/exported. However, our verification found several CommonJS patterns in the codebase that could lead to runtime issues under ESM:

  • Configuration and Setup Files:

    • apps/web/jest.setup.ts contains a require('resize-observer-polyfill') which might need to be replaced with an ESM-compatible alternative or handled via dynamic import.
    • apps/web/tailwind.config.ts uses require('@ufb/tailwindcss') and require('tailwind-scrollbar-hide') — ensure these usages are either safe in an ESM context or updated accordingly.
  • Action Required:
    Please verify that these instances are intentionally left as-is (for compatibility with specific tooling) or update them to use ESM syntax. Review how these files are executed (e.g., via bundlers or Node with interop settings) to avoid unexpected issues.

apps/api/src/common/repositories/opensearch.repository.ts (3)

24-24: LGTM: Good addition of Logger

Adding a Logger instance is a good practice for tracking operations in the repository. This aligns with the PR objective of adding logging when creating channel indexes.

Also applies to: 43-43


28-28: LGTM: Proper typing for the response

Adding the explicit type import for Indices_PutMapping_Response improves type safety in the codebase.


104-120: LGTM: Good implementation of error handling and response handling

The implementation for putMappings now correctly:

  1. Captures and logs errors with detailed information
  2. Properly types and returns the response
  3. Re-throws errors after logging them

This allows callers to handle errors appropriately and provides valuable debugging information.

Copy link
Contributor

@chiol chiol left a comment

Choose a reason for hiding this comment

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

👍🏼

@jihun jihun merged commit 4190f39 into dev Apr 14, 2025
7 checks passed
@jihun jihun deleted the feat/add-field-index-log branch April 14, 2025 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants