2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
26 """Check_MK base specific code of the crash reporting"""
31 import cStringIO
as StringIO
33 import cmk
.utils
.debug
34 import cmk
.utils
.paths
35 import cmk
.utils
.crash_reporting
as crash_reporting
37 import cmk_base
.config
as config
39 import cmk_base
.check_utils
42 # Create a crash dump with a backtrace and the agent output.
43 # This is put into a directory per service. The content is then
44 # put into a tarball, base64 encoded and put into the long output
46 def create_crash_dump(hostname
, check_plugin_name
, item
, is_manual_check
, params
, description
,
48 text
= "check failed - please submit a crash report!"
50 crash_dir
= cmk
.utils
.paths
.var_dir
+ "/crashed_checks/" + hostname
+ "/" + description
.replace(
52 _prepare_crash_dump_directory(crash_dir
)
54 _create_crash_dump_info_file(crash_dir
, hostname
, check_plugin_name
, item
, is_manual_check
,
55 params
, description
, info
, text
)
57 # TODO: Add caches of all data sources
58 if cmk_base
.check_utils
.is_snmp_check(check_plugin_name
):
59 _write_crash_dump_snmp_info(crash_dir
, hostname
, check_plugin_name
)
61 _write_crash_dump_agent_output(crash_dir
, hostname
)
63 text
+= "\n" + "Crash dump:\n" + _pack_crash_dump(crash_dir
) + "\n"
65 if cmk
.utils
.debug
.enabled():
71 def _prepare_crash_dump_directory(crash_dir
):
72 if not os
.path
.exists(crash_dir
):
73 os
.makedirs(crash_dir
)
74 # Remove all files of former crash reports
75 for f
in os
.listdir(crash_dir
):
77 os
.unlink(crash_dir
+ "/" + f
)
82 def _create_crash_dump_info_file(crash_dir
, hostname
, check_plugin_name
, item
, is_manual_check
,
83 params
, description
, info
, text
):
84 crash_info
= crash_reporting
.create_crash_info(
89 "is_cluster": config
.is_cluster(hostname
),
90 "description": description
,
91 "check_type": check_plugin_name
,
94 "uses_snmp": cmk_base
.check_utils
.is_snmp_check(check_plugin_name
),
95 "inline_snmp": config
.is_inline_snmp_host(hostname
),
96 "manual_check": is_manual_check
,
98 file(crash_dir
+ "/crash.info",
99 "w").write(crash_reporting
.crash_info_to_string(crash_info
) + "\n")
102 def _write_crash_dump_snmp_info(crash_dir
, hostname
, check_plugin_name
):
103 cachefile
= "%s/snmp/%s" % (cmk
.utils
.paths
.data_source_cache_dir
, hostname
)
104 if os
.path
.exists(cachefile
):
105 file(crash_dir
+ "/snmp_info", "w").write(file(cachefile
).read())
108 def _write_crash_dump_agent_output(crash_dir
, hostname
):
110 import cmk_base
.cee
.real_time_checks
as real_time_checks
112 real_time_checks
= None
114 if real_time_checks
and real_time_checks
.is_real_time_check_helper():
115 file(crash_dir
+ "/agent_output", "w").write(real_time_checks
.get_rtc_package())
117 cachefile
= "%s/%s" % (cmk
.utils
.paths
.tcp_cache_dir
, hostname
)
118 if os
.path
.exists(cachefile
):
119 file(crash_dir
+ "/agent_output", "w").write(file(cachefile
).read())
122 def _pack_crash_dump(crash_dir
):
123 buf
= StringIO
.StringIO()
124 with tarfile
.open(mode
="w:gz", fileobj
=buf
) as tar
:
125 for filename
in os
.listdir(crash_dir
):
126 tar
.add(os
.path
.join(crash_dir
, filename
), filename
)
128 return base64
.b64encode(buf
.getvalue())