LinuxMonitor 1.4.7__tar.gz → 1.4.8__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.4.7
3
+ Version: 1.4.8
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.4.7
3
+ Version: 1.4.8
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
@@ -180,13 +180,13 @@ def main() -> None:
180
180
  if args.list_processes:
181
181
  handled = True
182
182
  print("Listing active processes (ordered by RAM usage)...")
183
- out_msg: str = asyncio.run(monitoring.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=True))
183
+ out_msg: str = asyncio.run(monitoring.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=True, max_processes=20))
184
184
  print(out_msg)
185
185
 
186
186
  if args.list_processes_order_by_cpu:
187
187
  handled = True
188
188
  print("Listing active processes (ordered by CPU usage)...")
189
- out_msg: str = asyncio.run(monitoring.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=False))
189
+ out_msg: str = asyncio.run(monitoring.get_ordered_processes(get_non_consuming_processes=False, order_by_ram=False, max_processes=20))
190
190
  print(out_msg)
191
191
 
192
192
  if args.kill_process is not None:
@@ -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.4.7 (2024/10/07)"
36
+ __version__ = "1.4.8 (2024/10/27)"
37
37
  __status__ = "Usable for any Linux project"
38
38
 
39
39
  import json
@@ -589,6 +589,10 @@ class LinuxMonitor:
589
589
 
590
590
  if cpu_percent > self.critical_cpu_percent:
591
591
  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** ⚠️"
592
+
593
+ # If there is a critical CPU usage, we also display the top 10 processes consuming the most CPU
594
+ out_msg += "\n" + self.get_ordered_processes(get_non_consuming_processes: False, order_by_ram=False, max_processes=10)
595
+
592
596
  logging.warning(msg=out_msg)
593
597
  elif not display_only_if_critical:
594
598
  if cpu_percent > self.warning_cpu_percent:
@@ -624,6 +628,10 @@ class LinuxMonitor:
624
628
  percent_ram: float = ram.percent
625
629
  if percent_ram > self.critical_ram_percent:
626
630
  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** ⚠️"
631
+
632
+ # If there is a critical RAM usage, we also display the top 10 processes consuming the most RAM
633
+ out_msg += "\n" + self.get_ordered_processes(get_non_consuming_processes: False, order_by_ram=True, max_processes=10)
634
+
627
635
  logging.warning(msg=out_msg)
628
636
  elif not display_only_if_critical:
629
637
  if percent_ram > self.warning_ram_percent:
@@ -1672,7 +1680,7 @@ class LinuxMonitor:
1672
1680
 
1673
1681
  #region Processes
1674
1682
 
