LinuxMonitor 1.5.3__tar.gz → 1.5.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: LinuxMonitor
3
- Version: 1.5.3
3
+ Version: 1.5.5
4
4
  Summary: Get information and warning status of Linux server like service, port, ping, ssl certificate, disk/folder/cpu/ram/swap usage, ip connection, ... (Python and shell library, Linux ONLY)
5
5
  Home-page: https://github.com/QuentinCG/Linux-Monitor-Python-Library
6
6
  Author: Quentin Comte-Gaz
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: LinuxMonitor
3
- Version: 1.5.3
3
+ Version: 1.5.5
4
4
  Summary: Get information and warning status of Linux server like service, port, ping, ssl certificate, disk/folder/cpu/ram/swap usage, ip connection, ... (Python and shell library, Linux ONLY)
5
5
  Home-page: https://github.com/QuentinCG/Linux-Monitor-Python-Library
6
6
  Author: Quentin Comte-Gaz
@@ -33,7 +33,7 @@ __email__ = "quentin@comte-gaz.com"
33
33
  __license__ = "MIT License"
34
34
  __copyright__ = "Copyright Quentin Comte-Gaz (2024)"
35
35
  __python_version__ = "3.+"
36
- __version__ = "1.5.3 (2024/10/27)"
36
+ __version__ = "1.5.5 (2024/10/27)"
37
37
  __status__ = "Usable for any Linux project"
38
38
 
39
39
  import json
@@ -435,7 +435,7 @@ class LinuxMonitor:
435
435
 
436
436
  def _get_folder_size_in_bytes(self, start_path: str = '.') -> float:
437
437
  """
438
- Get the size of a folder in bytes.
438
+ Get the size of a folder in bytes, including hard-linked files only once.
439
439
 
440
440
  :param start_path: The path to the folder.
441
441
 
@@ -443,13 +443,23 @@ class LinuxMonitor:
443
443
  """
444
444
  try:
445
445
  total_size = 0
446
+ seen_inodes: set[int] = set() # Track inodes to avoid double-counting hard-linked files
447
+
446
448
  for dirpath, _, filenames in os.walk(start_path):
447
449
  for f in filenames:
448
450
  fp = os.path.join(dirpath, f)
451
+ try:
452
+ # Get file information
453
+ stat_info = os.stat(fp)
454
+ inode = stat_info.st_ino
455
+
456
+ # Include file size only if we haven't seen this inode before
457
+ if inode not in seen_inodes:
458
+ seen_inodes.add(inode)
459
+ total_size += stat_info.st_size
460
+ except FileNotFoundError:
461
+ logging.warning(f"File {fp} not found. It may be a broken link.")
449
462
 
450
- # Skip if it is symbolic link
451
- if not os.path.islink(fp):
452
- total_size += os.path.getsize(fp)
453
463
  logging.info(msg=f"Total size of folder {start_path}: {total_size} bytes")
454
464
  return total_size
455
465
  except Exception as e:
@@ -587,6 +597,10 @@ class LinuxMonitor:
587
597
  """
588
598
  out_msg: str = ""
589
599
  try:
600
+ if display_only_if_critical and self.critical_cpu_percent > 100:
601
+ # There is no need to check for showing msg only if critical and the critical percentage is greater than the max possible
602
+ return out_msg
603
+
590
604
  # Getting average CPU usage for the last second
591
605
  cpu_percent: float = psutil.cpu_percent(percpu=False)
592
606
 
@@ -599,9 +613,9 @@ class LinuxMonitor:
599
613
  out_msg = f"- 🚨 **Critical CPU usage**:\n- **{cpu_percent:.2f}%** used on {cpu_cores} core of {cpu_info:.2f}GHz ({cpu_name})\n⚠️ **Check what is using so much CPU power** ⚠️"
600
614
 
601
615
  # If there is a critical CPU usage, we also display the top 10 processes consuming the most CPU
602
- out_msg += "\n" + self.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=False, max_processes=10)
616
+ out_msg += "\n" + asyncio.run(self.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=False, max_processes=10)) # type: ignore
603
617
 
604
- logging.warning(msg=out_msg)
618
+ logging.warning(msg=out_msg) # type: ignore
605
619
  elif not display_only_if_critical:
606
620
  if cpu_percent >= self.warning_cpu_percent:
607
621
  icon = "⚠️"
@@ -628,6 +642,10 @@ class LinuxMonitor:
628
642
  """
629
643
  out_msg: str = ""
630
644
  try:
645
+ if display_only_if_critical and self.critical_ram_percent > 100:
646
+ # There is no need to check for showing msg only if critical and the critical percentage is greater than the max possible
647
+ return out_msg
648
+
631
649
  # Getting RAM usage
632
650
  ram = psutil.virtual_memory()
