LinuxMonitor 1.2.8__tar.gz → 1.3.0__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.2.8
3
+ Version: 1.3.0
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
@@ -61,6 +61,7 @@ Additionnal functionalities:
61
61
  - Get processes list (PID and name)
62
62
  - Kill a process by PID
63
63
  - Reboot server
64
+ - Restart/stop a service
64
65
 
65
66
  ## How to install (python script and shell)
66
67
 
@@ -135,6 +136,9 @@ python3 -m linuxmonitor --restart_all --config_file config-example.json --nodebu
135
136
  # Restart a service
136
137
  python3 -m linuxmonitor --restart_service SERVICE_NAME_HERE --config_file config-example.json --nodebug
137
138
 
139
+ # Stop a service
140
+ python3 -m linuxmonitor --stop_service SERVICE_NAME_HERE --config_file config-example.json --nodebug
141
+
138
142
  # Check ports
139
143
  python3 -m linuxmonitor --ports --config_file config-example.json --nodebug
140
144
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: LinuxMonitor
3
- Version: 1.2.8
3
+ Version: 1.3.0
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
@@ -61,6 +61,7 @@ Additionnal functionalities:
61
61
  - Get processes list (PID and name)
62
62
  - Kill a process by PID
63
63
  - Reboot server
64
+ - Restart/stop a service
64
65
 
65
66
  ## How to install (python script and shell)
66
67
 
@@ -135,6 +136,9 @@ python3 -m linuxmonitor --restart_all --config_file config-example.json --nodebu
135
136
  # Restart a service
136
137
  python3 -m linuxmonitor --restart_service SERVICE_NAME_HERE --config_file config-example.json --nodebug
137
138
 
139
+ # Stop a service
140
+ python3 -m linuxmonitor --stop_service SERVICE_NAME_HERE --config_file config-example.json --nodebug
141
+
138
142
  # Check ports
139
143
  python3 -m linuxmonitor --ports --config_file config-example.json --nodebug
140
144
 
@@ -33,6 +33,7 @@ Additionnal functionalities:
33
33
  - Get processes list (PID and name)
34
34
  - Kill a process by PID
35
35
  - Reboot server
36
+ - Restart/stop a service
36
37
 
37
38
  ## How to install (python script and shell)
38
39
 
@@ -107,6 +108,9 @@ python3 -m linuxmonitor --restart_all --config_file config-example.json --nodebu
107
108
  # Restart a service
108
109
  python3 -m linuxmonitor --restart_service SERVICE_NAME_HERE --config_file config-example.json --nodebug
109
110
 
111
+ # Stop a service
112
+ python3 -m linuxmonitor --stop_service SERVICE_NAME_HERE --config_file config-example.json --nodebug
113
+
110
114
  # Check ports
111
115
  python3 -m linuxmonitor --ports --config_file config-example.json --nodebug
112
116
 
@@ -23,6 +23,7 @@ def main() -> None:
23
23
  parser.add_argument('--services_status', action='store_true', help='🩺 Check services are running 🩺')
24
24
  parser.add_argument('--restart_all', action='store_true', help='🚀 Restart all services 🚀')
25
25
  parser.add_argument('--restart_service', type=str, help='🚀 Restart a service 🚀')
26
+ parser.add_argument('--stop_service', type=str, help='🚫 Stop a service 🚫')
26
27
  parser.add_argument('--list_services', action='store_true', help='📋 List all available services 📋')
27
28
  parser.add_argument('--ports', action='store_true', help='🔒 Check ports 🔒')
28
29
  parser.add_argument('--list_processes', action='store_true', help='📋 List active processes 📋')
@@ -105,7 +106,7 @@ def main() -> None:
105
106
  if args.websites:
106
107
  handled = True
107
108
  print("Checking websites availability...")
108
- out_msg: str = asyncio.run(monitoring.check_all_websites(is_private=True, display_only_if_critical=False, restart_if_down=False))
109
+ out_msg: str = asyncio.run(monitoring.check_all_websites(is_private=True, display_only_if_critical=False))
109
110
  print(out_msg)
110
111
 
111
112
  if args.certificates:
@@ -123,7 +124,7 @@ def main() -> None:
123
124
  if args.services_status:
