Exemple #1
0
    def run(self):
        # We have to (maybe) start up two servers.  Since each server requires its own thread, we may have
        # to create a new one (since we can use this thread to run one of the servers).
        if self.__accept_plaintext:
            text_server = GraphiteTextServer(
                self.__only_accept_local, self.__plaintext_port,
                self._run_state, self.__buffer_size, self.__max_request_size,
                self.__max_connection_idle_time, self._logger)
        else:
            text_server = None

        if self.__accept_pickle:
            pickle_server = GraphitePickleServer(
                self.__only_accept_local, self.__pickle_port, self._run_state,
                self.__buffer_size, self.__max_request_size,
                self.__max_connection_idle_time, self._logger)
        else:
            pickle_server = None

        if not self.__accept_plaintext:
            pickle_server.run()
        elif not self.__accept_pickle:
            text_server.run()
        else:
            # If we are accepting both kinds of traffic, we need a second thread to handle one of the ports.. the
            # other one will be handled by this thread.
            # noinspection PyAttributeOutsideInit
            self.__extra_thread = StoppableThread(
                target=text_server.run,
                name='Graphite monitor text server thread')
            self.__extra_thread.start()
            pickle_server.run()
    def stop(self, wait_on_join=True, join_timeout=5):
        """Stops the thread from running.

        By default, this will also block until the thread has completed (by performing a join).

        @param wait_on_join: If True, will block on a join of this thread.
        @param join_timeout: The maximum number of seconds to block for the join.
        """
        # We override this method to take some special care to ensure the reader thread will stop quickly as well.
        self._run_state.stop()
        # This thread may be blocking on self.__queue.get, so we add a fake entry to the
        # queue to get it to return.  Since we set run_state to stop before we do this, and we always
        # check run_state before acting on an element from queue, it should be ignored.
        if self._run_state.is_running():
            self.__queue.put('ignore this')
        StoppableThread.stop(self, wait_on_join=wait_on_join, join_timeout=join_timeout)
    def stop(self, wait_on_join=True, join_timeout=5):
        """Stops the thread from running.

        By default, this will also block until the thread has completed (by performing a join).

        @param wait_on_join: If True, will block on a join of this thread.
        @param join_timeout: The maximum number of seconds to block for the join.
        """
        # We override this method to take some special care to ensure the reader thread will stop quickly as well.
        self._run_state.stop()
        # This thread may be blocking on self.__queue.get, so we add a fake entry to the
        # queue to get it to return.  Since we set run_state to stop before we do this, and we always
        # check run_state before acting on an element from queue, it should be ignored.
        if self._run_state.is_running():
            self.__queue.put('ignore this')
        StoppableThread.stop(self, wait_on_join=wait_on_join, join_timeout=join_timeout)
    def run(self):
        # We have to (maybe) start up two servers.  Since each server requires its own thread, we may have
        # to create a new one (since we can use this thread to run one of the servers).
        if self.__accept_plaintext:
            text_server = GraphiteTextServer(self.__only_accept_local, self.__plaintext_port, self._run_state,
                                             self.__buffer_size, self.__max_request_size,
                                             self.__max_connection_idle_time, self._logger)
        else:
            text_server = None

        if self.__accept_pickle:
            pickle_server = GraphitePickleServer(self.__only_accept_local, self.__pickle_port, self._run_state,
                                                 self.__buffer_size, self.__max_request_size,
                                                 self.__max_connection_idle_time, self._logger)
        else:
            pickle_server = None

        if not self.__accept_plaintext:
            pickle_server.run()
        elif not self.__accept_pickle:
            text_server.run()
        else:
            # If we are accepting both kinds of traffic, we need a second thread to handle one of the ports.. the
            # other one will be handled by this thread.
            # noinspection PyAttributeOutsideInit
            self.__extra_thread = StoppableThread(target=text_server.run, name='Graphite monitor text server thread')
            self.__extra_thread.start()
            pickle_server.run()
    def __init__(self, monitor, queue, logger, error_logger):
        """Initializes the instance.

        @param monitor: The monitor instance associated with this tcollector.
        @param queue: The Queue of lines (strings) that are pending to be written to the log. These should come from
            the ReaderThread as it reads and transforms the data from the running collectors.
        @param logger: The Logger to use to report metric values.
        @param error_logger: The Logger to use to report diagnostic information about the running of the monitor.
        """
        StoppableThread.__init__(self, name='tcollector writer thread')
        self.__monitor = monitor
        self.__queue = queue
        self.__max_uncaught_exceptions = 100
        self.__logger = logger
        self.__error_logger = error_logger
        self.__timestamp_matcher = re.compile('(\\S+)\\s+\\d+\\s+(.*)')
        self.__key_value_matcher = re.compile('(\\S+)=(\\S+)')
    def __init__(self, monitor, queue, logger, error_logger):
        """Initializes the instance.

        @param monitor: The monitor instance associated with this tcollector.
        @param queue: The Queue of lines (strings) that are pending to be written to the log. These should come from
            the ReaderThread as it reads and transforms the data from the running collectors.
        @param logger: The Logger to use to report metric values.
        @param error_logger: The Logger to use to report diagnostic information about the running of the monitor.
        """
        StoppableThread.__init__(self, name="tcollector writer thread")
        self.__monitor = monitor
        self.__queue = queue
        self.__max_uncaught_exceptions = 100
        self.__logger = logger
        self.__error_logger = error_logger
        self.__timestamp_matcher = re.compile("(\\S+)\\s+\\d+\\s+(.*)")
        self.__key_value_matcher = re.compile("(\\S+)=(\\S+)")
