{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Usage Example\n", "\n", "Vislog (Visual Logger) adds a visual effect to standard logging. It is useful for logging in a function with multiple nested blocks and can help you understand the program's execution flow.\n", "\n", "## Create Visual Logger" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "import json\n", "import time\n", "from vislog import VisLog, AlignEnum\n", "\n", "logger = VisLog(name=\"vislog_demo\")" ] }, { "cell_type": "raw", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "See :class:`~vislog.impl.VisLog` for how to constructing a new logger." ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## Just Logging\n", "\n", "Just call ``.debug(\"message here\")``, ``.info(...)``, ..., ``.critical(...)`` to log some message. The ``|`` pipe character is for nested log block." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:18] | hello\n" ] } ], "source": [ "logger.info(\"hello\");" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Change the default pipe character" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:18] + hello\n" ] } ], "source": [ "logger.info(\"hello\", pipe=\"+\");" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## Ruler\n", "\n", "Horizontal ruler, by default it is left aligned" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:18] +----- start ------------------------------------------------------------------+\n" ] } ], "source": [ "logger.ruler(\"start\");" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Ruler can be center aligned" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:18] +----------------------------------- start ------------------------------------+\n" ] } ], "source": [ "logger.ruler(\"start\", align=AlignEnum.middle);" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Ruler can be right aligned" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:18] +------------------------------------------------------------------ start -----+\n" ] } ], "source": [ "logger.ruler(\"start\", align=AlignEnum.right);" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Ruler has many option, you can customize the ruler character." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:18] +===== start ==================================================================+\n" ] } ], "source": [ "logger.ruler(\"start\", char=\"=\");" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "You can customize corner character too." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:19] #----- start ------------------------------------------------------------------#\n" ] } ], "source": [ "logger.ruler(\"start\", corner=\"#\");" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## Multiline Message" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "If the log message across multiple lines, it still looks nice." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:19] | {\n", "[User 2024-06-16 15:06:19] | \"a\": {\n", "[User 2024-06-16 15:06:19] | \"b\": {\n", "[User 2024-06-16 15:06:19] | \"c\": 3\n", "[User 2024-06-16 15:06:19] | }\n", "[User 2024-06-16 15:06:19] | }\n", "[User 2024-06-16 15:06:19] | }\n" ] } ], "source": [ "data = {\n", " \"a\": {\n", " \"b\": {\n", " \"c\": 3\n", " }\n", " }\n", "}\n", "logger.info(json.dumps(data, indent=4));" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## Nested Log Block" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "You can put logic blocks nesting each other to improve readability." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:20] +----- section 1 --------------------------------------------------------------+\n", "[User 2024-06-16 15:06:20] | hello 1\n", "[User 2024-06-16 15:06:20] | +----- section 1.1 ----------------------------------------------------------+\n", "[User 2024-06-16 15:06:20] | | hello 1.1\n", "[User 2024-06-16 15:06:20] | | +----- section 1.1.1 ------------------------------------------------------+\n", "[User 2024-06-16 15:06:20] | | | hello 1.1.1\n", "[User 2024-06-16 15:06:20] | | +----- section 1.1.1 ------------------------------------------------------+\n", "[User 2024-06-16 15:06:20] | +----- section 1.1 ----------------------------------------------------------+\n", "[User 2024-06-16 15:06:20] +----- section 1 --------------------------------------------------------------+\n" ] } ], "source": [ "logger.ruler(\"section 1\")\n", "logger.info(\"hello 1\")\n", "\n", "with logger.nested():\n", " logger.ruler(\"section 1.1\")\n", " logger.info(\"hello 1.1\")\n", " \n", " with logger.nested():\n", " logger.ruler(\"section 1.1.1\")\n", " logger.info(\"hello 1.1.1\")\n", " logger.ruler(\"section 1.1.1\")\n", " \n", " logger.ruler(\"section 1.1\")\n", " \n", "logger.ruler(\"section 1\");" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## pretty_log Decorator\n", "\n", "You don't have to explicitly construct the nested log block. A decorator can help you. It will log a ruler when you enter and exit the function automatically. You can use pretty log decorator to wrap a function to provide this visual effect easily." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:20] +----- Start func1() ----------------------------------------------------------+\n", "[User 2024-06-16 15:06:20] | \n", "[User 2024-06-16 15:06:21] | run func1\n", "[User 2024-06-16 15:06:21] | \n", "[User 2024-06-16 15:06:21] +----- End func1(), elapsed = 1.01 sec ----------------------------------------+\n" ] } ], "source": [ "@logger.pretty_log()\n", "def func1():\n", " time.sleep(1)\n", " logger.info(\"run func1\")\n", "\n", "func1()" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "The default enter and exit ruler use the following string template ``\"Start {func_name}()\"`` and ``\"Error {func_name}(), elapsed = {elapsed:.2f} sec\"``, you can customize this." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:21] +----- Start func1(name=Alice) ------------------------------------------------+\n", "[User 2024-06-16 15:06:21] | \n", "[User 2024-06-16 15:06:22] | run func1: name = Alice\n", "[User 2024-06-16 15:06:22] | \n", "[User 2024-06-16 15:06:22] +----- End func1(), elapsed = 1.01 sec ----------------------------------------+\n" ] } ], "source": [ "@logger.pretty_log(\n", " start_msg=\"Start {func_name}(name={name})\",\n", " end_msg=\"End {func_name}(), elapsed = {elapsed:.2f} sec\",\n", ")\n", "def func1(name: str):\n", " time.sleep(1)\n", " logger.info(f\"run func1: name = {name}\")\n", "\n", "func1(name=\"Alice\")" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "``pretty_log`` decorator also automatically add a ruler when raises an error. You can customize the error ruler too." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:34] +----- Start func1() ----------------------------------------------------------+\n", "[User 2024-06-16 15:06:34] | \n", "[User 2024-06-16 15:06:35] | \n", "[User 2024-06-16 15:06:35] +----- OPS! -------------------------------------------------------------------+\n" ] }, { "ename": "ValueError", "evalue": "something wrong!", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[14], line 8\u001b[0m\n\u001b[1;32m 5\u001b[0m time\u001b[38;5;241m.\u001b[39msleep(\u001b[38;5;241m1\u001b[39m)\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msomething wrong!\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m----> 8\u001b[0m \u001b[43mfunc1\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[0;32m~/Documents/GitHub/vislog-project/vislog/impl.py:655\u001b[0m, in \u001b[0;36mVisLog.pretty_log..deco..wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 653\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m nest \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m (pipe \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m 654\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pipe_end(pipe, last_pipe)\n\u001b[0;32m--> 655\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m 657\u001b[0m et \u001b[38;5;241m=\u001b[39m datetime\u001b[38;5;241m.\u001b[39mutcnow()\n\u001b[1;32m 658\u001b[0m elapsed \u001b[38;5;241m=\u001b[39m (et \u001b[38;5;241m-\u001b[39m st)\u001b[38;5;241m.\u001b[39mtotal_seconds()\n", "File \u001b[0;32m~/Documents/GitHub/vislog-project/vislog/impl.py:632\u001b[0m, in \u001b[0;36mVisLog.pretty_log..deco..wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 629\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minfo(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 631\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 632\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 634\u001b[0m et \u001b[38;5;241m=\u001b[39m datetime\u001b[38;5;241m.\u001b[39mutcnow()\n", "Cell \u001b[0;32mIn[14], line 6\u001b[0m, in \u001b[0;36mfunc1\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;129m@logger\u001b[39m\u001b[38;5;241m.\u001b[39mpretty_log(\n\u001b[1;32m 2\u001b[0m error_msg\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mOPS!\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 3\u001b[0m )\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfunc1\u001b[39m():\n\u001b[1;32m 5\u001b[0m time\u001b[38;5;241m.\u001b[39msleep(\u001b[38;5;241m1\u001b[39m)\n\u001b[0;32m----> 6\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msomething wrong!\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", "\u001b[0;31mValueError\u001b[0m: something wrong!" ] } ], "source": [ "@logger.pretty_log(\n", " error_msg=\"OPS!\",\n", ")\n", "def func1():\n", " time.sleep(1)\n", " raise ValueError(\"something wrong!\")\n", "\n", "func1()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nest Pretty Log Block.\n", "\n", "You can nest one function in another too! It automatically gives you a human friendly visual effect." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:38] +----- Start func3() ----------------------------------------------------------+\n", "[User 2024-06-16 15:06:38] | \n", "[User 2024-06-16 15:06:39] | run func3\n", "[User 2024-06-16 15:06:39] | +----- Start func2() --------------------------------------------------------+\n", "[User 2024-06-16 15:06:39] | | \n", "[User 2024-06-16 15:06:40] | | run func2\n", "[User 2024-06-16 15:06:40] | | \n", "[User 2024-06-16 15:06:40] | +----- End func2(), elapsed = 1.00 sec --------------------------------------+\n", "[User 2024-06-16 15:06:40] | \n", "[User 2024-06-16 15:06:40] +----- End func3(), elapsed = 2.02 sec ----------------------------------------+\n" ] } ], "source": [ "@logger.pretty_log()\n", "def func2():\n", " time.sleep(1)\n", " logger.info(\"run func2\")\n", "\n", "@logger.pretty_log()\n", "def func3():\n", " time.sleep(1)\n", " logger.info(\"run func3\")\n", " with logger.nested():\n", " func2()\n", "\n", "func3()" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "editable": true, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%% md\n" }, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "You can customize the pipe character to create a semantic visual effect." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:40] +----- Start run_deploy() -----------------------------------------------------+\n", "[User 2024-06-16 15:06:40] ๐Ÿš€ \n", "[User 2024-06-16 15:06:41] ๐Ÿš€ run deploy\n", "[User 2024-06-16 15:06:41] ๐Ÿš€ +----- Start run_test() -----------------------------------------------------+\n", "[User 2024-06-16 15:06:41] ๐Ÿš€ ๐Ÿงช \n", "[User 2024-06-16 15:06:42] ๐Ÿš€ ๐Ÿงช run test\n", "[User 2024-06-16 15:06:42] ๐Ÿš€ ๐Ÿงช +----- Start run_build() --------------------------------------------------+\n", "[User 2024-06-16 15:06:42] ๐Ÿš€ ๐Ÿงช ๐Ÿญ \n", "[User 2024-06-16 15:06:43] ๐Ÿš€ ๐Ÿงช ๐Ÿญ run build\n", "[User 2024-06-16 15:06:43] ๐Ÿš€ ๐Ÿงช ๐Ÿญ \n", "[User 2024-06-16 15:06:43] ๐Ÿš€ ๐Ÿงช +----- End run_build(), elapsed = 1.00 sec --------------------------------+\n", "[User 2024-06-16 15:06:43] ๐Ÿš€ ๐Ÿงช \n", "[User 2024-06-16 15:06:43] ๐Ÿš€ +----- End run_test(), elapsed = 2.01 sec -----------------------------------+\n", "[User 2024-06-16 15:06:43] ๐Ÿš€ \n", "[User 2024-06-16 15:06:43] +----- End run_deploy(), elapsed = 3.02 sec -----------------------------------+\n" ] } ], "source": [ "@logger.pretty_log(pipe=\"๐Ÿญ\")\n", "def run_build():\n", " time.sleep(1)\n", " logger.info(\"run build\")\n", "\n", "@logger.pretty_log(pipe=\"๐Ÿงช\")\n", "def run_test():\n", " time.sleep(1)\n", " logger.info(\"run test\")\n", " with logger.nested():\n", " run_build()\n", "\n", "@logger.pretty_log(pipe=\"๐Ÿš€\")\n", "def run_deploy():\n", " time.sleep(1)\n", " logger.info(\"run deploy\")\n", " with logger.nested():\n", " run_test()\n", "\n", "run_deploy()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## start_and_end Decorator\n", "\n", "``start_and_end`` decorator is just a wrapper of the ``pretty_log`` decorator, it provide nice looking emoji for start, end and error. ``start_and_end`` is basically a equavilent of:\n", "\n", "```python\n", "@pretty_log(\n", " start_emoji=\"๐Ÿ•‘ ๐ŸŸข Start\",\n", " error_emoji=\"โฐ ๐Ÿ”ด Error\",\n", " end_emoji=\"โฐ ๐Ÿ”ด End\",\n", ")\n", "def your_function():\n", " ...\n", "```" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:43] +----- ๐Ÿ•‘ ๐ŸŸข Start 'My Function 1' ----------------------------------------------+\n", "[User 2024-06-16 15:06:43] ๐Ÿ“ฆ \n", "[User 2024-06-16 15:06:44] ๐Ÿ“ฆ alice do something in my func 1\n", "[User 2024-06-16 15:06:44] ๐Ÿ“ฆ \n", "[User 2024-06-16 15:06:44] +----- โฐ ๐Ÿ”ด End 'My Function 1', elapsed = 1.01 sec ----------------------------+\n" ] } ], "source": [ "@logger.start_and_end(\n", " msg=\"My Function 1\",\n", " start_emoji=\"๐ŸŸข\",\n", " end_emoji=\"๐Ÿ”ด\",\n", " pipe=\"๐Ÿ“ฆ\",\n", ")\n", "def my_func1(name: str):\n", " time.sleep(1)\n", " logger.info(f\"{name} do something in my func 1\")\n", "\n", "my_func1(name=\"alice\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## emoji_block Decorator\n", "\n", "``emoji_block`` decorator is just a wrapper of the ``start_and_end`` decorator. \n", "\n", "1. Use ``๐Ÿ•‘ {emoji}`` at begin.\n", "2. Use ``โฐ โœ… {emoji}`` at the end if exit successfully.\n", "3. Use ``โฐ โŒ {emoji}`` at the end if raises an error." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:44] +----- ๐Ÿ•‘ ๐Ÿš€ Start 'Deploy app my_app' ------------------------------------------+\n", "[User 2024-06-16 15:06:44] ๐Ÿš€ \n", "[User 2024-06-16 15:06:44] ๐Ÿš€ working ...\n", "[User 2024-06-16 15:06:44] ๐Ÿš€ done\n", "[User 2024-06-16 15:06:44] ๐Ÿš€ \n", "[User 2024-06-16 15:06:44] +----- โฐ โœ… ๐Ÿš€ End 'Deploy app my_app', elapsed = 0.01 sec ----------------------+\n" ] } ], "source": [ "@logger.emoji_block(\n", " msg=\"Deploy app {app_name}\", # set a semantic title \n", " emoji=\"๐Ÿš€\",\n", ")\n", "def deploy_app(app_name: str):\n", " logger.info(\"working ...\")\n", " logger.info(\"done\")\n", "\n", "deploy_app(app_name=\"my_app\")" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[User 2024-06-16 15:06:44] +----- ๐Ÿ•‘ ๐Ÿš€ Start 'deploy' -----------------------------------------------------+\n", "[User 2024-06-16 15:06:44] ๐Ÿš€ \n", "[User 2024-06-16 15:06:45] ๐Ÿš€ run deploy\n", "[User 2024-06-16 15:06:45] ๐Ÿš€ +----- ๐Ÿ•‘ ๐Ÿงช Start 'test' -----------------------------------------------------+\n", "[User 2024-06-16 15:06:45] ๐Ÿš€ ๐Ÿงช \n", "[User 2024-06-16 15:06:46] ๐Ÿš€ ๐Ÿงช run test\n", "[User 2024-06-16 15:06:46] ๐Ÿš€ ๐Ÿงช +----- ๐Ÿ•‘ ๐Ÿญ Start 'build' --------------------------------------------------+\n", "[User 2024-06-16 15:06:46] ๐Ÿš€ ๐Ÿงช ๐Ÿญ \n", "[User 2024-06-16 15:06:47] ๐Ÿš€ ๐Ÿงช ๐Ÿญ run build\n", "[User 2024-06-16 15:06:47] ๐Ÿš€ ๐Ÿงช ๐Ÿญ \n", "[User 2024-06-16 15:06:47] ๐Ÿš€ ๐Ÿงช +----- โฐ โœ… ๐Ÿญ End 'build', elapsed = 1.01 sec ------------------------------+\n", "[User 2024-06-16 15:06:47] ๐Ÿš€ ๐Ÿงช \n", "[User 2024-06-16 15:06:47] ๐Ÿš€ +----- โฐ โœ… ๐Ÿงช End 'test', elapsed = 2.02 sec ---------------------------------+\n", "[User 2024-06-16 15:06:47] ๐Ÿš€ \n", "[User 2024-06-16 15:06:47] +----- โฐ โœ… ๐Ÿš€ End 'deploy', elapsed = 3.03 sec ---------------------------------+\n" ] } ], "source": [ "@logger.emoji_block(msg=\"build\", emoji=\"๐Ÿญ\")\n", "def run_build():\n", " time.sleep(1)\n", " logger.info(\"run build\")\n", "\n", "@logger.emoji_block(msg=\"test\", emoji=\"๐Ÿงช\")\n", "def run_test():\n", " time.sleep(1)\n", " logger.info(\"run test\")\n", " with logger.nested():\n", " run_build()\n", "\n", "@logger.emoji_block(msg=\"deploy\", emoji=\"๐Ÿš€\")\n", "def run_deploy():\n", " time.sleep(1)\n", " logger.info(\"run deploy\")\n", " with logger.nested():\n", " run_test()\n", "\n", "run_deploy()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Integrate with Other Logging Library\n", "\n", "You can use ``vislog`` library with any of your favorite logging library. You just need to set the logger as a custom ``logging.Logger()`` object or any object what support ``logger.debug(\"message here\")``, ``logger.info(...)``, ``logger.warning(...)``, ``logger.error(...)``, ``logger.critical(...)``. The visual logger will use this object to log the message. If not provided, a new logger will be created by default." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\u001b[32m2024-06-16 15:57:47.639\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36mruler\u001b[0m:\u001b[36m441\u001b[0m - \u001b[1m+----- ๐Ÿ•‘ ๐Ÿš€ Start 'deploy' -----------------------------------------------------+\u001b[0m\n", "\u001b[32m2024-06-16 15:57:47.640\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ \u001b[0m\n", "\u001b[32m2024-06-16 15:57:48.645\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ run deploy\u001b[0m\n", "\u001b[32m2024-06-16 15:57:48.648\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36mruler\u001b[0m:\u001b[36m441\u001b[0m - \u001b[1m๐Ÿš€ +----- ๐Ÿ•‘ ๐Ÿงช Start 'test' -----------------------------------------------------+\u001b[0m\n", "\u001b[32m2024-06-16 15:57:48.650\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ ๐Ÿงช \u001b[0m\n", "\u001b[32m2024-06-16 15:57:49.654\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ ๐Ÿงช run test\u001b[0m\n", "\u001b[32m2024-06-16 15:57:49.657\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36mruler\u001b[0m:\u001b[36m441\u001b[0m - \u001b[1m๐Ÿš€ ๐Ÿงช +----- ๐Ÿ•‘ ๐Ÿญ Start 'build' --------------------------------------------------+\u001b[0m\n", "\u001b[32m2024-06-16 15:57:49.659\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ ๐Ÿงช ๐Ÿญ \u001b[0m\n", "\u001b[32m2024-06-16 15:57:50.663\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ ๐Ÿงช ๐Ÿญ run build\u001b[0m\n", "\u001b[32m2024-06-16 15:57:50.666\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ ๐Ÿงช ๐Ÿญ \u001b[0m\n", "\u001b[32m2024-06-16 15:57:50.668\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36mruler\u001b[0m:\u001b[36m441\u001b[0m - \u001b[1m๐Ÿš€ ๐Ÿงช +----- โฐ โœ… ๐Ÿญ End 'build', elapsed = 1.01 sec ------------------------------+\u001b[0m\n", "\u001b[32m2024-06-16 15:57:50.669\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ ๐Ÿงช \u001b[0m\n", "\u001b[32m2024-06-16 15:57:50.670\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36mruler\u001b[0m:\u001b[36m441\u001b[0m - \u001b[1m๐Ÿš€ +----- โฐ โœ… ๐Ÿงช End 'test', elapsed = 2.02 sec ---------------------------------+\u001b[0m\n", "\u001b[32m2024-06-16 15:57:50.671\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36m_log\u001b[0m:\u001b[36m318\u001b[0m - \u001b[1m๐Ÿš€ \u001b[0m\n", "\u001b[32m2024-06-16 15:57:50.673\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mvislog.impl\u001b[0m:\u001b[36mruler\u001b[0m:\u001b[36m441\u001b[0m - \u001b[1m+----- โฐ โœ… ๐Ÿš€ End 'deploy', elapsed = 3.03 sec ---------------------------------+\u001b[0m\n" ] } ], "source": [ "# use loguru: https://github.com/Delgan/loguru\n", "from loguru import logger as loguru_logger\n", "\n", "logger = VisLog(logger=loguru_logger, name=\"vislog_demo\")\n", "\n", "\n", "@logger.emoji_block(msg=\"build\", emoji=\"๐Ÿญ\")\n", "def run_build():\n", " time.sleep(1)\n", " logger.info(\"run build\")\n", "\n", "@logger.emoji_block(msg=\"test\", emoji=\"๐Ÿงช\")\n", "def run_test():\n", " time.sleep(1)\n", " logger.info(\"run test\")\n", " with logger.nested():\n", " run_build()\n", "\n", "@logger.emoji_block(msg=\"deploy\", emoji=\"๐Ÿš€\")\n", "def run_deploy():\n", " time.sleep(1)\n", " logger.info(\"run deploy\")\n", " with logger.nested():\n", " run_test()\n", "\n", "run_deploy()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## More Public API" ] }, { "cell_type": "raw", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "- :class:`vislog.impl.AlignEnum`\n", "- :meth:`vislog.impl.VisLog.pipe`\n", "- :meth:`vislog.impl.VisLog.ruler`\n", "- :meth:`vislog.impl.VisLog.indent`\n", "- :meth:`vislog.impl.VisLog.nested`\n", "- :meth:`vislog.impl.VisLog.pretty_log`\n", "- :meth:`vislog.impl.VisLog.start_and_end`\n", "- :meth:`vislog.impl.VisLog.emoji_block`\n", "- :meth:`vislog.impl.VisLog.disabled`" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 4 }