124
125
  handled = True
125
126
  print("Checking if services are running and restart if down...")
126
- out_msg: str = asyncio.run(monitoring.check_all_services_status_and_restart_if_down(is_private=True))
127
+ out_msg: str = asyncio.run(monitoring.check_all_services_status(is_private=True, display_only_if_critical=False))
127
128
  print(out_msg)
128
129
 
129
130
  if args.restart_all:
@@ -134,19 +135,25 @@ def main() -> None:
134
135
  if args.restart_service is not None:
135
136
  handled = True
136
137
  print(f"Restarting service: {args.restart_service}...")
137
- out_msg: str = asyncio.run(monitoring.restart_service(is_private=True, service_name=args.restart_service))
138
+ out_msg: str = asyncio.run(monitoring.restart_service(is_private=True, service_name=args.restart_service, force_restart=True))
139
+ print(out_msg)
140
+
141
+ if args.stop_service is not None:
142
+ handled = True
143
+ print(f"Stopping service: {args.stop_service}...")
144
+ out_msg: str = asyncio.run(monitoring.stop_service(is_private=True, service_name=args.stop_service))
138
145
  print(out_msg)
139
146
 
140
147
  if args.list_services:
141
148
  handled = True
142
149
  print("Listing all available services...")
143
- out_msg: str = monitoring.get_all_services_allowed_to_restart(is_private=True)
150
+ out_msg: str = monitoring.get_all_services(is_private=True)
144
151
  print(out_msg)
145
152
 
146
153
  if args.ports:
147
154
  handled = True
148
155
  print("Checking ports...")
149
- out_msg: str = asyncio.run(monitoring.check_all_ports(is_private=True, display_only_if_critical=False, restart_if_down=False))
156
+ out_msg: str = asyncio.run(monitoring.check_all_ports(is_private=True, display_only_if_critical=False))
150
157
  print(out_msg)
151
158
 
152
159
  if args.list_processes:
@@ -16,6 +16,9 @@ Non exhaustive list of features (available by using it in shell or in python scr
16
16
  - Check last user connections IPs
17
17
  - Check uptime (to inform if the server has been rebooted)
18
18
 
19
+ - Restart/stop a service
20
+ - List all services
21
+
19
22
  - Get hostname, OS details, kernel version, server datetime, uptime
20
23
  - Get connected users
21
24
 
@@ -30,7 +33,7 @@ __email__ = "quentin@comte-gaz.com"
30
33
  __license__ = "MIT License"
31
34
  __copyright__ = "Copyright Quentin Comte-Gaz (2024)"
32
35
  __python_version__ = "3.+"
33
- __version__ = "1.2.8 (2024/09/19)"
36
+ __version__ = "1.3.0 (2024/09/19)"
34
37
  __status__ = "Usable for any Linux project"
35
38
 
36
39
  import json
@@ -179,7 +182,7 @@ class LinuxMonitor:
179
182
 
180
183
  #region Execute Command
181
184
 
182
- async def execute_and_verify(self, command: List[str], display_name: str, show_only_std_and_exception: bool, timeout_in_sec: Optional[int] = None, display_only_if_critical: bool = False, check_also_stdout_not_containing: Optional[str] = None) -> Tuple[Optional[bool], str]:
185
+ async def execute_and_verify(self, command: str, display_name: str, show_only_std_and_exception: bool, timeout_in_sec: Optional[int] = None, display_only_if_critical: bool = False, check_also_stdout_not_containing: Optional[str] = None) -> Tuple[Optional[bool], str]:
183
186
  """
184
187
  Execute a shell command asynchronously and verify its correct execution.
185
188
 
@@ -195,11 +198,11 @@ class LinuxMonitor:
195
198
 
196
199
  try:
197
200
  logging.debug(msg=f"Executing command {display_name} (command: {command})...")
198
- process = await asyncio.create_subprocess_exec(
199
- *command,
201
+ process = await asyncio.create_subprocess_shell(
202
+ command,
200
203
  stdout=asyncio.subprocess.PIPE,
201
204
  stderr=asyncio.subprocess.PIPE,
202
- shell=False
205
+ shell=True
203
206
  )
204
207
 
205
208
  try:
@@ -270,7 +273,7 @@ class LinuxMonitor:
270
273
  IMPORTANT: To be usable, the user must have the right to execute `sudo /sbin/reboot` command without password.
271
274
  """
272
275
  logging.info(msg="Rebooting the server...")
273
- _, out_msg = await self.execute_and_verify(command=["sudo", "/sbin/reboot"], display_name="Server reboot", show_only_std_and_exception=False, timeout_in_sec=None, display_only_if_critical=False)
276
+ _, out_msg = await self.execute_and_verify(command="sudo /sbin/reboot", display_name="Server reboot", show_only_std_and_exception=False, timeout_in_sec=None, display_only_if_critical=False)
274
277
  return out_msg
275
278
 
276
279
  #endregion
@@ -749,7 +752,7 @@ class LinuxMonitor:
749
752
  :return: A string containing the result message.
750
753
  """
751
754
  try:
752
- ping_command: list[str] = ["ping", "-c", "1", website]
755
+ ping_command: str = f"ping -c 1 {website}"
753
756
  display_name = f"[{display_name}](https://{website})"
754
757
 
755
758
  start_time: float = time.time()
@@ -849,7 +852,7 @@ class LinuxMonitor:
849
852
  out_msg = f"⚠️ **Error checking {display_name}**:\n```sh\n{e}\n```"
850
853
  return False, out_msg
851
854
 
852
- async def check_all_websites(self, is_private: bool, display_only_if_critical: bool=False, restart_if_down: bool=False) -> str:
855
+ async def check_all_websites(self, is_private: bool, display_only_if_critical: bool=False) -> str:
853
856
  try:
854
857
  out_msg: str = ""
855
858
  for website_config in self.config['websites']:
@@ -875,8 +878,8 @@ class LinuxMonitor:
875
878
  out_msg += "\n"
876
879
  out_msg += f"- {msg}"
877
880
 
878
- if not res and restart_if_down and service_name_to_restart != "":
879
- restart_msg = await self.restart_service(is_private=is_private, service_name=service_name_to_restart)
881
+ if not res and service_name_to_restart != "":
882
+ restart_msg = await self.restart_service(is_private=is_private, service_name=service_name_to_restart, force_restart=False)
880
883
  out_msg += f"\n - {restart_msg}"
881
884
 
882
885
  if out_msg != "":
@@ -892,7 +895,7 @@ class LinuxMonitor:
892
895
 
893
896
  #region Services
894
897
 
895
- def get_all_services_allowed_to_restart(self, is_private: bool) -> str:
898
+ def get_all_services(self, is_private: bool) -> str:
896
899
  """
897
900
  Get all services allowed to restart which are configured in the JSON configuration file.
898
901
 
@@ -905,12 +908,24 @@ class LinuxMonitor:
905
908
  service = self.config['services'][service_name]
906
909
  if is_private or service['is_private'] == is_private:
907
910
  is_allowed_to_restart: bool = 'restart_command' in service
911
+ is_allowed_to_stop: bool = 'stop_command' in service
912
+ auto_restart: bool = service.get('force_restart', False)
908
913
 
909
914
  if out_msg != "":
910
915
  out_msg += "\n"
911
- out_msg += f"- `{service_name}`: {service['display_name']}"
916
+ out_msg += f"- `{service_name}`: {service['display_name']}:\n"
912
917
  if not is_allowed_to_restart:
913
- out_msg += " (❌ Not authorized to restart)"
918
+ out_msg += " - ❌ Not authorized to restart (no 'restart_command')\n"
919
+ else:
920
+ if auto_restart:
921
+ out_msg += " - ✅ Can be restarted (automatically & manually)\n"
922
+ else:
923
+ out_msg += " - ✅ Can be restarted (manually only because 'force_restart' = false)\n"
924
+
925
+ if is_allowed_to_stop:
926
+ out_msg += " - ✅ Can be stopped manually"
927
+ else:
928
+ out_msg += " - ❌ Not authorized to stop manually (no 'stop_command')"
914
929
 
915
930
  if out_msg != "":
916
931
  out_msg = f"# 🔄 Services list 🔄\n{out_msg}"
@@ -920,7 +935,7 @@ class LinuxMonitor:
920
935
  logging.info(msg=out_msg)
921
936
  return out_msg
922
937
 
923
- async def restart_service(self, is_private: bool, service_name: str) -> str:
938
+ async def restart_service(self, is_private: bool, service_name: str, force_restart: bool) -> str:
924
939
  """
925
940
  Restart a specific service.
926
941
 
@@ -947,9 +962,14 @@ class LinuxMonitor:
947
962
  logging.error(msg=out_msg)
948
963
  return out_msg
949
964
 
965
+ if not force_restart and not service.get('force_restart', False):
966
+ out_msg = f"⚠️ **Service {service_name} can be restarted only manually** (change configuration if needed)."
967
+ logging.error(msg=out_msg)
968
+ return out_msg
969
+
950
970
  timeout_in_sec: int = service.get('timeout_in_sec', 90)
951
971
 
952
- service_call: List[str] = service['restart_command']
972
+ service_call: str = service['restart_command']
953
973
  out_msg: str = ""
954
974
 
955
975
  logging.info(f"Trying to restart {display_name} (command: {service_call}) in less than {timeout_in_sec}sec...")
@@ -986,7 +1006,7 @@ class LinuxMonitor:
986
1006
  out_msg: str = ""
987
1007
  for service_name in self.config["services"].keys():
988
1008
  if is_private or self.config["services"][service_name]['is_private'] == is_private:
989
- res: str = await self.restart_service(is_private=is_private, service_name=service_name)
1009
+ res: str = await self.restart_service(is_private=is_private, service_name=service_name, force_restart=True)
990
1010
  if res != "":
991
1011
  if out_msg:
992
1012
  out_msg += "\n"
@@ -1023,7 +1043,7 @@ class LinuxMonitor:
1023
1043
  logging.error(msg=f"Status command (status_command) not found for service {service_name}")
1024
1044
  return None, ""
1025
1045
 
1026
- status_command = service['status_command']
1046
+ status_command: str = service['status_command']
1027
1047
  check_also_stdout_not_containing = service.get('check_also_stdout_not_containing', None)
1028
1048
 
1029
1049
  res, out_msg = await self.execute_and_verify(command=status_command, display_name=f"état de {display_name}", show_only_std_and_exception=True, timeout_in_sec=timeout_in_sec, display_only_if_critical=False, check_also_stdout_not_containing=check_also_stdout_not_containing)
@@ -1033,7 +1053,7 @@ class LinuxMonitor:
1033
1053
  logging.exception(msg=out_msg)
1034
1054
  return None, out_msg
1035
1055
 
1036
- async def check_all_services_status(self, is_private: bool) -> str:
1056
+ async def check_all_services_status(self, is_private: bool, display_only_if_critical: bool=False) -> str:
1037
1057
  """
1038
1058
  Check the status of all services configured in the JSON configuration file.
1039
1059
 
@@ -1058,58 +1078,85 @@ class LinuxMonitor:
1058
1078
  "❌"
1059
1079
  )