633
651
  total_ram: float = ram.total / (2**30)
@@ -638,9 +656,9 @@ class LinuxMonitor:
638
656
  out_msg = f"- 🚨 **Critical RAM usage**:\n- Total: {total_ram:.2f}GB\n- Used: {used_ram:.2f}GB ({percent_ram:.2f}%)\n- Free: {free_ram:.2f}GB\n⚠️ **Check what is using so much RAM** ⚠️"
639
657
 
640
658
  # If there is a critical RAM usage, we also display the top 10 processes consuming the most RAM
641
- out_msg += "\n" + self.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=True, max_processes=10)
659
+ out_msg += "\n" + asyncio.run(self.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=True, max_processes=10)) # type: ignore
642
660
 
643
- logging.warning(msg=out_msg)
661
+ logging.warning(msg=out_msg) # type: ignore
644
662
  elif not display_only_if_critical:
645
663
  if percent_ram >= self.warning_ram_percent:
646
664
  icon = "⚠️"
@@ -667,11 +685,15 @@ class LinuxMonitor:
667
685
  """
668
686
  out_msg: str = ""
669
687
  try:
688
+ if display_only_if_critical and self.critical_load_average_percent > 100:
689
+ # There is no need to check for showing msg only if critical and the critical percentage is greater than the max possible
690
+ return out_msg
691
+
670
692
  # Number of CPU cores
671
693
  num_cores: int = psutil.cpu_count()
672
694
 
673
695
  # Getting load average
674
- load_avg: Tuple[float] = psutil.getloadavg()
696
+ load_avg: Tuple[float] = psutil.getloadavg() # type: ignore
675
697
 
676
698
  # Getting an average of all 3 values
677
699
  avg_load_avg: float = 100 * sum(min(value, num_cores) for value in load_avg) / (len(load_avg) * num_cores)
@@ -680,9 +702,9 @@ class LinuxMonitor:
680
702
  out_msg = f"- 🚨 **High load average**: **{avg_load_avg:.2f}%**\n⚠️ **Check what is causing the high load average** ⚠️"
681
703
 
682
704
  # If there is a critical load average, we also display the top 10 processes consuming the most CPU
683
- out_msg += "\n" + self.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=False, max_processes=10)
705
+ out_msg += "\n" + asyncio.run(self.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=False, max_processes=10)) # type: ignore
684
706
 
685
- logging.warning(msg=out_msg)
707
+ logging.warning(msg=out_msg) # type: ignore
686
708
  elif not display_only_if_critical:
687
709
  if avg_load_avg >= self.warning_load_average_percent:
688
710
  icon = "⚠️"
@@ -709,6 +731,10 @@ class LinuxMonitor:
709
731
  """
710
732
  out_msg: str = ""
711
733
  try:
734
+ if display_only_if_critical and self.critical_swap_percent > 100:
735
+ # There is no need to check for showing msg only if critical and the critical percentage is greater than the max possible
736
+ return out_msg
737
+
712
738
  # Getting Swap usage
713
739
  swap = psutil.swap_memory()
714
740
  total_swap: float = swap.total / (2**30)
@@ -1548,7 +1574,7 @@ class LinuxMonitor:
1548
1574
 
1549
1575
  try:
1550
1576
  # Fetch the logs since the specified date
1551
- command: str = f"sudo last --ip --hostlast --time-format iso --since '{past_date}' | grep 'pts/'"
1577
+ command: str = f"sudo last --ip --hostlast --time-format iso --since '{past_date}' | grep 'pts/' || true"
1552
1578
  last_output: str = subprocess.check_output(
1553
1579
  args=command,
1554
1580
  shell=True,
@@ -2537,6 +2563,14 @@ class LinuxMonitor:
2537
2563
  out_msg += "\n"
2538
2564
  out_msg += msg
2539
2565
 
2566
+ # Load average
2567
+ if is_private:
2568
+ msg = self.check_load_average(display_only_if_critical=False)
2569
+ if msg != "":
2570
+ if out_msg != "":
2571
+ out_msg += "\n"
2572
+ out_msg += msg
2573
+
2540
2574
  # CPU
2541
2575
  if is_private:
2542
2576
  msg = self.check_cpu_usage(display_only_if_critical=False)
@@ -6,7 +6,7 @@ with io.open(file='README.md', mode='r', encoding='utf-8') as readme_file:
6
6
 
7
7
  setup(
8
8
  name="LinuxMonitor",
9
- version="1.5.3",
9
+ version="1.5.5",
10
10
  description="Get information and warning status of Linux server like service, port, ping, ssl certificate, disk/folder/cpu/ram/swap usage, ip connection, ... (Python and shell library, Linux ONLY)",
11
11
  long_description=readme,
12
12
  long_description_content_type="text/markdown",
File without changes
File without changes
File without changes