class GraphiteMonitor(ScalyrMonitor):
    """A Scalyr agent monitor acts as a Graphite server, accepting metrics over a network connection and then sends
    them to Scalyr.
    """
    def _initialize(self):
        """Performs monitor-specific initialization.
        """
        self.__only_accept_local = self._config.get("only_accept_local")
        self.__accept_plaintext = self._config.get("accept_plaintext")
        self.__accept_pickle = self._config.get("accept_pickle")
        self.__plaintext_port = self._config.get("plaintext_port")
        self.__pickle_port = self._config.get("pickle_port")
        self.__max_connection_idle_time = self._config.get(
            "max_connection_idle_time")
        self.__max_request_size = self._config.get("max_request_size")
        self.__buffer_size = self._config.get("buffer_size")
        # We may need an extra thread for this monitor if we are accepting traffic on both the text and pickle
        # ports since our server abstractions require a thread per port.
        self.__extra_thread = None

        if not self.__accept_plaintext and not self.__accept_pickle:
            raise Exception(
                "Invalid config state for Graphite Monitor.  At least one of accept_plaintext or "
                "accept_pickle must be true")

        if self.__max_request_size > self.__buffer_size:
            raise Exception(
                "The max_request_size of %d cannot be greater than the buffer size of %d"
                % (self.__max_request_size, self.__buffer_size))

        # We use different defaults for the log metric values so we need to update those variables.
        self._log_write_rate = self._config.get("monitor_log_write_rate",
                                                convert_to=int,
                                                default=-1)
        self._log_max_write_burst = self._config.get(
            "monitor_log_max_write_burst", convert_to=int, default=-1)
        self._log_flush_delay = self._config.get("monitor_log_flush_delay",
                                                 convert_to=float,
                                                 default=1.0,
                                                 min_value=0)

    def run(self):
        # We have to (maybe) start up two servers.  Since each server requires its own thread, we may have
        # to create a new one (since we can use this thread to run one of the servers).
        if self.__accept_plaintext:
            text_server = GraphiteTextServer(
                self.__only_accept_local,
                self.__plaintext_port,
                self._run_state,
                self.__buffer_size,
                self.__max_request_size,
                self.__max_connection_idle_time,
                self._logger,
            )
        else:
            text_server = None

        if self.__accept_pickle:
            pickle_server = GraphitePickleServer(
                self.__only_accept_local,
                self.__pickle_port,
                self._run_state,
                self.__buffer_size,
                self.__max_request_size,
                self.__max_connection_idle_time,
                self._logger,
            )
        else:
            pickle_server = None

        if not self.__accept_plaintext:
            pickle_server.run()
        elif not self.__accept_pickle:
            text_server.run()
        else:
            # We need a callback to start the text_server.  We cannot use text_server.run directly since it does
            # not take a run_state argument.
            # noinspection PyUnusedLocal
            def run_text_server(run_state):
                text_server.run()

            # If we are accepting both kinds of traffic, we need a second thread to handle one of the ports.. the
            # other one will be handled by this thread.
            # noinspection PyAttributeOutsideInit
            self.__extra_thread = StoppableThread(
                target=run_text_server,
                name="Graphite monitor text server thread")
            self.__extra_thread.start()
            pickle_server.run()

    def stop(self, wait_on_join=True, join_timeout=5):
        # The order here is important.  Since our servers use self._run_state to know when to stop, we need to
        # invoke the inherited method first since that is what actually stops self._run_state.  Then we can join
        # on the threads.
        ScalyrMonitor.stop(self,
                           wait_on_join=wait_on_join,
                           join_timeout=join_timeout)
        if self.__extra_thread is not None:
            self.__extra_thread.stop(wait_on_join=wait_on_join,
                                     join_timeout=join_timeout)
