Module: check_mk
Branch: master
Commit: c8d356c424c3d2c0cf5d18e3d3cdb1ffabd6849a
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=c8d356c424c3d2…
Author: Andreas Boesl <ab(a)mathias-kettner.de>
Date: Fri Apr 5 10:44:39 2019 +0200
added WK7254: Background Jobs: Fixed bug on several job detail pages, stating the job is stuck in initialized phase
Change-Id: I62012b483611f500ee6d0737eaeb37578e673efd
---
.werks/7254 | 13 +++++++++++++
cmk/gui/background_job.py | 15 +++++++--------
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/.werks/7254 b/.werks/7254
new file mode 100644
index 0000000..b78ab25
--- /dev/null
+++ b/.werks/7254
@@ -0,0 +1,13 @@
+Title: Background Jobs: Fixed bug on several job detail pages, stating the job is stuck in "initialized" phase
+Level: 1
+Component: wato
+Class: fix
+Compatible: compat
+Edition: cre
+State: unknown
+Version: 1.6.0i1
+Date: 1554382214
+
+The <tt>Bake agents</tt> or <tt>Download agent output</tt> background job details pages incorrectly showed the jobstatus as initialized.
+This error solely was a display bug and was caused by invalid parsing of the jobs statefile.
+The actual background job was running fine.
diff --git a/cmk/gui/background_job.py b/cmk/gui/background_job.py
index 7a6307c..f37140a 100644
--- a/cmk/gui/background_job.py
+++ b/cmk/gui/background_job.py
@@ -310,19 +310,18 @@ class BackgroundJob(object):
]:
return False
+ if job_status["state"] == JobStatus.state_initialized:
+ # The process was created a millisecond ago
+ # The child process however, did not have time to update the statefile with its PID
+ # We consider this scenario as OK, if the start time was recent enough
+ if time.time() - job_status["started"] < 5: # 5 seconds
+ return True
+
if job_status["pid"] is None:
return False
try:
p = psutil.Process(job_status["pid"])
- if job_status["state"] == JobStatus.state_initialized:
- # The process was just created, but has/may not been renamed yet
- # Additionally it has no open file handle to the status file
- # The _is_correct_process check will fail in this gray area
- # We consider this scenario as OK, if the start time was recent enough
- if time.time() - job_status["started"] < 5: # 5 seconds
- return True
-
if self._is_correct_process(job_status, p):
return True
except (psutil.NoSuchProcess, psutil.AccessDenied):
Module: check_mk
Branch: master
Commit: cebef02d2d29e44b5acbcd3a60a5862d6b8c78c3
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=cebef02d2d29e4…
Author: Moritz Kiemer <mo(a)mathias-kettner.de>
Date: Fri Apr 5 08:28:06 2019 +0200
mk_mongodb: fix handling of state file
reading:
* use context manager
* handle missing read permission and invalid content
* avoid returning (None, False) which would have crashed
updateing:
* moved to function
* use context manager
* handle missing write permission and invalid timestamp
Change-Id: Id80d9b1d183be3b6a337178ff6f7b6215fbc5ce2
---
agents/plugins/mk_mongodb | 52 ++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 21 deletions(-)
diff --git a/agents/plugins/mk_mongodb b/agents/plugins/mk_mongodb
index c4dfdeb..4159a38 100755
--- a/agents/plugins/mk_mongodb
+++ b/agents/plugins/mk_mongodb
@@ -126,7 +126,8 @@ def section_by_keys(section_name, keys, server_status, output_key=False):
def get_timestamp(text):
- """parse timestamps like 'Nov 6 13:44:09' or '2015-10-17T05:35:24'"""
+ """parse timestamps like 'Nov 6 13:44:09.345' or '2015-10-17T05:35:24.234'"""
+ text = text.split('.')[0]
for pattern in ["%a %b %d %H:%M:%S", "%Y-%m-%dT%H:%M:%S"]:
try:
return time.mktime(time.strptime(text, pattern))
@@ -135,24 +136,36 @@ def get_timestamp(text):
def read_statefile(state_file):
- last_timestamp = None
- output_all = False
- year_available = False
- if os.path.exists(state_file):
- last_timestamp = int(file(state_file).read())
- if time.localtime(last_timestamp).tm_year >= 2015:
- year_available = True
-
- # Note: there is no year information in these loglines
- # As workaround we look at the creation date (year) of the last statefile
- # If it differs and there are new messages we start from the beginning
- if not year_available:
- statefile_year = time.localtime(os.stat(state_file).st_ctime).tm_year
- if time.localtime().tm_year != statefile_year:
- output_all = True
+ try:
+ with open(state_file) as state_fd:
+ last_timestamp = int(state_fd.read())
+ except (IOError, ValueError):
+ return None, True
+
+ if time.localtime(last_timestamp).tm_year >= 2015:
+ return last_timestamp, False
+
+ # Note: there is no year information in these loglines
+ # As workaround we look at the creation date (year) of the last statefile
+ # If it differs and there are new messages we start from the beginning
+ statefile_year = time.localtime(os.stat(state_file).st_ctime).tm_year
+ output_all = time.localtime().tm_year != statefile_year
return last_timestamp, output_all
+def update_statefile(state_file, startup_warnings):
+ lines = startup_warnings.get("log")
+ if not lines:
+ return
+ timestamp = get_timestamp(lines[-1])
+ try:
+ with open(state_file, 'w') as state_fd:
+ state_fd.write("%d" % timestamp)
+ except (IOError, TypeError):
+ # TypeError: timestamp was None, but at least ctime is updated.
+ pass
+
+
def section_logwatch(client):
if not MK_VARDIR:
return
@@ -174,13 +187,10 @@ def section_logwatch(client):
if "** WARNING:" in line:
state = "W"
- if output_all or get_timestamp(line.split(".")[0]) > last_timestamp:
+ if output_all or get_timestamp(line) > last_timestamp:
sys.stdout.write("%s %s\n" % (state, line))
- # update state file
- if startup_warnings["log"]:
- timestamp = get_timestamp(startup_warnings["log"][-1].split(".")[0])
- file(state_file, "w").write("%d" % timestamp)
+ update_statefile(state_file, startup_warnings)
def main():
Module: check_mk
Branch: master
Commit: 659b58ca1b5733e4c885ac186154e37e25312759
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=659b58ca1b5733…
Author: Moritz Kiemer <mo(a)mathias-kettner.de>
Date: Fri Apr 5 08:06:34 2019 +0200
mk_mongodb: refactor reading of state file
Change-Id: Ifd1d69c0537a51d596e3fdafbf0cd89a0d9374d3
---
agents/plugins/mk_mongodb | 97 +++++++++++++++++++++++++----------------------
1 file changed, 51 insertions(+), 46 deletions(-)
diff --git a/agents/plugins/mk_mongodb b/agents/plugins/mk_mongodb
index 6f04ac4..c4dfdeb 100755
--- a/agents/plugins/mk_mongodb
+++ b/agents/plugins/mk_mongodb
@@ -125,57 +125,62 @@ def section_by_keys(section_name, keys, server_status, output_key=False):
sys.stdout.write(fmt % item)
+def get_timestamp(text):
+ """parse timestamps like 'Nov 6 13:44:09' or '2015-10-17T05:35:24'"""
+ for pattern in ["%a %b %d %H:%M:%S", "%Y-%m-%dT%H:%M:%S"]:
+ try:
+ return time.mktime(time.strptime(text, pattern))
+ except ValueError:
+ pass
+
+
+def read_statefile(state_file):
+ last_timestamp = None
+ output_all = False
+ year_available = False
+ if os.path.exists(state_file):
+ last_timestamp = int(file(state_file).read())
+ if time.localtime(last_timestamp).tm_year >= 2015:
+ year_available = True
+
+ # Note: there is no year information in these loglines
+ # As workaround we look at the creation date (year) of the last statefile
+ # If it differs and there are new messages we start from the beginning
+ if not year_available:
+ statefile_year = time.localtime(os.stat(state_file).st_ctime).tm_year
+ if time.localtime().tm_year != statefile_year:
+ output_all = True
+ return last_timestamp, output_all
+
+
def section_logwatch(client):
- # TODO: this produces an empty section if MK_VARDIR is not set. Intended?
+ if not MK_VARDIR:
+ return
+
sys.stdout.write("<<<logwatch>>>\n")
sys.stdout.write("[[[MongoDB startupWarnings]]]\n")
startup_warnings = client.admin.command({"getLog": "startupWarnings"})
- if MK_VARDIR:
- state_file = "%s/mongodb.state" % MK_VARDIR
- last_timestamp = None
- output_all = False
-
- # Supports: Nov 6 13:44:09
- # 2015-10-17T05:35:24
- def get_timestamp(text):
- for pattern in ["%a %b %d %H:%M:%S", "%Y-%m-%dT%H:%M:%S"]:
- try:
- result = time.mktime(time.strptime(text, pattern))
- return result
- except Exception: # pylint: disable=broad-except
- continue
-
- year_available = False
- if os.path.exists(state_file):
- last_timestamp = int(file(state_file).read())
- if time.localtime(last_timestamp).tm_year >= 2015:
- year_available = True
-
- # Note: there is no year information in these loglines
- # As workaround we look at the creation date (year) of the last statefile
- # If it differs and there are new messages we start from the beginning
- if not year_available:
- statefile_year = time.localtime(os.stat(state_file).st_ctime).tm_year
- if time.localtime().tm_year != statefile_year:
- output_all = True
-
- for line in startup_warnings["log"]:
- state = "C"
- state_index = line.find("]") + 2
- if len(line) == state_index or line[state_index:].startswith("** "):
- state = "."
-
- if "** WARNING:" in line:
- state = "W"
-
- if output_all or get_timestamp(line.split(".")[0]) > last_timestamp:
- sys.stdout.write("%s %s\n" % (state, line))
-
- # update state file
- if startup_warnings["log"]:
- timestamp = get_timestamp(startup_warnings["log"][-1].split(".")[0])
- file(state_file, "w").write("%d" % timestamp)
+ state_file = "%s/mongodb.state" % MK_VARDIR
+
+ last_timestamp, output_all = read_statefile(state_file)
+
+ for line in startup_warnings["log"]:
+ state = "C"
+ state_index = line.find("]") + 2
+ if len(line) == state_index or line[state_index:].startswith("** "):
+ state = "."
+
+ if "** WARNING:" in line:
+ state = "W"
+
+ if output_all or get_timestamp(line.split(".")[0]) > last_timestamp:
+ sys.stdout.write("%s %s\n" % (state, line))
+
+ # update state file
+ if startup_warnings["log"]:
+ timestamp = get_timestamp(startup_warnings["log"][-1].split(".")[0])
+ file(state_file, "w").write("%d" % timestamp)
def main():