1060
1080
 
1061
- out_msg = "# 📱 Services status 📱\n"
1062
-
1063
1081
  for service_name in self.config["services"].keys():
1064
1082
  if is_private or self.config["services"][service_name]['is_private'] == is_private:
1065
1083
  status, status_msg = await self._get_service_status(is_private=is_private, service_name=service_name)
1066
1084
  service_status: str = status_to_string(res=status)
1067
1085
  service_icon: str = status_to_icon(res=status)
1068
- if out_msg != "":
1069
- out_msg += "\n"
1070
- out_msg += f"- {service_icon} {self.config['services'][service_name]['display_name']}: **{service_status}**"
1071
- if status != True and status_msg != "":
1072
- out_msg += f"\n{status_msg}"
1086
+
1087
+ if status is not True or not display_only_if_critical:
1088
+ if out_msg != "":
1089
+ out_msg += "\n"
1090
+ out_msg += f"- {service_icon} {self.config['services'][service_name]['display_name']}: **{service_status}**"
1091
+ if status != True and status_msg != "":
1092
+ out_msg += f"\n{status_msg}"
1093
+
1094
+ if status is False:
1095
+ out_msg += f"\n - " + await self.restart_service(is_private=is_private, service_name=service_name, force_restart=False)
1096
+
1073
1097
  except Exception as e:
1074
1098
  out_msg = f"**Internal error checking services status**:\n```sh\n{e}\n```"
1075
1099
  logging.exception(msg=out_msg)
1076
1100
 
1101
+
1102
+ if out_msg != "":
1103
+ out_msg = f"# 📱 Services status 📱\n{out_msg}"
1104
+
1077
1105
  return out_msg
1078
1106
 
1079
- async def check_all_services_status_and_restart_if_down(self, is_private: bool) -> str:
1107
+ async def stop_service(self, is_private: bool, service_name: str) -> str:
1080
1108
  """
1081
- Check the status of all services configured in the JSON configuration file and restart them if they are inactive.
1109
+ Stop a specific service.
1082
1110
 
1083
- :param is_private: User permission to check private or public services (True for private, False for public).
1111
+ :param is_private: User permission to stop private or public services (True for private, False for public).
1112
+ :param service_name: The name of the service name to stop (as configured in the JSON configuration file).
1084
1113
 
1085
1114
  :return: A string containing the result message.
1086
1115
  """
1087
- out_msg_full: str = ""
1116
+ out_msg: str = ""
1088
1117
  try:
1089
- for service_name in self.config["services"].keys():
1090
- out_msg: str = ""
1091
- if is_private or self.config["services"][service_name]['is_private'] == is_private:
1092
- status, status_msg = await self._get_service_status(is_private=is_private, service_name=service_name)
1093
- if status is False:
1094
- out_msg = f"- ❌ **{self.config['services'][service_name]['display_name']} inactive**. Restarting the service is necessary."
1095
- logging.warning(msg=out_msg)
1096
- if status_msg != "":
1097
- out_msg += f"\n{status_msg}"
1118
+ if service_name not in self.config['services'].keys():
1119
+ out_msg = f"❌ **Service {service_name} not found**."
1120
+ logging.error(msg=out_msg)
1121
+ return out_msg
1098
1122
 
1099
- out_msg_full += out_msg + "\n"
1100
- out_msg_full += " - " + await self.restart_service(is_private=is_private, service_name=service_name) + "\n"
1101
- elif status is None:
1102
- out_msg: str = f"- ⚠️ **Error checking status of {self.config['services'][service_name]['display_name']}** (not restarting it)."
1103
- logging.error(msg=out_msg)
1104
- out_msg_full += out_msg + "\n"
1105
- except Exception as e:
1106
- out_msg_full = f"- **Internal error during service status check.**:\n```sh\n{e}\n```"
1107
- logging.exception(msg=out_msg_full)
1123
+ service = self.config['services'][service_name]
1124
+ if not is_private and is_private != service['is_private']:
1125
+ out_msg = f"❌ **Service {service_name} not authorized to stop in public**."
1126
+ logging.error(msg=out_msg)
1127
+ return out_msg
1128
+
1129
+ display_name: str = service.get('display_name', service_name)
1130
+ if 'stop_command' not in service:
1131
+ out_msg = f"❌ **Stop command not found for {display_name}**."
1132
+ logging.error(msg=out_msg)
1133
+ return out_msg
1134
+
1135
+ timeout_in_sec: int = service.get('timeout_in_sec', 90)
1136
+
1137
+ service_call: str = service['stop_command']
1138
+ out_msg: str = ""
1108
1139
 
1109
- if out_msg_full != "":
1110
- out_msg_full = f"# 📱 Services status 📱\n{out_msg_full}"
1140
+ logging.info(f"Trying to stop {display_name} (command: {service_call}) in less than {timeout_in_sec}sec...")
1111
1141
 
