Skip to content
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

feat/be/hardware monitor notifications #1037

Merged
merged 9 commits into from
Oct 26, 2024

Conversation

ajhollid
Copy link
Collaborator

@ajhollid ajhollid commented Oct 23, 2024

This PR implements sending notifcations when thresholds are exceeded for hardware monitors

  • Add hardware threshold fields to Monitor model
    • Updated BE validation to allow for threshold fields when creating a Monitor
  • Implement sending email on threshold violation
    • Added an email template for threshold violations
    • Added templates to lookup object in EmailService
    • Added a method to handle hardware updates
    • Refactored the handleNotifications method to take a config object instead of multiple parameters
      • handleNotifications can now handle arbirtary templates

Copy link

coderabbitai bot commented Oct 23, 2024

Walkthrough

This pull request includes several changes across multiple files. Key modifications involve renaming a schema from discSchema to diskSchema, adding a thresholds field to the MonitorSchema, implementing a new email template for threshold violations, and restructuring methods in the NetworkService class to enhance notification handling. Additionally, a new property for resource usage thresholds is added to the validation schema for monitor creation. These changes collectively improve the functionality and modularity of the service.

Changes

File Change Summary
Server/db/models/HardwareCheck.js Renamed discSchema to diskSchema and updated HardwareCheckSchema to reflect this change.
Server/db/models/Monitor.js Added thresholds field to MonitorSchema as an object with properties: usage_cpu, usage_memory, usage_disk.
Server/service/emailService.js Introduced thresholdViolatedTemplate in templateLookup for handling threshold violation notifications.
Server/service/networkService.js Updated method signatures in NetworkService: modified handleNotification, handleStatusUpdate, and added handleHardwareUpdate.
Server/templates/thresholdViolated.mjml Added new MJML template for threshold violation notifications.
Server/validation/joi.js Added thresholds property to createMonitorBodyValidation schema for resource usage thresholds.

Possibly related PRs

  • feat/be/hardware-checks-model references #985 #996: This PR introduces a new Mongoose schema for hardware checks, which includes a discSchema. The main PR modifies the naming of a schema from discSchema to diskSchema, indicating a direct relationship in the schema definitions.

Suggested reviewers

  • marcelluscaio
  • jennifer-gan

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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 resolve resolve all the CodeRabbit review comments.
  • @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.

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.

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: 10

🧹 Outside diff range and nitpick comments (5)
Server/db/models/Monitor.js (1)

50-57: Consider adding default threshold values, fam!

Since this is for hardware monitoring, it might be helpful to set some sensible default threshold values (like 80% or 90%) to help users get started quickly.

Example implementation:

 thresholds: {
   type: {
     usage_cpu: { 
       type: Number,
+      default: 90
     },
     usage_memory: { 
       type: Number,
+      default: 90
     },
     usage_disk: { 
       type: Number,
+      default: 90
     },
   },
   _id: false,
 },
Server/templates/thresholdViolated.mjml (1)

2-9: Yo! The head section needs some accessibility improvements, eh?

While the font and styling look clean, we should enhance accessibility by adding:

  • A default background color
  • Minimum contrast ratios
  • Fallback system fonts

Here's how to beef it up:

 <mj-head>
   <mj-font name="Roboto" href="https://fonts.googleapis.com/css?family=Roboto:300,500"></mj-font>
   <mj-attributes>
-    <mj-all font-family="Roboto, Helvetica, sans-serif"></mj-all>
+    <mj-all font-family="Roboto, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, sans-serif"></mj-all>
     <mj-text font-weight="300" font-size="16px" color="#616161" line-height="24px"></mj-text>
-    <mj-section padding="0px"></mj-section>
+    <mj-section padding="0px" background-color="#ffffff"></mj-section>
   </mj-attributes>
 </mj-head>
Server/db/models/HardwareCheck.js (1)

Line range hint 19-51: Yo, let's talk about that performance game! 💪

Since we're dealing with hardware metrics that could grow significantly over time, consider:

  1. Adding TTL indexes for automatic data cleanup
  2. Implementing data aggregation for historical metrics
  3. Setting up compound indexes for common query patterns (e.g., monitorId + timestamps)

Example TTL index implementation:

HardwareCheckSchema.index({ createdAt: 1 }, { expireAfterSeconds: 30 * 24 * 60 * 60 }); // 30 days retention
Server/service/emailService.js (2)

Line range hint 36-46: Strengthen error handling in loadTemplate method

