예제 #1
0
    def test_it_should_not_delete_event_files_except_current_one_if_service_stopped_midway(
            self):
        event_list = []
        telemetry_handler = MagicMock(autospec=True)
        telemetry_handler.stopped = MagicMock(return_value=False)
        telemetry_handler.enqueue_event = MagicMock(
            side_effect=ServiceStoppedError("Telemetry service stopped"),
            wraps=event_list.append)
        no_of_extensions = 3
        # self._WELL_FORMED_FILES has 3 event files, i.e. total files for 3 extensions = 3 * 3 = 9
        # But since we delete the file that we were processing last, expected count = 8
        expected_event_file_count = 8

        with self._create_extension_telemetry_processor(
                telemetry_handler) as extension_telemetry_processor:
            ext_names = self._create_random_extension_events_dir_with_events(
                no_of_extensions, self._WELL_FORMED_FILES)
            extension_telemetry_processor.run()

            self.assertEqual(0, len(event_list),
                             "No events should have been enqueued")
            total_file_count = 0
            for ext_name in ext_names:
                event_dir = os.path.join(conf.get_ext_log_dir(), ext_name,
                                         EVENTS_DIRECTORY)
                file_count = len(os.listdir(event_dir))
                self.assertGreater(file_count, 0,
                                   "Some event files should still be there")
                total_file_count += file_count

            self.assertEqual(expected_event_file_count, total_file_count,
                             "Expected File count doesn't match")
예제 #2
0
    def _create_random_extension_events_dir_with_events(
            no_of_extensions, events_path, no_of_chars=10):
        if os.path.isdir(events_path):
            # If its a directory, get all files from that directory
            test_events_paths = glob.glob(os.path.join(events_path, "*"))
        else:
            test_events_paths = [events_path]

        extension_names = {}
        for i in range(no_of_extensions):  # pylint: disable=unused-variable
            ext_name = "Microsoft.OSTCExtensions.{0}".format(''.join(
                random.sample(string.ascii_letters, no_of_chars)))
            no_of_good_events = 0

            for test_events_file_path in test_events_paths:
                if not os.path.exists(
                        test_events_file_path) or not os.path.isfile(
                            test_events_file_path):
                    continue
                no_of_good_events += TestExtensionTelemetryHandler._parse_file_and_count_good_events(
                    test_events_file_path)
                events_dir = os.path.join(conf.get_ext_log_dir(), ext_name,
                                          EVENTS_DIRECTORY)
                fileutil.mkdir(events_dir)
                shutil.copy(test_events_file_path, events_dir)

            extension_names[ext_name] = no_of_good_events

        return extension_names
예제 #3
0
    def test_it_should_only_process_the_newer_events(self):
        max_events = 5
        no_of_extension = 2
        test_guid = str(uuid.uuid4())

        with self._create_extension_telemetry_processor() as extension_telemetry_processor:
            with patch.object(extension_telemetry_processor, "_MAX_NUMBER_OF_EVENTS_PER_EXTENSION_PER_PERIOD", max_events):
                ext_names_with_count = self._create_random_extension_events_dir_with_events(no_of_extension, self._WELL_FORMED_FILES)

                for ext_name in ext_names_with_count.keys():
                    self._replace_in_file(
                        os.path.join(conf.get_ext_log_dir(), ext_name, EVENTS_DIRECTORY, "9999999999.json"),
                        replace_from='"{0}": ""'.format(ExtensionEventSchema.OperationId),
                        replace_to='"{0}": "{1}"'.format(ExtensionEventSchema.OperationId, test_guid))
                extension_telemetry_processor.run()

                telemetry_events = self._get_handlers_with_version(extension_telemetry_processor.event_list)
                self._assert_handler_data_in_event_list(telemetry_events, ext_names_with_count,
                                                        expected_count=max_events)
                self._assert_param_in_events(extension_telemetry_processor.event_list,
                                             param_key=GuestAgentGenericLogsSchema.Context1,
                                             param_value="This is the latest event", min_count=no_of_extension*max_events)
                self._assert_param_in_events(extension_telemetry_processor.event_list,
                                             param_key=GuestAgentGenericLogsSchema.Context3, param_value=test_guid,
                                             min_count=no_of_extension*max_events)
