Skip to content
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
11 changes: 9 additions & 2 deletions AzureMonitorAgent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -1671,9 +1671,16 @@ def uninstall_azureotelcollector():
hutil_log_error('Error removing azureotelcollector "{0}"'.format(output))


def is_telegraf_service_installed():
# Whether the telegraf (metrics-sourcer) unit file exists.
try:
return os.path.isfile(telhandler.get_telegraf_service_path(is_lad=False))
except Exception:
return False

def stop_metrics_process():

if telhandler.is_running(is_lad=False):
if telhandler.is_running(is_lad=False) or is_telegraf_service_installed():
Comment thread
NarineM marked this conversation as resolved.
#Stop the telegraf and ME services
tel_out, tel_msg = telhandler.stop_telegraf_service(is_lad=False)
if tel_out:
Expand Down Expand Up @@ -1976,7 +1983,7 @@ def metrics_watcher(hutil_error, hutil_log):

if len(json_data) == 0:
last_crc = hashlib.sha256(data.encode('utf-8')).hexdigest()
if telhandler.is_running(is_lad=False):
if telhandler.is_running(is_lad=False) or is_telegraf_service_installed():
# Stop the telegraf and ME services
tel_out, tel_msg = telhandler.stop_telegraf_service(is_lad=False)
if tel_out:
Expand Down
88 changes: 88 additions & 0 deletions AzureMonitorAgent/tests/test_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,5 +430,93 @@ def test_curl_upload_config_absent_when_disabled(self):
self.assertNotIn("ENABLE_CURL_UPLOAD", configs)


class TestIsTelegrafServiceInstalled(unittest.TestCase):
"""Tests for is_telegraf_service_installed (telegraf crash-loop fix)."""

@patch('agent.telhandler')
@patch('os.path.isfile', return_value=True)
def test_returns_true_when_unit_file_exists(self, mock_isfile, mock_telhandler):
mock_telhandler.get_telegraf_service_path.return_value = \
'/lib/systemd/system/metrics-sourcer.service'
self.assertTrue(agent.is_telegraf_service_installed())
mock_telhandler.get_telegraf_service_path.assert_called_once_with(is_lad=False)
mock_isfile.assert_called_once_with('/lib/systemd/system/metrics-sourcer.service')

@patch('agent.telhandler')
@patch('os.path.isfile', return_value=False)
def test_returns_false_when_unit_file_missing(self, mock_isfile, mock_telhandler):
mock_telhandler.get_telegraf_service_path.return_value = \
'/lib/systemd/system/metrics-sourcer.service'
self.assertFalse(agent.is_telegraf_service_installed())

@patch('agent.telhandler')
def test_returns_false_on_exception(self, mock_telhandler):
# get_telegraf_service_path raises when no systemd unit directory exists.
mock_telhandler.get_telegraf_service_path.side_effect = Exception("no systemd unit dir")
self.assertFalse(agent.is_telegraf_service_installed())


class TestStopMetricsProcessTelegrafCleanup(unittest.TestCase):
"""Tests stop_metrics_process telegraf teardown when unit file present but not running (crash-loop fix)."""

@patch('agent.run_command_and_log', return_value=(0, ''))
@patch('agent.hutil_log_error')
@patch('agent.hutil_log_info')
@patch('os.path.exists', return_value=False)
@patch('agent.me_handler')
@patch('agent.is_telegraf_service_installed', return_value=True)
@patch('agent.telhandler')
def test_stops_telegraf_when_installed_but_not_running(
self, mock_telhandler, mock_installed, mock_me, mock_exists, *_):
"""Not running + unit file present -> telegraf is stopped and removed."""
mock_telhandler.is_running.return_value = False
mock_telhandler.stop_telegraf_service.return_value = (True, 'stopped')
mock_telhandler.remove_telegraf_service.return_value = (True, 'removed')
mock_me.is_running.return_value = False

agent.stop_metrics_process()

mock_telhandler.stop_telegraf_service.assert_called_once_with(is_lad=False)
mock_telhandler.remove_telegraf_service.assert_called_once_with(is_lad=False)

@patch('agent.run_command_and_log', return_value=(0, ''))
@patch('agent.hutil_log_error')
@patch('agent.hutil_log_info')
@patch('os.path.exists', return_value=False)
@patch('agent.me_handler')
@patch('agent.is_telegraf_service_installed', return_value=False)
@patch('agent.telhandler')
def test_skips_telegraf_when_not_running_and_not_installed(
self, mock_telhandler, mock_installed, mock_me, mock_exists, *_):
"""Not running + no unit file -> telegraf teardown is skipped."""
mock_telhandler.is_running.return_value = False
mock_me.is_running.return_value = False

agent.stop_metrics_process()

mock_telhandler.stop_telegraf_service.assert_not_called()
mock_telhandler.remove_telegraf_service.assert_not_called()

@patch('agent.run_command_and_log', return_value=(0, ''))
@patch('agent.hutil_log_error')
@patch('agent.hutil_log_info')
@patch('os.path.exists', return_value=False)
@patch('agent.me_handler')
@patch('agent.is_telegraf_service_installed', return_value=False)
@patch('agent.telhandler')
def test_stops_telegraf_when_running(
self, mock_telhandler, mock_installed, mock_me, mock_exists, *_):
"""Running (regardless of unit file) -> telegraf is stopped and removed."""
mock_telhandler.is_running.return_value = True
mock_telhandler.stop_telegraf_service.return_value = (True, 'stopped')
mock_telhandler.remove_telegraf_service.return_value = (True, 'removed')
mock_me.is_running.return_value = False

agent.stop_metrics_process()

mock_telhandler.stop_telegraf_service.assert_called_once_with(is_lad=False)
mock_telhandler.remove_telegraf_service.assert_called_once_with(is_lad=False)


if __name__ == '__main__':
unittest.main()
Loading