Mom's spaghetti moment! 🍝 The current error handling might lead to silent failures. When template loading fails, we log the error but return undefined, which could cause issues downstream.

Consider this improvement:

 this.loadTemplate = (templateName) => {
   try {
     const templatePath = this.path.join(
       __dirname,
       `../templates/${templateName}.mjml`
     );
     const templateContent = this.fs.readFileSync(templatePath, "utf8");
     return this.compile(templateContent);
   } catch (error) {
     this.logger.error("Error loading Email templates", {
       error,
       service: this.SERVICE_NAME,
     });
+    throw new Error(`Failed to load template: ${templateName}`);
   }
 };

Line range hint 7-7: Improve code organization and configuration management

Knees weak! 🤔 A few organizational improvements could make this code more maintainable:

  1. Move SERVICE_NAME into the class as a static property
  2. Make template paths configurable
  3. Separate email config setup into its own method

Here's how we could refactor this:

-const SERVICE_NAME = "EmailService";

class EmailService {
+  static SERVICE_NAME = "EmailService";
+  static TEMPLATE_DIR = "../templates";

+  #initializeTemplates() {
     this.loadTemplate = (templateName) => {
       try {
         const templatePath = this.path.join(
           __dirname,
-          `../templates/${templateName}.mjml`
+          `${EmailService.TEMPLATE_DIR}/${templateName}.mjml`
         );
         // ... rest of the code
       } catch (error) {
         this.logger.error("Error loading Email templates", {
           error,
-          service: this.SERVICE_NAME,
+          service: EmailService.SERVICE_NAME,
         });
       }
     };
   }

Also applies to: 36-46

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8d44e9c and 8d9803f.

📒 Files selected for processing (6)
  • Server/db/models/HardwareCheck.js (2 hunks)
  • Server/db/models/Monitor.js (1 hunks)
  • Server/service/emailService.js (1 hunks)
  • Server/service/networkService.js (6 hunks)
  • Server/templates/thresholdViolated.mjml (1 hunks)
  • Server/validation/joi.js (1 hunks)
🧰 Additional context used
🪛 Biome
Server/service/networkService.js

[error] 107-107: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

🔇 Additional comments (5)
Server/db/models/Monitor.js (1)

50-57: Verify the impact on existing monitors, yo!

Since we're adding a new field to the schema, let's make sure existing monitors won't be affected.

✅ Verification successful

The initial search didn't give us enough context. Let's look for more specific usage patterns of monitors and thresholds to understand the potential impact better. Yo, we need to make sure we're not dropping any spaghetti here! 🍝


Yo, check it out! After analyzing the codebase like mom's spaghetti recipe, I can drop this hot response:

No worries about existing monitors, fam! The thresholds field is safe to add

The schema change is backward compatible because:

  1. The new thresholds field is optional (not required)
  2. The field is only used in networkService.js with proper null checks
  3. Existing monitors without thresholds will continue to work as the code has a defensive check:
if (thresholds === undefined) {
    return;
}

The implementation gracefully handles both old and new monitor formats, so there's no risk of breaking existing monitors. It's cleaner than mom's kitchen! 🍝

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for existing hardware monitors that might be affected

# Look for existing hardware monitors in the codebase
rg -l "type.*hardware" --type js

# Check for any hardcoded threshold values
rg -i "threshold.*hardware" --type js

Length of output: 119


Script:

#!/bin/bash
# Let's dig deeper into the Monitor schema and its usage

# Check for Monitor schema usage and references
rg -A 5 "new Monitor|Monitor\." --type js

# Look for any code handling monitor thresholds
rg -A 3 "thresholds?" --type js

# Check for any monitor-related tests
fd "monitor" -e test.js -x cat {}

# Look for any monitor creation or updates
ast-grep --pattern 'await Monitor.create($_)'

Length of output: 66520

Server/templates/thresholdViolated.mjml (1)

1-40: Verify template variable usage across the codebase

Let's ensure the template variables are consistently used throughout the notification system.

✅ Verification successful

Let me gather more specific information about how these template variables are used in the email service.

The above will help us understand exactly how these template variables are being passed to the email template. Let's see what we find in the actual implementation.


Let me check one more crucial piece - how the context is being populated for this template.

I'm nervous about making sure we catch all the places where these template variables are being set! 😰


Template variables are properly aligned with the code implementation

