# Path: canaryd/daemon.py
# def run_daemon(previous_states, settings, start_time=None):
#     if start_time:
#         _sleep_until_interval(
#             start_time, settings.collect_interval_s,
#         )
# 
#     iterations = 1  # start 1 for the initial sync
# 
#     while True:
#         start = time()
# 
#         _daemon_loop(iterations, previous_states, settings)
#         iterations += 1
# 
#         _sleep_until_interval(
#             start, settings.collect_interval_s,
#         )
# 
# Path: canaryd/log.py
# STDOUT_LOG_LEVELS = (logging.DEBUG, logging.INFO)
# STDERR_LOG_LEVELS = (logging.WARNING, logging.ERROR, logging.CRITICAL)
# class LogFilter(logging.Filter):
# class LogFormatter(logging.Formatter):
#     def __init__(self, *levels):
#     def filter(self, record):
#     def format(self, record):
# def setup_logging(verbose, debug, default_level=logging.CRITICAL):
# def setup_logging_from_settings(settings):
# def print_exception(debug_only=False):
# 
# Path: canaryd/plugin.py
# def get_and_prepare_working_plugins(settings, include_slow=True):
#     all_plugins = get_plugins()
#     working_plugins = []
# 
#     for plugin in all_plugins:
#         if not include_slow and plugin.is_slow:
#             continue
# 
#         status = prepare_plugin(plugin, settings)
# 
#         if status is True:
#             working_plugins.append(plugin)
# 
#     logger.info('Loaded plugins: {0}'.format(', '.join([
#         plugin.name
#         for plugin in working_plugins
#     ])))
# 
#     return working_plugins
# 
# def get_plugin_states(plugins, settings):
#     '''
#     Gets state output from multiple plugins.
#     '''
# 
#     return [
#         (plugin, get_plugin_state(plugin, settings))
#         for plugin in plugins
#     ]
# 
# Path: canaryd/remote.py
# def backoff(function, *args, **kwargs):
#     data = None
#     interval = 0
# 
#     error_message = kwargs.pop('error_message', 'API error')
#     max_wait = kwargs.pop('max_wait', 300)
# 
#     while data is None:
#         try:
#             return function(*args, **kwargs)
# 
#         except ApiError as e:
#             if interval + 10 <= max_wait:
#                 interval += 10
# 
#             e.log()
# 
#         logger.critical('{0}, retrying in {1}s'.format(error_message, interval))
#         sleep(interval)
# 
# def ping(settings):
#     return make_api_request(
#         get_session().get,
#         'server/{0}/ping'.format(settings.server_id),
#         settings=settings,
#     )
# 
# def shutdown(settings):
#     return make_api_request(
#         get_session().post,
#         'server/{0}/shutdown'.format(settings.server_id),
#         settings=settings,
#     )
# 
# def sync_states(states, settings):
#     '''
#     Uploads a full state to api.servicecanary.com and returns any data sent back
#     from the server (settings).
#     '''
# 
#     return _upload_states_return_settings(
#         'server/{0}/sync'.format(settings.server_id),
#         make_sync_or_changes_dict(states),
#         settings,
#         json={
#             'hostname': socket.gethostname(),
#             'canaryd_version': __version__,
#         },
#     )
# 
# Path: canaryd/settings.py
# def ensure_config_directory():
#     # Make sure the config directory exists
#     config_directory = get_config_directory()
# 
#     if not path.exists(config_directory):
#         logger.debug('Creating config directory: {0}'.format(config_directory))
#         makedirs(config_directory)
# 
# def get_settings(config_file=None):
#     '''
#     Cached/public version of _get_settings.
#     '''
# 
#     global SETTINGS
# 
#     if SETTINGS is None:
#         SETTINGS = _get_settings(config_file=config_file)
# 
#     return SETTINGS
# 
# Path: canaryd/version.py



import logging
import signal
from time import time
from canaryd_packages import click
from canaryd.daemon import run_daemon
from canaryd.log import logger, setup_logging, setup_logging_from_settings
from canaryd.plugin import (
    get_and_prepare_working_plugins,
    get_plugin_states,
)
from canaryd.remote import backoff, ping, shutdown, sync_states
from canaryd.settings import ensure_config_directory, get_settings
from canaryd.version import __version__
    # Initial ping for API presence
    logger.info('Ping API...')
    backoff(
        ping, settings,
        error_message='Could not ping',
        max_wait=settings.collect_interval_s,
    )

    # Load the plugin list
    plugins = get_and_prepare_working_plugins(settings)

    # Get the initial state
    logger.info('Getting initial state...')
    start_time = time()
    states = get_plugin_states(plugins, settings)

    # Filter out the non-working plugins and wrap as a (command, data) tuple
    # we don't track errors on the initial sync because often canaryd starts
    # early on a server meaning some things aren't up. The next state collection
    # will collect and sync these.
    working_states = []
    for plugin, status_data in states:
        status, data = status_data
        if status is not True:
            continue
        working_states.append((plugin, ('SYNC', data)))

    # Sync this state and get settings
    logger.info('Syncing initial state...')