예제 #4
0
    def _ensure_extension_telemetry_state_configured_properly(protocol):
        for name, path in list_agent_lib_directory(skip_agent_package=True):

            try:
                handler_instance = ExtHandlersHandler.get_ext_handler_instance_from_path(
                    name=name, path=path, protocol=protocol)
            except Exception:
                # Ignore errors if any
                continue

            try:
                if handler_instance is not None:
                    # Recreate the HandlerEnvironment for existing extensions on startup.
                    # This is to ensure that existing extensions can start using the telemetry pipeline if they support
                    # it and also ensures that the extensions are not sending out telemetry if the Agent has to disable the feature.
                    handler_instance.create_handler_env()
            except Exception as e:  # pylint: disable=C0103
                logger.warn(
                    "Unable to re-create HandlerEnvironment file on service startup. Error: {0}"
                    .format(ustr(e)))
                continue

        try:
            if not is_extension_telemetry_pipeline_enabled():
                # If extension telemetry pipeline is disabled, ensure we delete all existing extension events directory
                # because the agent will not be listening on those events.
                extension_event_dirs = glob.glob(
                    os.path.join(conf.get_ext_log_dir(), "*",
                                 EVENTS_DIRECTORY))
                for ext_dir in extension_event_dirs:
                    shutil.rmtree(ext_dir, ignore_errors=True)
        except Exception as e:  # pylint: disable=C0103
            logger.warn(
                "Error when trying to delete existing Extension events directory. Error: {0}"
                .format(ustr(e)))
예제 #5
0
    def test_it_should_skip_large_files_greater_than_max_file_size_and_report_event(self):
        max_file_size = 10000
        no_of_extensions = 5
        with patch("azurelinuxagent.ga.collect_telemetry_events.add_log_event") as mock_event:
            with patch("azurelinuxagent.ga.collect_telemetry_events._ProcessExtensionEvents._EXTENSION_EVENT_FILE_MAX_SIZE",
                       max_file_size):
                handler_name_with_count, _ = self._setup_and_assert_tests_for_max_sizes(no_of_extensions, expected_count=0)

                pattern = r'Skipping file:\s*{0}/(?P<name>.+?)/{1}.+'.format(conf.get_ext_log_dir(), EVENTS_DIRECTORY)
                self._assert_event_reported(mock_event, handler_name_with_count, pattern)
예제 #6
0
    def __init__(self, verbose, conf_file_path=None):
        """
        Initialize agent running environment.
        """
        self.conf_file_path = conf_file_path
        self.osutil = get_osutil()

        # Init stdout log
        level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
        logger.add_logger_appender(logger.AppenderType.STDOUT, level)

        # Init config
        conf_file_path = self.conf_file_path \
                if self.conf_file_path is not None \
                    else self.osutil.get_agent_conf_file_path()
        conf.load_conf_from_file(conf_file_path)

        # Init log
        verbose = verbose or conf.get_logs_verbose()
        level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
        logger.add_logger_appender(logger.AppenderType.FILE,
                                   level,
                                   path=conf.get_agent_log_file())

        # echo the log to /dev/console if the machine will be provisioned
        if conf.get_logs_console() and not ProvisionHandler.is_provisioned():
            self.__add_console_appender(level)

        if event.send_logs_to_telemetry():
            logger.add_logger_appender(logger.AppenderType.TELEMETRY,
                                       logger.LogLevel.WARNING,
                                       path=event.add_log_event)

        ext_log_dir = conf.get_ext_log_dir()
        try:
            if os.path.isfile(ext_log_dir):
                raise Exception("{0} is a file".format(ext_log_dir))
            if not os.path.isdir(ext_log_dir):
                fileutil.mkdir(ext_log_dir, mode=0o755, owner="root")
        except Exception as e:
            logger.error("Exception occurred while creating extension "
                         "log directory {0}: {1}".format(ext_log_dir, e))

        # Init event reporter
        # Note that the reporter is not fully initialized here yet. Some telemetry fields are filled with data
        # originating from the goal state or IMDS, which requires a WireProtocol instance. Once a protocol
        # has been established, those fields must be explicitly initialized using
        # initialize_event_logger_vminfo_common_parameters(). Any events created before that initialization
        # will contain dummy values on those fields.
        event.init_event_status(conf.get_lib_dir())
        event_dir = os.path.join(conf.get_lib_dir(), event.EVENTS_DIRECTORY)
        event.init_event_logger(event_dir)
        event.enable_unhandled_err_dump("WALA")