Yo, after checking the codebase with sweaty palms and racing heart, I can confirm that the template variables (message, cpu, memory, disk) in thresholdViolated.mjml are perfectly matched with the context object being populated in networkService.js. The implementation:

  • Sets a base message for all threshold violations
  • Conditionally adds cpu, memory, and disk variables only when their respective thresholds are exceeded
  • Properly formats the values with percentages for display

The template's Handlebars conditionals ({{#if}}) handle the optional nature of these variables like mom's spaghetti - they're ready when they need to be! 🍝

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for template variable usage in the codebase
echo "Checking template variable usage..."
rg -l "message|cpu|disk|memory" --type js

# Look for email service integration
echo "Checking email service integration..."
rg "thresholdViolated" --type js

Length of output: 3086


Script:

#!/bin/bash
# Check the email service implementation for template variable usage
echo "Checking email service implementation..."
rg -A 10 "thresholdViolated" Server/service/emailService.js

# Check the network service for how these variables are populated
echo "Checking network service implementation..."
rg -A 10 "thresholdViolatedTemplate" Server/service/networkService.js

Length of output: 1053


Script:

#!/bin/bash
# Search for where the context object is being created for threshold violations
echo "Checking context population..."
rg -B 5 -A 10 "context.*thresholdViolated" Server/service/networkService.js

# Also check for any hardware monitoring related code that might set these variables
echo "Checking hardware monitoring implementation..."
rg -B 5 -A 10 "cpu|memory|disk.*threshold" Server/service/networkService.js

Length of output: 2594

Server/db/models/HardwareCheck.js (2)

Line range hint 19-26: Yo dawg, that schema rename is straight fire! 🔥

The correction from discSchema to diskSchema makes perfect sense - ain't nobody got time for typos in our code! This change improves code readability and maintains consistency with standard hardware terminology.


49-51: Schema reference update looking clean! ✨

The corresponding update to use [diskSchema] in the HardwareCheckSchema keeps everything in sync. The array type indicates multiple disk monitoring support - that's some next-level thinking right there!

Server/service/networkService.js (1)

371-385: Ensure consistent units for usage_percent values

In the fake hardware data, usage_percent is set to 1, which may represent 100%. Ensure that usage_percent values are consistently represented as fractions (e.g., 0.75) or percentages (e.g., 75), and adjust the logic accordingly.

Comment on lines +50 to +57
thresholds: {
type: {
usage_cpu: { type: Number },
usage_memory: { type: Number },
usage_disk: { type: Number },
},
_id: false,
},
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Yo! Add validation and documentation for threshold values, dawg!

The thresholds implementation looks solid, but we should add some validation to ensure the values make sense. Here's what's missing:

  1. Validation to ensure threshold values are between 0-100 (as they represent percentages)
  2. Documentation of the expected value ranges

Here's how we can beef this up:

 thresholds: {
   type: {
-    usage_cpu: { type: Number },
-    usage_memory: { type: Number },
-    usage_disk: { type: Number },
+    usage_cpu: { 
+      type: Number,
+      min: [0, 'CPU threshold cannot be negative'],
+      max: [100, 'CPU threshold cannot exceed 100%']
+    },
+    usage_memory: { 
+      type: Number,
+      min: [0, 'Memory threshold cannot be negative'],
+      max: [100, 'Memory threshold cannot exceed 100%']
+    },
+    usage_disk: { 
+      type: Number,
+      min: [0, 'Disk threshold cannot be negative'],
+      max: [100, 'Disk threshold cannot exceed 100%']
+    },
   },
   _id: false,
 },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
thresholds: {
type: {
usage_cpu: { type: Number },
usage_memory: { type: Number },
usage_disk: { type: Number },
},
_id: false,
},
thresholds: {
type: {
usage_cpu: {
type: Number,
min: [0, 'CPU threshold cannot be negative'],
max: [100, 'CPU threshold cannot exceed 100%']
},
usage_memory: {
type: Number,
min: [0, 'Memory threshold cannot be negative'],
max: [100, 'Memory threshold cannot exceed 100%']
},
usage_disk: {
type: Number,
min: [0, 'Disk threshold cannot be negative'],
max: [100, 'Disk threshold cannot exceed 100%']
},
},
_id: false,
},