# Path: canaryd/daemon.py
# def run_daemon(previous_states, settings, start_time=None):
#     if start_time:
#         _sleep_until_interval(
#             start_time, settings.collect_interval_s,
#         )
# 
#     iterations = 1  # start 1 for the initial sync
# 
#     while True:
#         start = time()
# 
#         _daemon_loop(iterations, previous_states, settings)
#         iterations += 1
# 
#         _sleep_until_interval(
#             start, settings.collect_interval_s,
#         )
# 
# Path: canaryd/log.py
# STDOUT_LOG_LEVELS = (logging.DEBUG, logging.INFO)
# STDERR_LOG_LEVELS = (logging.WARNING, logging.ERROR, logging.CRITICAL)
# class LogFilter(logging.Filter):
# class LogFormatter(logging.Formatter):
#     def __init__(self, *levels):
#     def filter(self, record):
#     def format(self, record):
# def setup_logging(verbose, debug, default_level=logging.CRITICAL):
# def setup_logging_from_settings(settings):
# def print_exception(debug_only=False):
# 
# Path: canaryd/plugin.py
# def get_and_prepare_working_plugins(settings, include_slow=True):
#     all_plugins = get_plugins()
#     working_plugins = []
# 
#     for plugin in all_plugins:
#         if not include_slow and plugin.is_slow:
#             continue
# 
#         status = prepare_plugin(plugin, settings)
# 
#         if status is True:
#             working_plugins.append(plugin)
# 
#     logger.info('Loaded plugins: {0}'.format(', '.join([
#         plugin.name
#         for plugin in working_plugins
#     ])))
# 
#     return working_plugins
# 
# def get_plugin_states(plugins, settings):
#     '''
#     Gets state output from multiple plugins.
#     '''
# 
#     return [
#         (plugin, get_plugin_state(plugin, settings))
#         for plugin in plugins
#     ]
# 
# Path: canaryd/remote.py
# def backoff(function, *args, **kwargs):
#     data = None
#     interval = 0
# 
#     error_message = kwargs.pop('error_message', 'API error')
#     max_wait = kwargs.pop('max_wait', 300)
# 
#     while data is None:
#         try:
#             return function(*args, **kwargs)
# 
#         except ApiError as e:
#             if interval + 10 <= max_wait:
#                 interval += 10
# 
#             e.log()
# 
#         logger.critical('{0}, retrying in {1}s'.format(error_message, interval))
#         sleep(interval)
# 
# def ping(settings):
#     return make_api_request(
#         get_session().get,
#         'server/{0}/ping'.format(settings.server_id),
#         settings=settings,
#     )
# 
# def shutdown(settings):
#     return make_api_request(
#         get_session().post,
#         'server/{0}/shutdown'.format(settings.server_id),
#         settings=settings,
#     )
# 
# def sync_states(states, settings):
#     '''
#     Uploads a full state to api.servicecanary.com and returns any data sent back
#     from the server (settings).
#     '''
# 
#     return _upload_states_return_settings(
#         'server/{0}/sync'.format(settings.server_id),
#         make_sync_or_changes_dict(states),
#         settings,
#         json={
#             'hostname': socket.gethostname(),
#             'canaryd_version': __version__,
#         },
#     )
# 
# Path: canaryd/settings.py
# def ensure_config_directory():
#     # Make sure the config directory exists
#     config_directory = get_config_directory()
# 
#     if not path.exists(config_directory):
#         logger.debug('Creating config directory: {0}'.format(config_directory))
#         makedirs(config_directory)
# 
# def get_settings(config_file=None):
#     '''
#     Cached/public version of _get_settings.
#     '''
# 
#     global SETTINGS
# 
#     if SETTINGS is None:
#         SETTINGS = _get_settings(config_file=config_file)
# 
#     return SETTINGS
# 
# Path: canaryd/version.py



# Path: canaryd/__main__.py
import logging
import signal
from time import time
from canaryd_packages import click
from canaryd.daemon import run_daemon
from canaryd.log import logger, setup_logging, setup_logging_from_settings
from canaryd.plugin import (
    get_and_prepare_working_plugins,
    get_plugin_states,
)
from canaryd.remote import backoff, ping, shutdown, sync_states
from canaryd.settings import ensure_config_directory, get_settings
from canaryd.version import __version__

    # Initial ping for API presence
    logger.info('Ping API...')
    backoff(
        ping, settings,
        error_message='Could not ping',
        max_wait=settings.collect_interval_s,
    )

    # Load the plugin list
    plugins = get_and_prepare_working_plugins(settings)

    # Get the initial state
    logger.info('Getting initial state...')
    start_time = time()
    states = get_plugin_states(plugins, settings)

    # Filter out the non-working plugins and wrap as a (command, data) tuple
    # we don't track errors on the initial sync because often canaryd starts
    # early on a server meaning some things aren't up. The next state collection
    # will collect and sync these.
    working_states = []
    for plugin, status_data in states:
        status, data = status_data
        if status is not True:
            continue
        working_states.append((plugin, ('SYNC', data)))

    # Sync this state and get settings
    logger.info('Syncing initial state...')


    remote_settings = backoff(