krux/python-krux-stdlib

View on GitHub
example.py

Summary

Maintainability
A
50 mins
Test Coverage
#!/usr/bin/env python3
# Copyright 2013-2020 Salesforce.com, inc.
import krux.cli


class ExampleLoggingApp(krux.cli.Application):
    """
    This class gets a few things for free; not least of which:
      * a command-line option parser
      * a logger
      * a stats dispatcher
      * a context manager, which cleans up after us,
        including deleting the lock file, if one was created.
    """
    def __init__(
        self,
        name,
        parser=None,
        logger=None,
        lockfile=False,
        syslog_facility=krux.cli.DEFAULT_LOG_FACILITY,
        log_to_stdout=True,
        parser_args=None,
    ):
        # The above method signature matches that of the parent, krux.cli.Application.__init__()
        super(ExampleLoggingApp, self).__init__(
            name=name,
            parser=parser,
            logger=logger,
            lockfile=lockfile,
            syslog_facility=syslog_facility,
            log_to_stdout=log_to_stdout,
            parser_args=parser_args,
        )

        # If you have command line arguments, this is when you want
        # to get retrieve & store them. super().__init__() will have stored them
        # self.args for us. The only place we want to read from self.args
        # is here in our __init__().
        self.bit_bucket_kg = self.args.bit_bucket_kg
        self.has_headlight_fluid = self.args.has_headlight_fluid

        # Do any other initialization tasks here

    # If your app wants to add its own command line arguments, do it here.
    # If not, then you don't need to create this method.
    def add_cli_arguments(self, parser):
        super(ExampleLoggingApp, self).add_cli_arguments(parser)

        # See the docstring & comments in get_group()
        group = krux.cli.get_group(self.parser, self.name)
        # Build arguments as you would with ArgumentParser
        # https://docs.python.org/2.7/library/argparse.html
        group.add_argument(
            '--bit-bucket-kg',
            default=5,
            help='Bit bucket weight in kg.',
        )
        group.add_argument(
            '-f', '--has-headlight-fluid',
            default=False,
            action='store_true',
            help='Contains sufficient headlight fluid.',
        )

    def run(self):
        """
        Trivial example of calling at least one thing.
        """
        print('The bit bucket weighs {} kg.'.format(self.bit_bucket_kg))
        if self.has_headlight_fluid:
            print('We have enough headlight fluid.')
        else:
            print('We could use more headlight fluid.')
        # the default log level is "warn" so you won't see these unless
        # you pass in --log-level from the command line
        self.logger.critical("this is a critical level message")
        self.logger.error("this is a error level message")
        self.logger.warn("this is a warning level message")
        self.logger.info("this is a info level message")
        self.logger.debug("this is a debug level message")


def main():
    # instantiate your application class.

    # the 'name' parameter is just a string/name for your script. It should be unique in your environment,
    # because stats will be emitted to statsd with that as part of the stat name.

    # the syslog_facility parameter being set changes where logs get sent to;
    # the default is to print them out to the console; setting a syslog facility
    # means messages will go to syslog with the named facility and called severity;
    # your local syslog config will need to route those messages to a file or remote syslog.

    app = ExampleLoggingApp('testloggingapp', syslog_facility='local0')

    # app.context() makes sure the exceptions are logged, if any, exit hooks are handled (i.e. lock files),
    # and exit code is set properly.
    with app.context():
        # go ahead and call whatever methods you have defined under your app; .logger is
        # provided by the Krux standard library. calling logger with each available log level
        # might help you diagnose/tune your local syslog config; you can also over-ride the
        # class' syslog_facility as configured above with the --syslog-facility argument.
        app.logger.info('Doing app things.')
        app.run()
        app.logger.info('Finished doing app things.')


if __name__ == '__main__':
    main()