예제 #7
0
    def test_it_should_always_cleanup_files_on_good_and_bad_cases(self):
        with self._create_extension_telemetry_processor(
        ) as extension_telemetry_processor:
            extensions_with_count = self._create_random_extension_events_dir_with_events(
                2, os.path.join(self._TEST_DATA_DIR, "large_messages"))
            extensions_with_count.update(
                self._create_random_extension_events_dir_with_events(
                    3, self._MALFORMED_FILES))
            extensions_with_count.update(
                self._create_random_extension_events_dir_with_events(
                    4, self._WELL_FORMED_FILES))
            extensions_with_count.update(
                self._create_random_extension_events_dir_with_events(
                    1, self._MIX_FILES))

            # Create random files in the events directory for each extension just to ensure that we delete them later
            for handler_name in extensions_with_count.keys():
                file_name = os.path.join(
                    conf.get_ext_log_dir(), handler_name, EVENTS_DIRECTORY,
                    ''.join(random.sample(string.ascii_letters, 10)))
                with open(file_name, 'a') as random_file:
                    random_file.write('1*2*3' * 100)

            extension_telemetry_processor.run()
            telemetry_events = self._get_handlers_with_version(
                extension_telemetry_processor.event_list)

            self._assert_handler_data_in_event_list(telemetry_events,
                                                    extensions_with_count)

            for handler_name in extensions_with_count.keys():
                events_path = os.path.join(conf.get_ext_log_dir(),
                                           handler_name, EVENTS_DIRECTORY)
                self.assertTrue(os.path.exists(events_path),
                                "{0} dir doesn't exist".format(events_path))
                self.assertEqual(
                    0, len(os.listdir(events_path)),
                    "There should be no files inside the events dir")
예제 #8
0
    def __init__(self, verbose, conf_file_path=None):
        """
        Initialize agent running environment.
        """
        self.conf_file_path = conf_file_path
        self.osutil = get_osutil()

        #Init stdout log
        level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
        logger.add_logger_appender(logger.AppenderType.STDOUT, level)

        #Init config
        conf_file_path = self.conf_file_path \
                if self.conf_file_path is not None \
                    else self.osutil.get_agent_conf_file_path()
        conf.load_conf_from_file(conf_file_path)

        #Init log
        verbose = verbose or conf.get_logs_verbose()
        level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
        logger.add_logger_appender(logger.AppenderType.FILE,
                                   level,
                                   path="/var/log/waagent.log")
        if conf.get_logs_console():
            logger.add_logger_appender(logger.AppenderType.CONSOLE,
                                       level,
                                       path="/dev/console")
        # See issue #1035
        # logger.add_logger_appender(logger.AppenderType.TELEMETRY,
        #                            logger.LogLevel.WARNING,
        #                            path=event.add_log_event)

        ext_log_dir = conf.get_ext_log_dir()
        try:
            if os.path.isfile(ext_log_dir):
                raise Exception("{0} is a file".format(ext_log_dir))
            if not os.path.isdir(ext_log_dir):
                fileutil.mkdir(ext_log_dir, mode=0o755, owner="root")
        except Exception as e:
            logger.error("Exception occurred while creating extension "
                         "log directory {0}: {1}".format(ext_log_dir, e))

        #Init event reporter
        event.init_event_status(conf.get_lib_dir())
        event_dir = os.path.join(conf.get_lib_dir(), "events")
        event.init_event_logger(event_dir)
        event.enable_unhandled_err_dump("WALA")