Exemple #8
0
class GraphiteMonitor(ScalyrMonitor):
    # fmt: off
    """
# Graphite Monitor

This agent monitor plugin acts as a Graphite server, allowing you to import data from Graphite-compatible tools
into Scalyr.

@class=bg-warning docInfoPanel: An *agent monitor plugin* is a component of the Scalyr Agent. To use a plugin,
simply add it to the ``monitors`` section of the Scalyr Agent configuration file (``/etc/scalyr/agent.json``).
For more information, see [Agent Plugins](/help/scalyr-agent#plugins).

## Sample Configuration

Here is a simple configuration fragment showing use of the url_monitor plugin. This sample will record
the instance type of the Amazon EC2 server on which the agent is running.

    monitors: [
      {
        module: "scalyr_agent.builtin_monitors.graphite_monitor"
      }
    ]

By default, the plugin will listen for connecions on both of the standard Graphite TCP ports (2003 for
the "plain text" protocol, and 2004 for "pickle" protocol). For security, it will only accept connections
from localhost (i.e. from processes running on the same server). Set the configuration option ``only_accept_local``
to false to allow connections from other servers. You can also specify custom ports; see Configuration Reference.

## Viewing Data

After adding this plugin to the agent configuration file, wait one minute for the agent to open the Graphite
ports. Then configure your Graphite-compatible tools to send data to these ports.

Once you are sending Graphite data to the agent, go to the Search page and search for
[$monitor = 'graphite_monitor'](/events?filter=$monitor%20%3D%20%27graphite_monitor%27). This will show all Graphite
data imported by the agent, across all servers. You can use the {{menuRef:Refine search by}} dropdown to narrow your
search to specific servers and monitors.

The [View Logs](/help/view) page describes the tools you can use to view and analyze log data.
[Query Language](/help/query-language) lists the operators you can use to select specific metrics and values.
You can also use this data in [Dashboards](/help/dashboards) and [Alerts](/help/alerts).
    """

    # fmt: on

    def _initialize(self):
        """Performs monitor-specific initialization."""
        self.__only_accept_local = self._config.get("only_accept_local")
        self.__accept_plaintext = self._config.get("accept_plaintext")
        self.__accept_pickle = self._config.get("accept_pickle")
        self.__plaintext_port = self._config.get("plaintext_port")
        self.__pickle_port = self._config.get("pickle_port")
        self.__max_connection_idle_time = self._config.get(
            "max_connection_idle_time")
        self.__max_request_size = self._config.get("max_request_size")
        self.__buffer_size = self._config.get("buffer_size")
        # We may need an extra thread for this monitor if we are accepting traffic on both the text and pickle
        # ports since our server abstractions require a thread per port.
        self.__extra_thread = None

        if not self.__accept_plaintext and not self.__accept_pickle:
            raise Exception(
                "Invalid config state for Graphite Monitor.  At least one of accept_plaintext or "
                "accept_pickle must be true")

        if self.__max_request_size > self.__buffer_size:
            raise Exception(
                "The max_request_size of %d cannot be greater than the buffer size of %d"
                % (self.__max_request_size, self.__buffer_size))

        # We use different defaults for the log metric values so we need to update those variables.
        self._log_write_rate = self._config.get("monitor_log_write_rate",
                                                convert_to=int,
                                                default=-1)
        self._log_max_write_burst = self._config.get(
            "monitor_log_max_write_burst", convert_to=int, default=-1)
        self._log_flush_delay = self._config.get("monitor_log_flush_delay",
                                                 convert_to=float,
                                                 default=1.0,
                                                 min_value=0)

    def run(self):
        # We have to (maybe) start up two servers.  Since each server requires its own thread, we may have
        # to create a new one (since we can use this thread to run one of the servers).
        if self.__accept_plaintext:
            text_server = GraphiteTextServer(
                self.__only_accept_local,
                self.__plaintext_port,
                self._run_state,
                self.__buffer_size,
                self.__max_request_size,
                self.__max_connection_idle_time,
                self._logger,
            )
        else:
            text_server = None

        if self.__accept_pickle:
            pickle_server = GraphitePickleServer(
                self.__only_accept_local,
                self.__pickle_port,
                self._run_state,
                self.__buffer_size,
                self.__max_request_size,
                self.__max_connection_idle_time,
                self._logger,
            )
        else:
            pickle_server = None

        if not self.__accept_plaintext:
            pickle_server.run()
        elif not self.__accept_pickle:
            text_server.run()
        else:
            # We need a callback to start the text_server.  We cannot use text_server.run directly since it does
            # not take a run_state argument.
            # noinspection PyUnusedLocal
            def run_text_server(run_state):
                text_server.run()

            # If we are accepting both kinds of traffic, we need a second thread to handle one of the ports.. the
            # other one will be handled by this thread.
            # noinspection PyAttributeOutsideInit
            self.__extra_thread = StoppableThread(
                target=run_text_server,
                name="Graphite monitor text server thread")
            self.__extra_thread.start()
            pickle_server.run()

    def stop(self, wait_on_join=True, join_timeout=5):
        # The order here is important.  Since our servers use self._run_state to know when to stop, we need to
        # invoke the inherited method first since that is what actually stops self._run_state.  Then we can join
        # on the threads.
        ScalyrMonitor.stop(self,
                           wait_on_join=wait_on_join,
                           join_timeout=join_timeout)
        if self.__extra_thread is not None:
            self.__extra_thread.stop(wait_on_join=wait_on_join,
                                     join_timeout=join_timeout)
