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

Make InfluxDB logging more robust #397

Merged
merged 8 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions linien-gui/linien_gui/ui/logging_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

class LoggingPanel(QtWidgets.QWidget):
set_parameter_log = pyqtSignal(str, bool)
influx_credentials_update = pyqtSignal(bool, int, str)
influx_credentials_update = pyqtSignal(bool, str)

logParametersToolButton: "LoggedParametersToolButton"
lineEditURL: QtWidgets.QLineEdit
Expand Down Expand Up @@ -78,6 +78,10 @@ def on_connection_established(self) -> None:
self.lineEditBucket.setText(credentials.bucket)
self.lineEditMeas.setText(credentials.measurement)

# hide test indicator that might be set from previous connection to a different
# device
self.influxTestIndicator.setText("")

# getting the logging status from the remote
log_status = self.control.exposed_get_logging_status()
button_text = STOP_LOG_BUTTON_TEXT if log_status else START_LOG_BUTTON_TEXT
Expand Down Expand Up @@ -106,28 +110,20 @@ def on_influx_update_button_clicked(self) -> None:
bucket=self.lineEditBucket.text(),
measurement=self.lineEditMeas.text(),
)
(
success,
status_code,
message,
) = self.control.exposed_update_influxdb_credentials(credentials)
update_msg = f"Update of InfluxDB credentials successful: {success}"
if not success:
update_msg += f" (Status {status_code}): {message}"
(success, message) = self.control.exposed_update_influxdb_credentials(
credentials
)
update_msg = f"Update of InfluxDB credentials successful: {success}: {message}"
logger.info(update_msg)
self.influx_credentials_update.emit(success, status_code, message)
self.influx_credentials_update.emit(success, message)

def on_influxdb_credentials_updated(
self, success: bool, status_code: int, message: str
) -> None:
def on_influxdb_credentials_updated(self, success: bool, message: str) -> None:
if success:
self.influxTestIndicator.setText("✅")
self.influxTestIndicator.setToolTip("Connection successful")
self.influxTestIndicator.setToolTip(f"Connection successful: {message}")
else:
self.influxTestIndicator.setText("❌")
self.influxTestIndicator.setToolTip(
f"Connection failed: {message} (Status {status_code})"
)
self.influxTestIndicator.setToolTip(f"Connection failed: {message}.")


# checkable menu for logged parameters, inspired by
Expand Down
40 changes: 26 additions & 14 deletions linien-server/linien_server/influxdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from influxdb_client import InfluxDBClient
from influxdb_client.client.write_api import SYNCHRONOUS
from influxdb_client.rest import ApiException
from linien_common.communication import ParameterValues
from linien_common.influxdb import InfluxDBCredentials, save_credentials
from linien_server.parameters import Parameters
Expand All @@ -29,7 +30,7 @@ class InfluxDBLogger:
def __init__(
self, credentials: InfluxDBCredentials, parameters: Parameters
) -> None:
self.credentials: InfluxDBClient = credentials
self.credentials: InfluxDBCredentials = credentials
self.parameters: Parameters = parameters
self.stop_event = Event()
self.stop_event.set()
Expand All @@ -53,7 +54,7 @@ def update_connection(self) -> InfluxDBClient:
self.write_api = client.write_api(write_options=SYNCHRONOUS)

def start_logging(self, interval: float) -> None:
conn_success, status_code, message = self.test_connection(self.credentials)
conn_success, message = self.test_connection(self.credentials)
self.thread = Thread(
target=self._logging_loop,
args=(interval,),
Expand All @@ -63,10 +64,7 @@ def start_logging(self, interval: float) -> None:
self.stop_event.clear()
self.thread.start()
else:
raise ConnectionError(
"Failed to connect to InfluxDB database: "
f" {message} (Status code: {status_code})"
)
raise ConnectionError(f"Failed to connect to InfluxDB database: {message}")

def stop_logging(self) -> None:
self.stop_event.set()
Expand All @@ -85,21 +83,35 @@ def _logging_loop(self, interval: float) -> None:
self.write_data(self.credentials, data)
sleep(interval)

def test_connection(
self, credentials: InfluxDBCredentials
) -> tuple[bool, int, str]:
def test_connection(self, credentials: InfluxDBCredentials) -> tuple[bool, str]:
"""Write empty data to the server to test the connection"""
client = InfluxDBClient(
url=credentials.url,
token=credentials.token,
org=credentials.org,
)

# FIXME: This does not test the credentials, yet.
status_code = 0
message = ""
success = client.ping()
return success, status_code, message
health = client.health()
message = health.message
success = health.status == "pass"
if success:
try:
client.write_api(write_options=SYNCHRONOUS).write(
bucket=credentials.bucket,
org=credentials.org,
record={
"measurement": credentials.measurement,
"fields": {},
},
)
except ApiException as e:
success = False
message = e.message
except Exception:
success = False
message = "Exception occurred. Check server log file for details."

return success, message

def write_data(
self, credentials: InfluxDBCredentials, fields: dict[str, ParameterValues]
Expand Down
10 changes: 3 additions & 7 deletions linien-server/linien_server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,22 +118,18 @@ def exposed_get_parameter_log(self, param_name: str) -> bool:

def exposed_update_influxdb_credentials(
self, credentials: InfluxDBCredentials
) -> tuple[bool, int, str]:
) -> tuple[bool, str]:
credentials = copy(credentials)
(
connection_succesful,
status_code,
message,
) = self.influxdb_logger.test_connection(credentials)
if connection_succesful:
self.influxdb_logger.credentials = credentials
logger.info("InfluxDB credentials updated successfully")
else:
logger.info(
"InfluxDB credentials update failed. Error message: "
f" {message} (Status Code {status_code})"
)
return connection_succesful, status_code, message
logger.info(f"InfluxDB credentials update failed. Error message: {message}")
return connection_succesful, message

def exposed_get_influxdb_credentials(self) -> InfluxDBCredentials:
return self.influxdb_logger.credentials
Expand Down
Loading