예제 #9
0
파일: agent.py 프로젝트: Azure/WALinuxAgent
    def __init__(self, verbose, conf_file_path=None):
        """
        Initialize agent running environment.
        """
        self.conf_file_path = conf_file_path
        self.osutil = get_osutil()

        #Init stdout log
        level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
        logger.add_logger_appender(logger.AppenderType.STDOUT, level)

        #Init config
        conf_file_path = self.conf_file_path \
                if self.conf_file_path is not None \
                    else self.osutil.get_agent_conf_file_path()
        conf.load_conf_from_file(conf_file_path)

        #Init log
        verbose = verbose or conf.get_logs_verbose()
        level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
        logger.add_logger_appender(logger.AppenderType.FILE, level,
                                 path="/var/log/waagent.log")
        if conf.get_logs_console():
            logger.add_logger_appender(logger.AppenderType.CONSOLE, level,
                    path="/dev/console")
        # See issue #1035
        # logger.add_logger_appender(logger.AppenderType.TELEMETRY,
        #                            logger.LogLevel.WARNING,
        #                            path=event.add_log_event)

        ext_log_dir = conf.get_ext_log_dir()
        try:
            if os.path.isfile(ext_log_dir):
                raise Exception("{0} is a file".format(ext_log_dir))
            if not os.path.isdir(ext_log_dir):
                fileutil.mkdir(ext_log_dir, mode=0o755, owner="root")
        except Exception as e:
            logger.error(
                "Exception occurred while creating extension "
                "log directory {0}: {1}".format(ext_log_dir, e))

        #Init event reporter
        event.init_event_status(conf.get_lib_dir())
        event_dir = os.path.join(conf.get_lib_dir(), "events")
        event.init_event_logger(event_dir)
        event.enable_unhandled_err_dump("WALA")
    def _operation(self):

        if self._send_telemetry_events_handler.stopped():
            logger.warn(
                "{0} service is not running, skipping current iteration".
                format(self._send_telemetry_events_handler.get_thread_name()))
            return

        delete_all_event_files = True
        extension_handler_with_event_dirs = []

        try:
            extension_handler_with_event_dirs = self._get_extension_events_dir_with_handler_name(
                conf.get_ext_log_dir())

            if not extension_handler_with_event_dirs:
                logger.verbose("No Extension events directory exist")
                return

            for extension_handler_with_event_dir in extension_handler_with_event_dirs:
                handler_name = extension_handler_with_event_dir[0]
                handler_event_dir_path = extension_handler_with_event_dir[1]
                self._capture_extension_events(handler_name,
                                               handler_event_dir_path)
        except ServiceStoppedError:
            # Since the service stopped, we should not delete the extension files and retry sending them whenever
            # the telemetry service comes back up
            delete_all_event_files = False
        except Exception as error:
            msg = "Unknown error occurred when trying to collect extension events:{0}".format(
                textutil.format_exception(error))
            add_event(op=WALAEventOperation.ExtensionTelemetryEventProcessing,
                      message=msg,
                      is_success=False)
        finally:
            # Always ensure that the events directory are being deleted each run except when Telemetry Service is stopped,
            # even if we run into an error and dont process them this run.
            if delete_all_event_files:
                self._ensure_all_events_directories_empty(
                    extension_handler_with_event_dirs)
예제 #11
0
 def del_dirs(self, warnings, actions):
     dirs = [conf.get_lib_dir(), conf.get_ext_log_dir()]
     actions.append(DeprovisionAction(fileutil.rm_dirs, dirs))
예제 #12
0
    def setUp(self):
        AgentTestCase.setUp(self)
        clear_singleton_instances(ProtocolUtil)

        # Create the log directory if not exists
        fileutil.mkdir(conf.get_ext_log_dir())
예제 #13
0
 def get_log_dir(self):
     return os.path.join(conf.get_ext_log_dir(), self.ext_handler.name)
예제 #14
0
import logging
import os
import subprocess
import time
import zipfile
from datetime import datetime
from heapq import heappush, heappop

from azurelinuxagent.common.conf import get_lib_dir, get_ext_log_dir, get_agent_log_file
from azurelinuxagent.common.future import ustr
from azurelinuxagent.common.logcollector_manifests import MANIFEST_NORMAL, MANIFEST_FULL

# Please note: be careful when adding agent dependencies in this module.
# This module uses its own logger and logs to its own file, not to the agent log.

_EXTENSION_LOG_DIR = get_ext_log_dir()
_AGENT_LIB_DIR = get_lib_dir()
_AGENT_LOG = get_agent_log_file()

_LOG_COLLECTOR_DIR = os.path.join(_AGENT_LIB_DIR, "logcollector")
_TRUNCATED_FILES_DIR = os.path.join(_LOG_COLLECTOR_DIR, "truncated")

OUTPUT_RESULTS_FILE_PATH = os.path.join(_LOG_COLLECTOR_DIR, "results.txt")
COMPRESSED_ARCHIVE_PATH = os.path.join(_LOG_COLLECTOR_DIR, "logs.zip")

_MUST_COLLECT_FILES = [
    _AGENT_LOG,
    os.path.join(_AGENT_LIB_DIR, "GoalState.*.xml"),
    os.path.join(_AGENT_LIB_DIR, "ExtensionsConfig.*.xml"),
    os.path.join(_AGENT_LIB_DIR, "HostingEnvironmentConfig.*.xml"),
    os.path.join(_AGENT_LIB_DIR, "SharedConfig.*.xml"),
 def get_log_dir(self):
     return os.path.join(conf.get_ext_log_dir(), self.ext_handler.name)
예제 #16
0
 def del_dirs(self, warnings, actions):
     dirs = [conf.get_lib_dir(), conf.get_ext_log_dir()]
     actions.append(DeprovisionAction(fileutil.rm_dirs, dirs))
예제 #17
0
 def get_log_dir(self):
     return os.path.join(conf.get_ext_log_dir(), self.ext_handler.name,
                         str(self.ext_handler.properties.version))
예제 #18
0
 def get_log_dir(self):
     return os.path.join(conf.get_ext_log_dir(), self.ext_handler.name,
                         self.ext_handler.properties.version)