{"title":"How to configure and use logging","version":"dev","locale":"en","docname":"howto/logging","url":"/en/dev/howto/logging/","canonical":"https://djangodocs.dev/en/dev/howto/logging/","summary":"Django provides a working default logging configuration that is readily extended.","html":"<span id=\"logging-how-to\"></span><h1>How to configure and use logging<a class=\"heading-anchor\" href=\"#how-to-configure-and-use-logging\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">See also</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/logging/#logging-ref\"><span class=\"std std-ref\">Django logging reference</span></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/logging/#logging-explanation\"><span class=\"std std-ref\">Django logging overview</span></a></p></li>\n</ul>\n</aside>\n<p>Django provides a working <a class=\"reference internal\" href=\"/en/dev/ref/logging/#default-logging-configuration\"><span class=\"std std-ref\">default logging configuration</span></a> that is readily extended.</p>\n<section id=\"make-a-basic-logging-call\">\n<h2>Make a basic logging call<a class=\"heading-anchor\" href=\"#make-a-basic-logging-call\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>To send a log message from within your code, you place a logging call into it.</p>\n<aside class=\"admonition-don-t-be-tempted-to-use-logging-calls-in-settings-py admonition\" role=\"note\">\n<p class=\"admonition-title\">Don’t be tempted to use logging calls in <code class=\"docutils literal notranslate\">settings.py</code>.</p>\n<p>The way that Django logging is configured as part of the <code class=\"docutils literal notranslate\">setup()</code>\nfunction means that logging calls placed in <code class=\"docutils literal notranslate\">settings.py</code> may not work as\nexpected, because <em>logging will not be set up at that point</em>. To explore\nlogging, use a view function as suggested in the example below.</p>\n</aside>\n<p>First, import the Python logging library, and then obtain a logger instance\nwith <a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.html#logging.getLogger\" title=\"(in Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\">logging.getLogger()</code></a>. Provide the <code class=\"docutils literal notranslate\">getLogger()</code> method with a\nname to identify it and the records it emits. A good option is to use\n<code class=\"docutils literal notranslate\">__name__</code> (see <a class=\"reference internal\" href=\"#naming-loggers\"><span class=\"std std-ref\">Use logger namespacing</span></a> below for more on this) which will\nprovide the name of the current Python module as a dotted path:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span> <span class=\"nn\">logging</span>\n\nlogger <span class=\"o\">=</span> logging<span class=\"o\">.</span>getLogger<span class=\"p\">(</span><span class=\"vm\">__name__</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>It’s a good convention to perform this declaration at module level.</p>\n<p>And then in a function, for example in a view, send a record to the logger:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span> <span class=\"nf\">some_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    <span class=\"k\">if</span> some_risky_state<span class=\"p\">:</span>\n        logger<span class=\"o\">.</span>warning<span class=\"p\">(</span><span class=\"s2\">&quot;Platform is running at risk&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>When this code is executed, a <a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.html#logging.LogRecord\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">LogRecord</code></a> containing that\nmessage will be sent to the logger. If you’re using Django’s default logging\nconfiguration, the message will appear in the console.</p>\n<p>The <code class=\"docutils literal notranslate\">WARNING</code> level used in the example above is one of several\n<a class=\"reference internal\" href=\"/en/dev/topics/logging/#topic-logging-parts-loggers\"><span class=\"std std-ref\">logging severity levels</span></a>: <code class=\"docutils literal notranslate\">DEBUG</code>,\n<code class=\"docutils literal notranslate\">INFO</code>, <code class=\"docutils literal notranslate\">WARNING</code>, <code class=\"docutils literal notranslate\">ERROR</code>, <code class=\"docutils literal notranslate\">CRITICAL</code>. So, another example might be:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>logger<span class=\"o\">.</span>critical<span class=\"p\">(</span><span class=\"s2\">&quot;Payment system is not responding&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"admonition admonition-important\" role=\"note\">\n<p class=\"admonition-title\">Important</p>\n<p>Records with a level lower than <code class=\"docutils literal notranslate\">WARNING</code> will not appear in the console\nby default. Changing this behavior requires additional configuration.</p>\n</aside>\n</section>\n<section id=\"customize-logging-configuration\">\n<h2>Customize logging configuration<a class=\"heading-anchor\" href=\"#customize-logging-configuration\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Although Django’s logging configuration works out of the box, you can control\nexactly how your logs are sent to various destinations - to log files, external\nservices, email and so on - with some additional configuration.</p>\n<p>You can configure:</p>\n<ul class=\"simple\">\n<li><p>logger mappings, to determine which records are sent to which handlers</p></li>\n<li><p>handlers, to determine what they do with the records they receive</p></li>\n<li><p>filters, to provide additional control over the transfer of records, and\neven modify records in-place</p></li>\n<li><p>formatters, to convert <a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.html#logging.LogRecord\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">LogRecord</code></a> objects to a string or\nother form for consumption by human beings or another system</p></li>\n</ul>\n<p>There are various ways of configuring logging. In Django, the\n<a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-LOGGING\"><code class=\"xref std std-setting docutils literal notranslate\">LOGGING</code></a> setting is most commonly used. The setting uses the\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.config.html#logging-config-dictschema\" title=\"(in Python v3.14)\"><span class=\"xref std std-ref\">dictConfig format</span></a>, and extends the\n<a class=\"reference internal\" href=\"/en/dev/ref/logging/#default-logging-definition\"><span class=\"std std-ref\">default logging configuration</span></a>.</p>\n<p>See <a class=\"reference internal\" href=\"/en/dev/topics/logging/#configuring-logging\"><span class=\"std std-ref\">Configuring logging</span></a> for an explanation of how your custom settings\nare merged with Django’s defaults.</p>\n<p>See the <a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.config.html#module-logging.config\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\">Python logging documentation</code></a> for\ndetails of other ways of configuring logging. For the sake of simplicity, this\ndocumentation will only consider configuration via the <code class=\"docutils literal notranslate\">LOGGING</code> setting.</p>\n<section id=\"basic-logging-configuration\">\n<span id=\"basic-logger-configuration\"></span><h3>Basic logging configuration<a class=\"heading-anchor\" href=\"#basic-logging-configuration\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When configuring logging, it makes sense to</p>\n<section id=\"create-a-logging-dictionary\">\n<h4>Create a <code class=\"docutils literal notranslate\">LOGGING</code> dictionary<a class=\"heading-anchor\" href=\"#create-a-logging-dictionary\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>In your <code class=\"docutils literal notranslate\">settings.py</code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>LOGGING <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;version&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>  <span class=\"c1\"># the dictConfig format version</span>\n    <span class=\"s2\">&quot;disable_existing_loggers&quot;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>  <span class=\"c1\"># retain the default loggers</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>It nearly always makes sense to retain and extend the default logging\nconfiguration by setting <code class=\"docutils literal notranslate\">disable_existing_loggers</code> to <code class=\"docutils literal notranslate\">False</code>.</p>\n</section>\n<section id=\"configure-a-handler\">\n<h4>Configure a handler<a class=\"heading-anchor\" href=\"#configure-a-handler\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>This example configures a single handler named <code class=\"docutils literal notranslate\">file</code>, that uses Python’s\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.handlers.html#logging.FileHandler\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">FileHandler</code></a> to save logs of level <code class=\"docutils literal notranslate\">DEBUG</code> and higher to the\nfile <code class=\"docutils literal notranslate\">general.log</code> (at the project root):</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code>LOGGING <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"c1\"># ...</span>\n<span class=\"hll\">    <span class=\"s2\">&quot;handlers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n</span><span class=\"hll\">        <span class=\"s2\">&quot;file&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n</span><span class=\"hll\">            <span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;logging.FileHandler&quot;</span><span class=\"p\">,</span>\n</span><span class=\"hll\">            <span class=\"s2\">&quot;filename&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;general.log&quot;</span><span class=\"p\">,</span>\n</span><span class=\"hll\">        <span class=\"p\">},</span>\n</span><span class=\"hll\">    <span class=\"p\">},</span>\n</span><span class=\"p\">}</span>\n</code></pre></div>\n<p>Different handler classes take different configuration options. For more\ninformation on available handler classes, see the\n<a class=\"reference internal\" href=\"/en/dev/ref/logging/#django.utils.log.AdminEmailHandler\" title=\"django.utils.log.AdminEmailHandler\"><code class=\"xref py py-class docutils literal notranslate\">AdminEmailHandler</code></a> provided by Django and the various\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.handlers.html#module-logging.handlers\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\">handler classes</code></a> provided by Python.</p>\n<p>Logging levels can also be set on the handlers (by default, they accept log\nmessages of all levels). Using the example above, adding:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"p\">{</span>\n    <span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;logging.FileHandler&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;filename&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;general.log&quot;</span><span class=\"p\">,</span>\n<span class=\"hll\">    <span class=\"s2\">&quot;level&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;DEBUG&quot;</span><span class=\"p\">,</span>\n</span><span class=\"p\">}</span>\n</code></pre></div>\n<p>would define a handler configuration that only accepts records of level\n<code class=\"docutils literal notranslate\">DEBUG</code> and higher.</p>\n</section>\n<section id=\"configure-a-logger-mapping\">\n<h4>Configure a logger mapping<a class=\"heading-anchor\" href=\"#configure-a-logger-mapping\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>To send records to this handler, configure a logger mapping to use it for\nexample:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code>LOGGING <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"c1\"># ...</span>\n<span class=\"hll\">    <span class=\"s2\">&quot;loggers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n</span><span class=\"hll\">        <span class=\"s2\">&quot;&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n</span><span class=\"hll\">            <span class=\"s2\">&quot;level&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;DEBUG&quot;</span><span class=\"p\">,</span>\n</span><span class=\"hll\">            <span class=\"s2\">&quot;handlers&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;file&quot;</span><span class=\"p\">],</span>\n</span><span class=\"hll\">        <span class=\"p\">},</span>\n</span><span class=\"hll\">    <span class=\"p\">},</span>\n</span><span class=\"p\">}</span>\n</code></pre></div>\n<p>The mapping’s name determines which log records it will process. This\nconfiguration (<code class=\"docutils literal notranslate\">''</code>) is <em>unnamed</em>. That means that it will process records\nfrom <em>all</em> loggers (see <a class=\"reference internal\" href=\"#naming-loggers\"><span class=\"std std-ref\">Use logger namespacing</span></a> below on how to use the mapping\nname to determine the loggers for which it will process records).</p>\n<p>It will forward messages of levels <code class=\"docutils literal notranslate\">DEBUG</code> and higher to the handler named\n<code class=\"docutils literal notranslate\">file</code>.</p>\n<p>Note that a logger can forward messages to multiple handlers, so the relation\nbetween loggers and handlers is many-to-many.</p>\n<p>If you execute:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>logger<span class=\"o\">.</span>debug<span class=\"p\">(</span><span class=\"s2\">&quot;Attempting to connect to API&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>in your code, you will find that message in the file <code class=\"docutils literal notranslate\">general.log</code> in the\nroot of the project.</p>\n</section>\n<section id=\"configure-a-formatter\">\n<h4>Configure a formatter<a class=\"heading-anchor\" href=\"#configure-a-formatter\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>By default, the final log output contains the message part of each\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.html#logging.LogRecord\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">LogRecord</code></a> object. Use a formatter if you want to include\nadditional data. First name and define your formatters - this example defines\nformatters named <code class=\"docutils literal notranslate\">verbose</code> and <code class=\"docutils literal notranslate\">simple</code>:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code>LOGGING <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"c1\"># ...</span>\n<span class=\"hll\">    <span class=\"s2\">&quot;formatters&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n</span><span class=\"hll\">        <span class=\"s2\">&quot;verbose&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n</span><span class=\"hll\">            <span class=\"s2\">&quot;format&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;</span><span class=\"si\">{name}</span><span class=\"s2\"> </span><span class=\"si\">{levelname}</span><span class=\"s2\"> </span><span class=\"si\">{asctime}</span><span class=\"s2\"> </span><span class=\"si\">{module}</span><span class=\"s2\"> </span><span class=\"si\">{process:d}</span><span class=\"s2\"> </span><span class=\"si\">{thread:d}</span><span class=\"s2\"> </span><span class=\"si\">{message}</span><span class=\"s2\">&quot;</span><span class=\"p\">,</span>\n</span><span class=\"hll\">            <span class=\"s2\">&quot;style&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;{&quot;</span><span class=\"p\">,</span>\n</span><span class=\"hll\">        <span class=\"p\">},</span>\n</span><span class=\"hll\">        <span class=\"s2\">&quot;simple&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n</span><span class=\"hll\">            <span class=\"s2\">&quot;format&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;</span><span class=\"si\">{levelname}</span><span class=\"s2\"> </span><span class=\"si\">{message}</span><span class=\"s2\">&quot;</span><span class=\"p\">,</span>\n</span><span class=\"hll\">            <span class=\"s2\">&quot;style&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;{&quot;</span><span class=\"p\">,</span>\n</span><span class=\"hll\">        <span class=\"p\">},</span>\n</span><span class=\"hll\">    <span class=\"p\">},</span>\n</span><span class=\"p\">}</span>\n</code></pre></div>\n<p>The <code class=\"docutils literal notranslate\">style</code> keyword allows you to specify <code class=\"docutils literal notranslate\">{</code> for <a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str.format\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\">str.format()</code></a> or\n<code class=\"docutils literal notranslate\">$</code> for <a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#string.Template\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">string.Template</code></a> formatting; the default is <code class=\"docutils literal notranslate\">$</code>.</p>\n<p>See <a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.html#logrecord-attributes\" title=\"(in Python v3.14)\"><span>LogRecord attributes</span></a> for the <a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.html#logging.LogRecord\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">LogRecord</code></a> attributes\nyou can include.</p>\n<p>To apply a formatter to a handler, add a <code class=\"docutils literal notranslate\">formatter</code> entry to the handler’s\ndictionary referring to the formatter by name, for example:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"s2\">&quot;handlers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;file&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;logging.FileHandler&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;filename&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;general.log&quot;</span><span class=\"p\">,</span>\n<span class=\"hll\">        <span class=\"s2\">&quot;formatter&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;verbose&quot;</span><span class=\"p\">,</span>\n</span>    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n</section>\n<section id=\"use-logger-namespacing\">\n<span id=\"naming-loggers\"></span><h4>Use logger namespacing<a class=\"heading-anchor\" href=\"#use-logger-namespacing\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>The unnamed logging configuration <code class=\"docutils literal notranslate\">''</code> captures logs from any Python\napplication. A named logging configuration will capture logs only from loggers\nwith matching names.</p>\n<p>The namespace of a logger instance is defined using\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/logging.html#logging.getLogger\" title=\"(in Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\">getLogger()</code></a>. For example in <code class=\"docutils literal notranslate\">views.py</code> of <code class=\"docutils literal notranslate\">my_app</code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>logger <span class=\"o\">=</span> logging<span class=\"o\">.</span>getLogger<span class=\"p\">(</span><span class=\"vm\">__name__</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>will create a logger in the <code class=\"docutils literal notranslate\">my_app.views</code> namespace. <code class=\"docutils literal notranslate\">__name__</code> allows you\nto organize log messages according to their provenance within your project’s\napplications automatically. It also ensures that you will not experience name\ncollisions.</p>\n<p>A logger mapping named <code class=\"docutils literal notranslate\">my_app.views</code> will capture records from this logger:</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code>LOGGING <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"s2\">&quot;loggers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n<span class=\"hll\">        <span class=\"s2\">&quot;my_app.views&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"o\">...</span><span class=\"p\">},</span>\n</span>    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>A logger mapping named <code class=\"docutils literal notranslate\">my_app</code> will be more permissive, capturing records\nfrom loggers anywhere within the <code class=\"docutils literal notranslate\">my_app</code> namespace (including\n<code class=\"docutils literal notranslate\">my_app.views</code>, <code class=\"docutils literal notranslate\">my_app.utils</code>, and so on):</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code>LOGGING <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"s2\">&quot;loggers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n<span class=\"hll\">        <span class=\"s2\">&quot;my_app&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"o\">...</span><span class=\"p\">},</span>\n</span>    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>You can also define logger namespacing explicitly:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>logger <span class=\"o\">=</span> logging<span class=\"o\">.</span>getLogger<span class=\"p\">(</span><span class=\"s2\">&quot;project.payment&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>and set up logger mappings accordingly.</p>\n<section id=\"using-logger-hierarchies-and-propagation\">\n<span id=\"naming-loggers-hierarchy\"></span><h5>Using logger hierarchies and propagation<a class=\"heading-anchor\" href=\"#using-logger-hierarchies-and-propagation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h5>\n<p>Logger naming is <em>hierarchical</em>. <code class=\"docutils literal notranslate\">my_app</code> is the parent of <code class=\"docutils literal notranslate\">my_app.views</code>,\nwhich is the parent of <code class=\"docutils literal notranslate\">my_app.views.private</code>. Unless specified otherwise,\nlogger mappings will propagate the records they process to their parents - a\nrecord from a logger in the <code class=\"docutils literal notranslate\">my_app.views.private</code> namespace will be handled\nby a mapping for both <code class=\"docutils literal notranslate\">my_app</code> and <code class=\"docutils literal notranslate\">my_app.views</code>.</p>\n<p>To manage this behavior, set the propagation key on the mappings you define:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>LOGGING <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"s2\">&quot;loggers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;my_app&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"c1\"># ...</span>\n        <span class=\"p\">},</span>\n        <span class=\"s2\">&quot;my_app.views&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"c1\"># ...</span>\n        <span class=\"p\">},</span>\n        <span class=\"s2\">&quot;my_app.views.private&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"c1\"># ...</span>\n            <span class=\"s2\">&quot;propagate&quot;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">propagate</code> defaults to <code class=\"docutils literal notranslate\">True</code>. In this example, the logs from\n<code class=\"docutils literal notranslate\">my_app.views.private</code> will not be handled by the parent, but logs from\n<code class=\"docutils literal notranslate\">my_app.views</code> will.</p>\n</section>\n</section>\n</section>\n<section id=\"configure-responsive-logging\">\n<h3>Configure responsive logging<a class=\"heading-anchor\" href=\"#configure-responsive-logging\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Logging is most useful when it contains as much information as possible, but\nnot information that you don’t need - and how much you need depends upon what\nyou’re doing. When you’re debugging, you need a level of information that would\nbe excessive and unhelpful if you had to deal with it in production.</p>\n<p>You can configure logging to provide you with the level of detail you need,\nwhen you need it. Rather than manually change configuration to achieve this, a\nbetter way is to apply configuration automatically according to the\nenvironment.</p>\n<p>For example, you could set an environment variable <code class=\"docutils literal notranslate\">DJANGO_LOG_LEVEL</code>\nappropriately in your development and staging environments, and make use of it\nin a logger mapping thus:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"s2\">&quot;level&quot;</span><span class=\"p\">:</span> os<span class=\"o\">.</span>getenv<span class=\"p\">(</span><span class=\"s2\">&quot;DJANGO_LOG_LEVEL&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;WARNING&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>- so that unless the environment specifies a lower log level, this\nconfiguration will only forward records of severity <code class=\"docutils literal notranslate\">WARNING</code> and above to\nits handler.</p>\n<p>Other options in the configuration (such as the <code class=\"docutils literal notranslate\">level</code> or <code class=\"docutils literal notranslate\">formatter</code>\noption of handlers) can be similarly managed.</p>\n</section>\n</section>","rootId":"how-to-configure-and-use-logging","toc":[{"title":"Make a basic logging call","anchor":"make-a-basic-logging-call","children":[]},{"title":"Customize logging configuration","anchor":"customize-logging-configuration","children":[{"title":"Basic logging configuration","anchor":"basic-logging-configuration","children":[{"title":"Create a LOGGING dictionary","anchor":"create-a-logging-dictionary","children":[]},{"title":"Configure a handler","anchor":"configure-a-handler","children":[]},{"title":"Configure a logger mapping","anchor":"configure-a-logger-mapping","children":[]},{"title":"Configure a formatter","anchor":"configure-a-formatter","children":[]},{"title":"Use logger namespacing","anchor":"use-logger-namespacing","children":[{"title":"Using logger hierarchies and propagation","anchor":"using-logger-hierarchies-and-propagation","children":[]}]}]},{"title":"Configure responsive logging","anchor":"configure-responsive-logging","children":[]}]}],"breadcrumbs":[{"docname":"howto/index","title":"How-to guides","url":"/en/dev/howto/"}],"prev":{"docname":"howto/static-files/index","title":"How to manage static files (e.g. images, JavaScript, CSS)","url":"/en/dev/howto/static-files/"},"next":{"docname":"howto/error-reporting","title":"How to manage error reporting","url":"/en/dev/howto/error-reporting/"},"formats":{"html":"/en/dev/howto/logging/","markdown":"/en/dev/howto/logging.md","json":"/en/dev/howto/logging.json"},"source":"https://github.com/django/django/blob/main/docs/howto/logging.txt","official":"https://docs.djangoproject.com/en/dev/howto/logging/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0"],"inLocales":["en"]}