class GraphiteMonitor(ScalyrMonitor):
    """A Scalyr agent monitor acts as a Graphite server, accepting metrics over a network connection and then sends
    them to Scalyr.
    """
    def _initialize(self):
        """Performs monitor-specific initialization.
        """
        # Configuration parameters are:
        # only_accept_local: (defaults to True)
        # accept_plaintext: (defaults to True)
        # accept_pickle: (defaults to True)
        # plaintext_port: (defaults to 2003)
        # pickle_port: (defaults to 2004)
        # max_connection_idle_time: (defaults to 300)
        # max_request_size: (defaults to 100K)
        # buffer_size: (defaults to 100K)

        self.__only_accept_local = self._config.get('only_accept_local', default=True, convert_to=bool)
        self.__accept_plaintext = self._config.get('accept_plaintext', default=True, convert_to=bool)
        self.__accept_pickle = self._config.get('accept_pickle', default=True, convert_to=bool)
        self.__plaintext_port = self._config.get('plaintext_port', default=2003, min_value=1, max_value=65535,
                                                 convert_to=int)
        self.__pickle_port = self._config.get('pickle_port', default=2004, min_value=1, max_value=65535,
                                              convert_to=int)
        self.__max_connection_idle_time = self._config.get('max_connection_idle_time', default=300.0,
                                                           min_value=1, convert_to=float)
        self.__max_request_size = self._config.get('max_request_size', default=100*1024,
                                                   min_value=1000, convert_to=int)
        self.__buffer_size = self._config.get('buffer_size', default=100*1024,
                                              min_value=10*1024, convert_to=int)
        # We may need an extra thread for this monitor if we are accepting traffic on both the text and pickle
        # ports since our server abstractions require a thread per port.
        self.__extra_thread = None

        if not self.__accept_plaintext and not self.__accept_pickle:
            raise Exception('Invalid config state for Graphite Monitor.  At least one of accept_plaintext or '
                            'accept_pickle must be true')

        if self.__max_request_size > self.__buffer_size:
            raise Exception('The max_request_size of %d cannot be greater than the buffer size of %d' %
                            (self.__max_request_size, self.__buffer_size))

    def run(self):
        # We have to (maybe) start up two servers.  Since each server requires its own thread, we may have
        # to create a new one (since we can use this thread to run one of the servers).
        if self.__accept_plaintext:
            text_server = GraphiteTextServer(self.__only_accept_local, self.__plaintext_port, self._run_state,
                                             self.__buffer_size, self.__max_request_size,
                                             self.__max_connection_idle_time, self._logger)
        else:
            text_server = None

        if self.__accept_pickle:
            pickle_server = GraphitePickleServer(self.__only_accept_local, self.__pickle_port, self._run_state,
                                                 self.__buffer_size, self.__max_request_size,
                                                 self.__max_connection_idle_time, self._logger)
        else:
            pickle_server = None

        if not self.__accept_plaintext:
            pickle_server.run()
        elif not self.__accept_pickle:
            text_server.run()
        else:
            # If we are accepting both kinds of traffic, we need a second thread to handle one of the ports.. the
            # other one will be handled by this thread.
            # noinspection PyAttributeOutsideInit
            self.__extra_thread = StoppableThread(target=text_server.run, name='Graphite monitor text server thread')
            self.__extra_thread.start()
            pickle_server.run()

    def stop(self, wait_on_join=True, join_timeout=5):
        # The order here is important.  Since our servers use self._run_state to know when to stop, we need to
        # invoke the inherited method first since that is what actually stops self._run_state.  Then we can join
        # on the threads.
        ScalyrMonitor.stop(self, wait_on_join=wait_on_join, join_timeout=join_timeout)
        if self.__extra_thread is not None:
            self.__extra_thread.stop(wait_on_join=wait_on_join, join_timeout=join_timeout)