1675
- async def get_ordered_processes(self, get_non_consuming_processes: bool = False, order_by_ram: bool = True) -> str:
1683
+ async def get_ordered_processes(self, get_non_consuming_processes: bool = False, order_by_ram: bool = False, max_processes: int = 10) -> str:
1676
1684
  """
1677
1685
  Get the ordered list of processes by memory and CPU usage.
1678
1686
 
@@ -1727,9 +1735,13 @@ class LinuxMonitor:
1727
1735
  proc['create_time']), reverse=True)
1728
1736
 
1729
1737
  full_res: str = ""
1738
+ count: int = max_processes
1730
1739
  for proc in processes: # type: ignore
1740
+ if count <= 0:
1741
+ break
1742
+
1731
1743
  if not get_non_consuming_processes and proc['cpu_percent'] == 0 and proc['memory'] == 0:
1732
- continue
1744
+ break
1733
1745
 
1734
1746
  res: str = f"- PID **{proc['pid']}**: {proc['name']} ("
1735
1747
 
@@ -1751,6 +1763,8 @@ class LinuxMonitor:
1751
1763
  full_res += "\n"
1752
1764
  full_res += res
1753
1765
 
1766
+ count -= 1
1767
+
1754
1768
  if full_res != "":
1755
1769
  full_res = f"# 🔄 Processes 🔄\n{full_res}"
1756
1770
 
@@ -1853,7 +1867,7 @@ class LinuxMonitor:
1853
1867
  network_usage: str = ""
1854
1868
 
1855
1869
  for interface in interfaces:
1856
- if interface in self.excluded_interfaces or interface not in stats:
1870
+ if interface not in stats or (any(re.match(pattern=pattern, string=interface) for pattern in self.excluded_interfaces)):
1857
1871
  continue
1858
1872
 
1859
1873
  ip_addresses = []
@@ -2053,11 +2067,135 @@ class LinuxMonitor:
2053
2067
 
2054
2068
  while True:
2055
2069
  out_msg: str = ""
2070
+ msg: str = ""
2056
2071
  logging.info(msg="-----------------------------------------------")
2057
2072
  logging.info(msg="Checking services status and all disk usage, CPU, RAM, Swap, CPU temperature and ping of websites periodically...")
2058
2073
  try:
2074
+ # CPU
2075
+ if is_private:
2076
+ msg = self.check_cpu_usage(display_only_if_critical=True)
2077
+ if msg != "":
2078
+ logging.warning(msg=msg)
2079
+ if datetime_last_cpu_usage_error_displayed is None or ((datetime.now() - datetime_last_cpu_usage_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2080
+ if out_msg != "":
2081
+ out_msg += "\n"
2082
+ out_msg += msg
2083
+ datetime_last_cpu_usage_error_displayed = datetime.now()
2084
+ else:
2085
+ logging.warning(msg="CPU usage critical but already notified less than 12 hours ago, not notifying...")
2086
+ elif datetime_last_cpu_usage_error_displayed is not None:
2087
+ msg = "✅ **CPU usage returned to normal state**"
2088
+ logging.info(msg=msg)
2089
+ if out_msg != "":
2090
+ out_msg += "\n"
2091
+ out_msg += msg
2092
+ datetime_last_cpu_usage_error_displayed = None
2093
+ else:
2094
+ logging.info(msg="- ✅ CPU usage is OK.")
2095
+
2096
+ # RAM
2097
+ if is_private:
2098
+ msg = self.check_ram_usage(display_only_if_critical=True)
2099
+ if msg != "":
2100
+ logging.warning(msg=msg)
2101
+ if datetime_last_ram_usage_error_displayed is None or ((datetime.now() - datetime_last_ram_usage_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2102
+ if out_msg != "":
2103
+ out_msg += "\n"
2104
+ out_msg += msg
2105
+ datetime_last_ram_usage_error_displayed = datetime.now()
2106
+ else:
2107
+ logging.warning(msg="RAM usage critical but already notified less than 12 hours ago, not notifying...")
2108
+ elif datetime_last_ram_usage_error_displayed is not None:
2109
+ msg = "✅ **RAM usage returned to normal state**"
2110
+ logging.info(msg=msg)
2111
+ if out_msg != "":
2112
+ out_msg += "\n"
2113
+ out_msg += msg
2114
+ datetime_last_ram_usage_error_displayed = None
2115
+ else:
2116
+ logging.info(msg="- ✅ RAM usage is OK.")
2117
+
2118
+ # Swap
2119
+ if is_private:
2120
+ msg = self.check_swap_usage(display_only_if_critical=True)
2121
+ if msg != "":
2122
+ logging.warning(msg=msg)
2123
+ if datetime_last_swap_usage_error_displayed is None or ((datetime.now() - datetime_last_swap_usage_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2124
+ if out_msg != "":
2125
+ out_msg += "\n"
2126
+ out_msg += msg
2127
+ datetime_last_swap_usage_error_displayed = datetime.now()
2128
+ else:
2129
+ logging.warning(msg="Swap usage critical but already notified less than 12 hours ago, not notifying...")
2130
+ elif datetime_last_swap_usage_error_displayed is not None:
2131
+ msg = "✅ **SWAP usage returned to normal state**"
2132
+ logging.info(msg=msg)
2133
+ if out_msg != "":
2134
+ out_msg += "\n"
2135
+ out_msg += msg
2136
+ datetime_last_swap_usage_error_displayed = None
2137
+ else:
2138
+ logging.info(msg="- ✅ Swap usage is OK.")
2139
+
2140
+ # CPU temperature
2141
+ if is_private:
2142
+ msg = self.check_cpu_temperature(display_only_if_critical=True)
2143
+ if msg != "":
2144
+ logging.warning(msg=msg)
2145
+ if datetime_last_cpu_temperature_error_displayed is None or ((datetime.now() - datetime_last_cpu_temperature_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2146
+ if out_msg != "":
2147
+ out_msg += "\n"
2148
+ out_msg += msg
2149
+ datetime_last_cpu_temperature_error_displayed = datetime.now()
2150
+ else:
2151
+ logging.warning(msg="CPU temperature critical but already notified less than 12 hours ago, not notifying...")
2152
+ elif datetime_last_cpu_temperature_error_displayed is not None:
2153
+ msg = "✅ **CPU temperature returned to normal state**"
2154
+ logging.info(msg=msg)
2155
+ if out_msg != "":
2156
+ out_msg += "\n"
2157
+ out_msg += msg
2158
+ datetime_last_cpu_temperature_error_displayed = None
2159
+ else:
2160
+ logging.info(msg="- ✅ CPU temperature is OK.")
2161
+
2162
+ # Uptime
2163
+ if is_private:
2164
+ if need_to_check_uptime:
2165
+ msg = self.check_uptime(display_only_if_critical=True)
2166
+ need_to_check_uptime = False
2167
+ if msg != "":
2168
+ logging.warning(msg=msg)
2169
+ if out_msg != "":
2170
+ out_msg += "\n"
2171
+ out_msg += msg
2172
+ else:
2173
+ logging.info(msg="- ✅ Uptime is OK.")
2174
+
2175
+ # User logins
2176
+ if is_private:
2177
+ msg = self.check_all_recent_user_logins(display_only_if_critical=True)
2178
+ if msg != "":
2179
+ logging.warning(msg=msg)
2180
+ if datetime_last_user_logins_error_displayed is None or ((datetime.now() - datetime_last_user_logins_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2181
+ if out_msg != "":
2182
+ out_msg += "\n"
2183
+ out_msg += msg
2184
+ datetime_last_user_logins_error_displayed = datetime.now()
2185
+ else:
2186
+ logging.warning(msg="User logins critical but already notified less than 12 hours ago, not notifying...")
2187
+ elif datetime_last_user_logins_error_displayed is not None:
2188
+ msg="✅ **Last user logins returned to normal state**"
2189
+ logging.info(msg=msg)
2190
+ if out_msg != "":
2191
+ out_msg += "\n"
2192
+ out_msg += msg
2193
+ datetime_last_user_logins_error_displayed = None
2194
+ else:
2195
+ logging.info(msg="- ✅ All user logins are OK.")
2196
+
2059
2197
  # Services status
2060
- msg: str = await self.check_all_services_status(is_private=is_private, display_only_if_critical=True)
2198
+ msg = await self.check_all_services_status(is_private=is_private, display_only_if_critical=True)
2061
2199
  if msg != "":
2062
2200
  logging.warning(msg=msg)
2063
2201
  if datetime_last_services_error_displayed is None or ((datetime.now() - datetime_last_services_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
@@ -2224,128 +2362,6 @@ class LinuxMonitor:
2224
2362
  else:
2225
2363
  logging.info(msg="- ✅ All commands are OK.")
2226
2364
 
2227
- # User logins
2228
- if is_private:
2229
- msg = self.check_all_recent_user_logins(display_only_if_critical=True)
2230
- if msg != "":
2231
- logging.warning(msg=msg)
2232
- if datetime_last_user_logins_error_displayed is None or ((datetime.now() - datetime_last_user_logins_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2233
- if out_msg != "":
2234
- out_msg += "\n"
2235
- out_msg += msg
2236
- datetime_last_user_logins_error_displayed = datetime.now()
2237
- else:
2238
- logging.warning(msg="User logins critical but already notified less than 12 hours ago, not notifying...")
2239
- elif datetime_last_user_logins_error_displayed is not None:
2240
- msg="✅ **Last user logins returned to normal state**"
2241
- logging.info(msg=msg)
2242
- if out_msg != "":
2243
- out_msg += "\n"
2244
- out_msg += msg
2245
- datetime_last_user_logins_error_displayed = None
2246
- else:
2247
- logging.info(msg="- ✅ All user logins are OK.")
2248
-
2249
- # CPU
2250
- if is_private:
2251
- msg = self.check_cpu_usage(display_only_if_critical=True)
2252
- if msg != "":
2253
- logging.warning(msg=msg)
2254
- if datetime_last_cpu_usage_error_displayed is None or ((datetime.now() - datetime_last_cpu_usage_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2255
- if out_msg != "":
2256
- out_msg += "\n"
2257
- out_msg += msg
2258
- datetime_last_cpu_usage_error_displayed = datetime.now()
2259
- else:
2260
- logging.warning(msg="CPU usage critical but already notified less than 12 hours ago, not notifying...")
2261
- elif datetime_last_cpu_usage_error_displayed is not None:
2262
- msg = "✅ **CPU usage returned to normal state**"
2263
- logging.info(msg=msg)
2264
- if out_msg != "":
2265
- out_msg += "\n"
2266
- out_msg += msg
2267
- datetime_last_cpu_usage_error_displayed = None
2268
- else:
2269
- logging.info(msg="- ✅ CPU usage is OK.")
2270
-
2271
- # RAM
2272
- if is_private:
2273
- msg = self.check_ram_usage(display_only_if_critical=True)
2274
- if msg != "":
2275
- logging.warning(msg=msg)
2276
- if datetime_last_ram_usage_error_displayed is None or ((datetime.now() - datetime_last_ram_usage_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2277
- if out_msg != "":
2278
- out_msg += "\n"
2279
- out_msg += msg
2280
- datetime_last_ram_usage_error_displayed = datetime.now()
2281
- else:
2282
- logging.warning(msg="RAM usage critical but already notified less than 12 hours ago, not notifying...")
2283
- elif datetime_last_ram_usage_error_displayed is not None:
2284
- msg = "✅ **RAM usage returned to normal state**"
2285
- logging.info(msg=msg)
2286
- if out_msg != "":
2287
- out_msg += "\n"
2288
- out_msg += msg
2289
- datetime_last_ram_usage_error_displayed = None
2290
- else:
2291
- logging.info(msg="- ✅ RAM usage is OK.")
2292
-
2293
- # Swap
2294
- if is_private:
2295
- msg = self.check_swap_usage(display_only_if_critical=True)
2296
- if msg != "":
2297
- logging.warning(msg=msg)
2298
- if datetime_last_swap_usage_error_displayed is None or ((datetime.now() - datetime_last_swap_usage_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2299
- if out_msg != "":
2300
- out_msg += "\n"
2301
- out_msg += msg
2302
- datetime_last_swap_usage_error_displayed = datetime.now()
2303
- else:
2304
- logging.warning(msg="Swap usage critical but already notified less than 12 hours ago, not notifying...")
2305
- elif datetime_last_swap_usage_error_displayed is not None:
2306
- msg = "✅ **SWAP usage returned to normal state**"
2307
- logging.info(msg=msg)
2308
- if out_msg != "":
2309
- out_msg += "\n"
2310
- out_msg += msg
2311
- datetime_last_swap_usage_error_displayed = None
2312
- else:
2313
- logging.info(msg="- ✅ Swap usage is OK.")
2314
-
2315
- # CPU temperature
2316
- if is_private:
2317
- msg = self.check_cpu_temperature(display_only_if_critical=True)
2318
- if msg != "":
2319
- logging.warning(msg=msg)
2320
- if datetime_last_cpu_temperature_error_displayed is None or ((datetime.now() - datetime_last_cpu_temperature_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
2321
- if out_msg != "":
2322
- out_msg += "\n"
2323
- out_msg += msg
2324
- datetime_last_cpu_temperature_error_displayed = datetime.now()
2325
- else:
2326
- logging.warning(msg="CPU temperature critical but already notified less than 12 hours ago, not notifying...")
2327
- elif datetime_last_cpu_temperature_error_displayed is not None:
2328
- msg = "✅ **CPU temperature returned to normal state**"
2329
- logging.info(msg=msg)
2330
- if out_msg != "":
2331
- out_msg += "\n"
2332
- out_msg += msg
2333
- datetime_last_cpu_temperature_error_displayed = None
2334
- else:
2335
- logging.info(msg="- ✅ CPU temperature is OK.")
2336
-
2337
- # Uptime
2338
- if is_private:
2339
- if need_to_check_uptime:
2340
- msg = self.check_uptime(display_only_if_critical=True)
2341
- need_to_check_uptime = False
2342
- if msg != "":
2343
- logging.warning(msg=msg)
2344
- if out_msg != "":
2345
- out_msg += "\n"
2346
- out_msg += msg
2347
- else:
2348
- logging.info(msg="- ✅ Uptime is OK.")
2349
2365
  except Exception as e:
2350
2366
  out_msg = f"**Internal error during periodic server check task**:\n```sh\n{e}\n```"
2351
2367
  logging.exception(msg=out_msg)
@@ -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.4.7",
9
+ version="1.4.8",
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