1112
- return out_msg_full
1142
+ start_time: float = time.time()
1143
+ res, res_msg = await self.execute_and_verify(command=service_call, display_name=f"stop {display_name}", show_only_std_and_exception=True, timeout_in_sec=timeout_in_sec, display_only_if_critical=False)
1144
+ end_time: float = time.time()
1145
+
1146
+ if res == True:
1147
+ readable_duration: str = "{:.2f}".format(end_time - start_time)
1148
+ out_msg = f"✅ **{display_name} stopped with success** in {readable_duration}sec."
1149
+ logging.info(msg=out_msg)
1150
+ else:
1151
+ out_msg = f"❌ **Error stopping service {display_name}**"
1152
+ if res_msg and res_msg != "":
1153
+ out_msg += f"\n{res_msg}"
1154
+ logging.warning(msg=out_msg)
1155
+ except Exception as e:
1156
+ out_msg = f"⚠️ **Error stopping service {service_name}**:\n```sh\n{e}\n```"
1157
+ logging.exception(msg=out_msg)
1158
+
1159
+ return out_msg
1113
1160
 
1114
1161
  #endregion
1115
1162
 
@@ -1383,7 +1430,8 @@ class LinuxMonitor:
1383
1430
  command: str = f"last --ip --hostlast --time-format iso --since '{past_date}' | grep 'pts/'"
1384
1431
  last_output: str = subprocess.check_output(
1385
1432
  args=command,
1386
- shell=True, text=True
1433
+ shell=True,
1434
+ text=True
1387
1435
  ).strip()
1388
1436
  except subprocess.CalledProcessError as e:
1389
1437
  logging.error(msg=f"Error getting recent user logins:\n{e}")
@@ -1514,13 +1562,12 @@ class LinuxMonitor:
1514
1562
 
1515
1563
  return res, out_msg
1516
1564
 
1517
- async def check_all_ports(self, is_private: bool, display_only_if_critical: bool=False, restart_if_down: bool=False) -> str:
1565
+ async def check_all_ports(self, is_private: bool, display_only_if_critical: bool=False) -> str:
1518
1566
  """
1519
1567
  Check all ports configured in the JSON configuration file (and restart the service if the port is down and service_name_to_restart added in config file).
1520
1568
 
1521
1569
  :param is_private: User permission to check private or public ports (True for private, False for public).
1522
1570
  :param display_only_if_critical: If True, the string result will only be returned if there is an error during execution.
1523
- :param restart_if_down: If True, restart the service if the port is down.
1524
1571
 
1525
1572
  :return: A string containing the result message.
1526
1573
  """
@@ -1535,7 +1582,7 @@ class LinuxMonitor:
1535
1582
  want_port_to_be_open: bool = port_config.get('want_port_to_be_open', True)
1536
1583
 
1537
1584
  service_name_to_restart: str = ""
1538
- if want_port_to_be_open and restart_if_down:
1585
+ if want_port_to_be_open:
1539
1586
  service_name_to_restart = port_config.get('service_name_to_restart', "")
1540
1587
 
1541
1588
  result, result_msg = self._is_port_in_required_state(port=port, host=host, timeout_in_sec=timeout_in_sec, want_port_to_be_open=want_port_to_be_open, display_name=display_name)
@@ -1544,11 +1591,11 @@ class LinuxMonitor:
1544
1591
  out_msg += "\n"
1545
1592
  out_msg += f"- {result_msg}"
1546
1593
 
1547
- if (not result) and restart_if_down and service_name_to_restart != "":
1594
+ if (not result) and service_name_to_restart != "":
1548
1595
  if out_msg != "":
1549
1596
  out_msg += "\n"
1550
1597
 
1551
- restart_res: str = await self.restart_service(is_private=is_private, service_name=service_name_to_restart)
1598
+ restart_res: str = await self.restart_service(is_private=is_private, service_name=service_name_to_restart, force_restart=False)
1552
1599
  out_msg += f" - {restart_res}"
1553
1600
 
1554
1601
  if out_msg != "":
@@ -1669,7 +1716,7 @@ class LinuxMonitor:
1669
1716
  process_cmdline = process_cmdline[:60] + '...'
1670
1717
 
1671
1718
  # Attempt to terminate the process
1672
- terminate_command: List[str] = ['sudo', '/bin/kill', '-TERM', str(pid)]
1719
+ terminate_command: str = f"sudo /bin/kill -TERM {pid}"
1673
1720
  result_terminate, _ = await self.execute_and_verify(command=terminate_command, display_name=f"stop process {pid} ({process_name})", show_only_std_and_exception=False, timeout_in_sec=timeout_in_sec, display_only_if_critical=False)
1674
1721
 
1675
1722
  if result_terminate == True:
@@ -1681,7 +1728,7 @@ class LinuxMonitor:
1681
1728
  out_msg = f"⚠️ **Stopping nicely {pid} ({process_name}) expired**.\n"
1682
1729
 
1683
1730
  # Attempt to kill the process
1684
- kill_command = ['sudo', '/bin/kill', '-KILL', str(pid)]
1731
+ kill_command: str = f"sudo /bin/kill -KILL {pid}"
1685
1732
  _, strerror_kill = await self.execute_and_verify(command=kill_command, display_name=f"kill process {pid} ({process_name})", show_only_std_and_exception=True, timeout_in_sec=timeout_in_sec, display_only_if_critical=False)
1686
1733
  out_msg += strerror_kill
1687
1734
 
@@ -1804,7 +1851,7 @@ class LinuxMonitor:
1804
1851
  logging.info(msg="Checking services status and all disk usage, CPU, RAM, Swap, CPU temperature and ping of websites periodically...")
1805
1852
  try:
1806
1853
  # Services status
1807
- msg: str = await self.check_all_services_status_and_restart_if_down(is_private=is_private)
1854
+ msg: str = await self.check_all_services_status(is_private=is_private, display_only_if_critical=True)
1808
1855
  if msg != "":
1809
1856
  logging.warning(msg=msg)
1810
1857
  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):
@@ -1909,7 +1956,7 @@ class LinuxMonitor:
1909
1956
  logging.info(msg="- ✅ Ping of all websites are OK.")
1910
1957
 
1911
1958
  # Websites availability (GET request)
1912
- msg = await self.check_all_websites(is_private=is_private, display_only_if_critical=True, restart_if_down=True)
1959
+ msg = await self.check_all_websites(is_private=is_private, display_only_if_critical=True)
1913
1960
  if msg != "":
1914
1961
  logging.warning(msg=msg)
1915
1962
  if datetime_last_websites_error_displayed is None or ((datetime.now() - datetime_last_websites_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
@@ -1930,7 +1977,7 @@ class LinuxMonitor:
1930
1977
  logging.info(msg="- ✅ All websites availability (GET requests) are OK.")
1931
1978
 
1932
1979
  # Ports
1933
- msg = await self.check_all_ports(is_private=is_private, display_only_if_critical=True, restart_if_down=True)
1980
+ msg = await self.check_all_ports(is_private=is_private, display_only_if_critical=True)
1934
1981
  if msg != "":
1935
1982
  logging.warning(msg=msg)
1936
1983
  if datetime_last_port_error_displayed is None or ((datetime.now() - datetime_last_port_error_displayed).total_seconds() > self.max_duration_seconds_showing_same_error_again_in_scheduled_tasks):
@@ -2111,7 +2158,7 @@ class LinuxMonitor:
2111
2158
  logging.info(msg="-----------------------------------------------")
2112
2159
 
2113
2160
  # Services status
2114
- msg: str = await self.check_all_services_status_and_restart_if_down(is_private=is_private)
2161
+ msg: str = await self.check_all_services_status(is_private=is_private, display_only_if_critical=False)
2115
2162
  if msg != "":
2116
2163
  if out_msg != "":
2117
2164
  out_msg += "\n"
@@ -2146,14 +2193,14 @@ class LinuxMonitor:
2146
2193
  out_msg += msg
2147
2194
 
2148
2195
  # Websites availability (GET request)
2149
- msg = await self.check_all_websites(is_private=is_private, display_only_if_critical=False, restart_if_down=False)
2196
+ msg = await self.check_all_websites(is_private=is_private, display_only_if_critical=False)
2150
2197
  if msg != "":
2151
2198
  if out_msg != "":
2152
2199
  out_msg += "\n"
2153
2200
  out_msg += msg
2154
2201
 
2155
2202
  # Ports
2156
- msg = await self.check_all_ports(is_private=is_private, display_only_if_critical=False, restart_if_down=False)
2203
+ msg = await self.check_all_ports(is_private=is_private, display_only_if_critical=False)
2157
2204
  if msg != "":
2158
2205
  if out_msg != "":
2159
2206
  out_msg += "\n"
@@ -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.2.8",
9
+ version="1.3.0",
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