{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Creating and processing logs\n", "\n", "## Goals\n", " \n", " - importance of logging\n", " - configuring logger module\n", " - open log files\n", " \n", "## modules" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from __future__ import print_function\n", "\n", "import logging\n", "import logging.config\n", "import logging.handlers\n", "import mimetypes\n", "import gzip, bz2\n", "import yaml\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Importance of Logging\n", "\n", "All automation and scripting activity should be carefully logged.\n", "\n", "The ```logging``` module:\n", "\n", " - can stream logs to files and network\n", " - is configurable via yml \n", " - optimizes output via log levels\n", " - takes care of rotation\n", " \n", "Hint: manage logs with syslog.\n", " " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "\n", "# Logs to stdout|err with a default loglevel.\n", "# Logs are not printed on jupyter cells but you can \n", "# check them in another terminal with\n", "# #docker-compose logs\n", "logging.basicConfig(level=logging.DEBUG)\n", "\n", "# Create a logger.\n", "log = logging.getLogger()\n", "\n", "# Logs supports a print-like syntax, and doesn't \n", "# build unneeded message strings. \n", "log.info(\"Use %r instead of %s to avoid\", [u\"Serialization\"], \"issues\")\n", "\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "version: 1\r\n", "formatters:\r\n", " detailed: \r\n", " class: logging.Formatter\r\n", " format: '%(asctime)s %(name)-15s %(levelname)-8s %(processName)-10s %(message)s'\r\n", "\r\n", "handlers:\r\n", " console: \r\n", " class: logging.StreamHandler\r\n", " level: INFO\r\n", " syslog: \r\n", " class: logging.handlers.SysLogHandler\r\n", " formatter: detailed\r\n", " level: DEBUG\r\n", "\r\n", "loggers:\r\n", " os:\r\n", " handlers: [syslog]\r\n", "\r\n", "root:\r\n", " handlers: [console, syslog]\r\n", " level: DEBUG\r\n" ] } ], "source": [ "\n", "%cat logger.yml\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "To syslog\n" ] } ], "source": [ "with open('logger.yml') as logger_config:\n", " logging.config.dictConfig(yaml.safe_load(logger_config))\n", " \n", "# The ```os``` module goes to syslog\n", "log.info(\"To syslog\")\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# To process compressed files, use an helper function. \n", "import mimetools\n", "import gzip\n", "import bz2\n", "\n", "def log_open(path):\n", " \"\"\"Open log files using its mimetype to choose the correct method\"\"\"\n", " l_type, l_encoding = mimetypes.guess_type(path)\n", " if l_encoding == 'gzip':\n", " return gzip.open(path, 'rb')\n", " elif l_encoding == 'bzip2':\n", " return bz2.BZ2File(path, 'rb')\n", " else:\n", " return open(path, 'rb')\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Exercise:\n", "# log some messages modifying the default format string.\n", "# check the outcome in a separate terminal with\n", "# docker-compose logs" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.12" } }, "nbformat": 4, "nbformat_minor": 0 }