class GraphiteMonitor(ScalyrMonitor):
    """A Scalyr agent monitor acts as a Graphite server, accepting metrics over a network connection and then sends
    them to Scalyr.
    """

    def _initialize(self):
        """Performs monitor-specific initialization.
        """
        self.__only_accept_local = self._config.get('only_accept_local')
        self.__accept_plaintext = self._config.get('accept_plaintext')
        self.__accept_pickle = self._config.get('accept_pickle')
        self.__plaintext_port = self._config.get('plaintext_port')
        self.__pickle_port = self._config.get('pickle_port')
        self.__max_connection_idle_time = self._config.get('max_connection_idle_time')
        self.__max_request_size = self._config.get('max_request_size')
        self.__buffer_size = self._config.get('buffer_size')
        # We may need an extra thread for this monitor if we are accepting traffic on both the text and pickle
        # ports since our server abstractions require a thread per port.
        self.__extra_thread = None

        if not self.__accept_plaintext and not self.__accept_pickle:
            raise Exception('Invalid config state for Graphite Monitor.  At least one of accept_plaintext or '
                            'accept_pickle must be true')

        if self.__max_request_size > self.__buffer_size:
            raise Exception('The max_request_size of %d cannot be greater than the buffer size of %d' %
                            (self.__max_request_size, self.__buffer_size))

        # We use different defaults for the log metric values so we need to update those variables.
        self._log_write_rate = self._config.get('monitor_log_write_rate', convert_to=int, default=-1)
        self._log_max_write_burst = self._config.get('monitor_log_max_write_burst', convert_to=int, default=-1)
        self._log_flush_delay = self._config.get('monitor_log_flush_delay', convert_to=float, default=1.0, min_value=0)

    def run(self):
        # We have to (maybe) start up two servers.  Since each server requires its own thread, we may have
        # to create a new one (since we can use this thread to run one of the servers).
        if self.__accept_plaintext:
            text_server = GraphiteTextServer(self.__only_accept_local, self.__plaintext_port, self._run_state,
                                             self.__buffer_size, self.__max_request_size,
                                             self.__max_connection_idle_time, self._logger)
        else:
            text_server = None

        if self.__accept_pickle:
            pickle_server = GraphitePickleServer(self.__only_accept_local, self.__pickle_port, self._run_state,
                                                 self.__buffer_size, self.__max_request_size,
                                                 self.__max_connection_idle_time, self._logger)
        else:
            pickle_server = None

        if not self.__accept_plaintext:
            pickle_server.run()
        elif not self.__accept_pickle:
            text_server.run()
        else:
            # We need a callback to start the text_server.  We cannot use text_server.run directly since it does
            # not take a run_state argument.
            # noinspection PyUnusedLocal
            def run_text_server(run_state):
                text_server.run()

            # If we are accepting both kinds of traffic, we need a second thread to handle one of the ports.. the
            # other one will be handled by this thread.
            # noinspection PyAttributeOutsideInit
            self.__extra_thread = StoppableThread(target=run_text_server, name='Graphite monitor text server thread')
            self.__extra_thread.start()
            pickle_server.run()

    def stop(self, wait_on_join=True, join_timeout=5):
        # The order here is important.  Since our servers use self._run_state to know when to stop, we need to
        # invoke the inherited method first since that is what actually stops self._run_state.  Then we can join
        # on the threads.
        ScalyrMonitor.stop(self, wait_on_join=wait_on_join, join_timeout=join_timeout)
        if self.__extra_thread is not None:
            self.__extra_thread.stop(wait_on_join=wait_on_join, join_timeout=join_timeout)