Comment on lines +22 to +35
{{#if cpu}}
{{cpu}}
{{/if}}
</mj-text>
<mj-text font-weight="500" padding="0px" font-size="18px">
{{#if disk}}
{{disk}}
{{/if}}
</mj-text>
<mj-text font-weight="500" padding="0px" font-size="18px">
{{#if memory}}
{{memory}}
{{/if}}
</mj-text>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Heads up! The conditional blocks need some error handling, buddy!

The template should gracefully handle cases where the metrics are present but empty or undefined.

Add null checks and default messages:

-          {{#if cpu}}
+          {{#if cpu}}
+            {{#if (ne cpu '')}}
               {{cpu}}
+            {{else}}
+              CPU usage data unavailable
+            {{/if}}
           {{/if}}

-          {{#if disk}}
+          {{#if disk}}
+            {{#if (ne disk '')}}
               {{disk}}
+            {{else}}
+              Disk usage data unavailable
+            {{/if}}
           {{/if}}

-          {{#if memory}}
+          {{#if memory}}
+            {{#if (ne memory '')}}
               {{memory}}
+            {{else}}
+              Memory usage data unavailable
+            {{/if}}
           {{/if}}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{#if cpu}}
{{cpu}}
{{/if}}
</mj-text>
<mj-text font-weight="500" padding="0px" font-size="18px">
{{#if disk}}
{{disk}}
{{/if}}
</mj-text>
<mj-text font-weight="500" padding="0px" font-size="18px">
{{#if memory}}
{{memory}}
{{/if}}
</mj-text>
{{#if cpu}}
{{#if (ne cpu '')}}
{{cpu}}
{{else}}
CPU usage data unavailable
{{/if}}
{{/if}}
</mj-text>
<mj-text font-weight="500" padding="0px" font-size="18px">
{{#if disk}}
{{#if (ne disk '')}}
{{disk}}
{{else}}
Disk usage data unavailable
{{/if}}
{{/if}}
</mj-text>
<mj-text font-weight="500" padding="0px" font-size="18px">
{{#if memory}}
{{#if (ne memory '')}}
{{memory}}
{{else}}
Memory usage data unavailable
{{/if}}
{{/if}}
</mj-text>

Comment on lines +11 to +17
<mj-section padding="20px 0">
<mj-column width="100%">
<mj-text align="left" font-size="10px">
Message from BlueWave Uptime Service
</mj-text>
</mj-column>
<mj-column width="45%" padding-top="20px">
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

The layout's looking fresh, but let's make it more responsive!

The current fixed width might not play nice on all devices. Consider:

  • Using relative units for padding
  • Adding media queries for mobile optimization

Try this improvement:

-    <mj-section padding="20px 0">
+    <mj-section padding="4% 2%">
       <mj-column width="100%">
         <mj-text align="left" font-size="10px">
           Message from BlueWave Uptime Service
         </mj-text>
       </mj-column>
-      <mj-column width="45%" padding-top="20px">
+      <mj-column width="100%" padding-top="20px">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<mj-section padding="20px 0">
<mj-column width="100%">
<mj-text align="left" font-size="10px">
Message from BlueWave Uptime Service
</mj-text>
</mj-column>
<mj-column width="45%" padding-top="20px">
<mj-section padding="4% 2%">
<mj-column width="100%">
<mj-text align="left" font-size="10px">
Message from BlueWave Uptime Service
</mj-text>
</mj-column>
<mj-column width="100%" padding-top="20px">

@@ -63,6 +63,7 @@ class EmailService {
serverIsDownTemplate: this.loadTemplate("serverIsDown"),
serverIsUpTemplate: this.loadTemplate("serverIsUp"),
passwordResetTemplate: this.loadTemplate("passwordReset"),
thresholdViolatedTemplate: this.loadTemplate("thresholdViolated"),
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider lazy loading for less frequently used templates

Yo! While adding the thresholdViolatedTemplate is solid, I noticed we're loading all templates at initialization. The existing TODO comment suggests loading less used templates on demand. Since hardware threshold notifications might be frequent, this template is probably fine to load upfront, but we should consider implementing lazy loading for others to improve startup time.

Here's a pattern we could use:

// In templateLookup
get welcomeEmailTemplate() {
  if (!this._welcomeEmailTemplate) {
    this._welcomeEmailTemplate = this.loadTemplate("welcomeEmail");
  }
  return this._welcomeEmailTemplate;
}

Comment on lines +225 to +229
thresholds: joi.object().keys({
usage_cpu: joi.number(),
usage_memory: joi.number(),
usage_disk: joi.number(),
}),
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

Yo, check it out! After analyzing the code like mom's spaghetti, I'm ready to drop these bars! 🎤

Threshold validation needs to match the actual implementation, eh! 🍁

Looking at networkService.js, I noticed the thresholds are being used as decimal values (0-1) internally, but our validation schema suggests percentages (0-100). This mismatch could cause some serious confusion, buddy!

Here's what's going down in the service:

if (cpuUsage > thresholds.usage_cpu) {
    context.cpu = `CPU USAGE: ${cpuUsage * 100}% > ${thresholds.usage_cpu * 100}%`;
}

Let's modify the validation to match this implementation:

 thresholds: joi.object().keys({
-    usage_cpu: joi.number(),
-    usage_memory: joi.number(),
-    usage_disk: joi.number(),
+    usage_cpu: joi.number().min(0).max(1).precision(4)
+      .description('CPU usage threshold as decimal (0-1)'),
+    usage_memory: joi.number().min(0).max(1).precision(4)
+      .description('Memory usage threshold as decimal (0-1)'),
+    usage_disk: joi.number().min(0).max(1).precision(4)
+      .description('Disk usage threshold as decimal (0-1)'),
 }),

The service multiplies these values by 100 when displaying them, so we should keep the validation in sync with the actual implementation.

🔗 Analysis chain

Yo dawg, we need to beef up these threshold validations! 🔥

The current validation schema for thresholds needs some constraints to prevent invalid values. Consider these improvements:

  1. CPU and memory usage should be percentages between 0 and 100
  2. Disk usage validation should handle different measurement units
  3. All values should be non-negative

Here's a suggested improvement to make the validation more robust:

 thresholds: joi.object().keys({
-    usage_cpu: joi.number(),
-    usage_memory: joi.number(),
-    usage_disk: joi.number(),
+    usage_cpu: joi.number().min(0).max(100).precision(2)
+      .description('CPU usage threshold as percentage (0-100)'),
+    usage_memory: joi.number().min(0).max(100).precision(2)
+      .description('Memory usage threshold as percentage (0-100)'),
+    usage_disk: joi.number().min(0).precision(2)
+      .description('Disk usage threshold in percentage or absolute value'),
+    usage_disk_unit: joi.string().valid('percentage', 'GB', 'TB')
+      .default('percentage')
+      .description('Unit for disk usage threshold'),
 }),

Let's check if there are any existing monitors with threshold values:


Let me check the network service implementation to understand how these thresholds are used.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing monitor configurations with thresholds
rg -l 'thresholds.*usage_' --type js --type json

Length of output: 83


Script:

#!/bin/bash
# Check the usage of thresholds in networkService.js
rg -A 5 -B 5 'thresholds.*usage_' Server/service/networkService.js

Length of output: 839


Script:

#!/bin/bash
# Look for Monitor model schema to verify threshold fields
ast-grep --pattern 'const MonitorSchema = new Schema({
  $$$
})'

Length of output: 66


Script:

#!/bin/bash
# Search for any monitor-related tests that might have threshold examples
rg 'test|describe|it.*monitor.*threshold' --type js

Length of output: 16706

@@ -369,7 +429,7 @@ class NetworkService {
};
this.logAndStoreCheck(nullData, this.db.createHardwareCheck);
} finally {
this.handleStatusUpdate(job, isAlive);
this.handleStatusUpdate(job, isAlive, hardwareData);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

This opportunity comes once: Await the async call to handleStatusUpdate

In handleHardware, you're calling the async function handleStatusUpdate without awaiting it. To maintain proper flow, consider awaiting this call.

Apply this diff to resolve the issue:

-      this.handleStatusUpdate(job, isAlive, hardwareData);
+      await this.handleStatusUpdate(job, isAlive, hardwareData);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.handleStatusUpdate(job, isAlive, hardwareData);
await this.handleStatusUpdate(job, isAlive, hardwareData);

subject:
(subject = `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`),
};
this.handleNotification(config);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Don't miss your chance: Await the async call to handleNotification

In handleStatusUpdate, handleNotification is an async function that's called without awaiting. To ensure notifications are properly handled, you should await this call.

Apply this diff to resolve the issue:

-          this.handleNotification(config);
+          await this.handleNotification(config);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.handleNotification(config);
await this.handleNotification(config);

context: context,
subject: `Threshold Violated for ${monitor.name}`,
};
this.handleNotification(config);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Seize the moment: Await the async call to handleNotification

In handleHardwareUpdate, handleNotification is an async function called without awaiting. To ensure notifications are sent, you should await this call.

Apply this diff to resolve the issue:

-      this.handleNotification(config);
+      await this.handleNotification(config);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.handleNotification(config);
await this.handleNotification(config);

template: isAlive === true ? "serverIsUpTemplate" : "serverIsDownTemplate",
context: { monitorName: monitor.name, monitorUrl: monitor.url },
subject:
(subject = `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Snap back to reality: Correct the assignment in the object literal

There's an incorrect assignment within the object literal on line 107. Replace (subject = ...) with subject: ... to fix the syntax error.

Apply this diff to resolve the issue:

-      (subject = `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`),
+      subject: `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
(subject = `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`),
subject: `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`,
🧰 Tools
🪛 Biome

[error] 107-107: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

}
}
if (monitor.type === this.TYPE_HARDWARE) {
this.handleHardwareUpdate(monitor, hardwareData);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

One shot: Await the async call to handleHardwareUpdate

The handleHardwareUpdate function is async but is called without awaiting. To handle hardware updates correctly, consider awaiting this call.

Apply this diff to resolve the issue:

-          this.handleHardwareUpdate(monitor, hardwareData);
+          await this.handleHardwareUpdate(monitor, hardwareData);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.handleHardwareUpdate(monitor, hardwareData);
await this.handleHardwareUpdate(monitor, hardwareData);

context: context,
subject: `Threshold Violated for ${monitor.name}`,
};
this.handleNotification(config);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need await here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We don't need to await here as the result of handleNotification isn't needed for anything, we just want to fire off the notification and then keep executing code. If the notification fails for whatever reason we want to keep executing

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 and nitpick comments (3)
Server/service/networkService.js (3)

155-163: Lose yourself in the math: Consider formatting those percentages! 📊

The percentage calculations in the messages might be clearer with fixed decimal places.

Try this enhancement:

-     context.cpu = `CPU USAGE: ${cpuUsage * 100}% > ${thresholds.usage_cpu * 100}%`;
+     context.cpu = `CPU USAGE: ${(cpuUsage * 100).toFixed(1)}% > ${(thresholds.usage_cpu * 100).toFixed(1)}%`;
-     context.memory = `MEMORY USAGE: ${memoryUsage * 100}% > ${thresholds.usage_memory * 100}%`;
+     context.memory = `MEMORY USAGE: ${(memoryUsage * 100).toFixed(1)}% > ${(thresholds.usage_memory * 100).toFixed(1)}%`;
-     context.disk = `DISK USAGE: ${diskUsage * 100}% > ${thresholds.usage_disk * 100}%`;
+     context.disk = `DISK USAGE: ${(diskUsage * 100).toFixed(1)}% > ${(thresholds.usage_disk * 100).toFixed(1)}%`;

373-387: Snap back to reality: Document that test data! 📝

The simulated hardware data is setting all usage percentages to 1 (100%), which will always trigger threshold violations. This needs documentation.

Add a comment explaining the test values:

+ // Test data: Setting all usage_percent values to 1 (100%) to simulate threshold violations
  cpu: {
    physical_core: 1,
    logical_core: 1,
    frequency: 266,
    temperature: null,
    free_percent: null,
    usage_percent: 1,  // 100% usage
  },

126-173: One shot opportunity: Consider threshold granularity! 🎯

The current implementation treats all threshold violations equally. Consider adding severity levels or different notification frequencies based on how much the thresholds are exceeded.

Suggestions:

  1. Add warning thresholds (e.g., 80%) in addition to critical thresholds
  2. Implement cooldown periods between notifications
  3. Add severity levels based on the percentage over threshold
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8d9803f and 50c6e32.

📒 Files selected for processing (3)
  • Server/db/models/HardwareCheck.js (3 hunks)
  • Server/service/emailService.js (1 hunks)
  • Server/service/networkService.js (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • Server/db/models/HardwareCheck.js
  • Server/service/emailService.js
🔇 Additional comments (2)
Server/service/networkService.js (2)

Line range hint 37-65: Yo, this refactor is straight fire! 🔥

The switch to a config object pattern makes the code more maintainable and flexible. The documentation is on point with clear parameter descriptions.


103-108: ⚠️ Potential issue

Mom's spaghetti moment: Fix that object literal syntax! 🍝

There's a syntax error in the config object creation. The subject property uses incorrect assignment syntax.

Here's the fix:

-       subject = `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`,
+       subject: `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`

Likely invalid or redundant comment.

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