Exemple #11
0
class GraphiteMonitor(ScalyrMonitor):
    """A Scalyr agent monitor acts as a Graphite server, accepting metrics over a network connection and then sends
    them to Scalyr.
    """
    def _initialize(self):
        """Performs monitor-specific initialization.
        """
        self.__only_accept_local = self._config.get('only_accept_local')
        self.__accept_plaintext = self._config.get('accept_plaintext')
        self.__accept_pickle = self._config.get('accept_pickle')
        self.__plaintext_port = self._config.get('plaintext_port')
        self.__pickle_port = self._config.get('pickle_port')
        self.__max_connection_idle_time = self._config.get(
            'max_connection_idle_time')
        self.__max_request_size = self._config.get('max_request_size')
        self.__buffer_size = self._config.get('buffer_size')
        # We may need an extra thread for this monitor if we are accepting traffic on both the text and pickle
        # ports since our server abstractions require a thread per port.
        self.__extra_thread = None

        if not self.__accept_plaintext and not self.__accept_pickle:
            raise Exception(
                'Invalid config state for Graphite Monitor.  At least one of accept_plaintext or '
                'accept_pickle must be true')

        if self.__max_request_size > self.__buffer_size:
            raise Exception(
                'The max_request_size of %d cannot be greater than the buffer size of %d'
                % (self.__max_request_size, self.__buffer_size))

    def run(self):
        # We have to (maybe) start up two servers.  Since each server requires its own thread, we may have
        # to create a new one (since we can use this thread to run one of the servers).
        if self.__accept_plaintext:
            text_server = GraphiteTextServer(
                self.__only_accept_local, self.__plaintext_port,
                self._run_state, self.__buffer_size, self.__max_request_size,
                self.__max_connection_idle_time, self._logger)
        else:
            text_server = None

        if self.__accept_pickle:
            pickle_server = GraphitePickleServer(
                self.__only_accept_local, self.__pickle_port, self._run_state,
                self.__buffer_size, self.__max_request_size,
                self.__max_connection_idle_time, self._logger)
        else:
            pickle_server = None

        if not self.__accept_plaintext:
            pickle_server.run()
        elif not self.__accept_pickle:
            text_server.run()
        else:
            # If we are accepting both kinds of traffic, we need a second thread to handle one of the ports.. the
            # other one will be handled by this thread.
            # noinspection PyAttributeOutsideInit
            self.__extra_thread = StoppableThread(
                target=text_server.run,
                name='Graphite monitor text server thread')
            self.__extra_thread.start()
            pickle_server.run()

    def stop(self, wait_on_join=True, join_timeout=5):
        # The order here is important.  Since our servers use self._run_state to know when to stop, we need to
        # invoke the inherited method first since that is what actually stops self._run_state.  Then we can join
        # on the threads.
        ScalyrMonitor.stop(self,
                           wait_on_join=wait_on_join,
                           join_timeout=join_timeout)
        if self.__extra_thread is not None:
            self.__extra_thread.stop(wait_on_join=wait_on_join,
                                     join_timeout=join_timeout)