We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Document LogFormatter
Currently, the `LogFormatter` class is only mentioned in the [Release notes](https://docs.scrapy.org/en/latest/news.html) page of the documentation. This class should be properly documented, both its API members and a small section introducing it on the documentation page about [Logging](https://docs.scrapy.org/en/latest/topics/logging.html).

The responses to [Scrapy - Silently drop an item](https://stackoverflow.com/q/13527921/939364) in StackOverflow would be a good starting point.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scrapy/logformatter.py`
Content:
```
1 import os
2 import logging
3 
4 from twisted.python.failure import Failure
5 
6 from scrapy.utils.request import referer_str
7 
8 SCRAPEDMSG = u"Scraped from %(src)s" + os.linesep + "%(item)s"
9 DROPPEDMSG = u"Dropped: %(exception)s" + os.linesep + "%(item)s"
10 CRAWLEDMSG = u"Crawled (%(status)s) %(request)s%(request_flags)s (referer: %(referer)s)%(response_flags)s"
11 
12 
13 class LogFormatter(object):
14     """Class for generating log messages for different actions.
15 
16     All methods must return a dictionary listing the parameters ``level``,
17     ``msg`` and ``args`` which are going to be used for constructing the log
18     message when calling logging.log.
19 
20     Dictionary keys for the method outputs:
21         * ``level`` should be the log level for that action, you can use those
22         from the python logging library: logging.DEBUG, logging.INFO,
23         logging.WARNING, logging.ERROR and logging.CRITICAL.
24 
25         * ``msg`` should be a string that can contain different formatting
26         placeholders. This string, formatted with the provided ``args``, is
27         going to be the log message for that action.
28 
29         * ``args`` should be a tuple or dict with the formatting placeholders
30         for ``msg``.  The final log message is computed as output['msg'] %
31         output['args'].
32     """
33 
34     def crawled(self, request, response, spider):
35         request_flags = ' %s' % str(request.flags) if request.flags else ''
36         response_flags = ' %s' % str(response.flags) if response.flags else ''
37         return {
38             'level': logging.DEBUG,
39             'msg': CRAWLEDMSG,
40             'args': {
41                 'status': response.status,
42                 'request': request,
43                 'request_flags' : request_flags,
44                 'referer': referer_str(request),
45                 'response_flags': response_flags,
46                 # backward compatibility with Scrapy logformatter below 1.4 version
47                 'flags': response_flags
48             }
49         }
50 
51     def scraped(self, item, response, spider):
52         if isinstance(response, Failure):
53             src = response.getErrorMessage()
54         else:
55             src = response
56         return {
57             'level': logging.DEBUG,
58             'msg': SCRAPEDMSG,
59             'args': {
60                 'src': src,
61                 'item': item,
62             }
63         }
64 
65     def dropped(self, item, exception, response, spider):
66         return {
67             'level': logging.WARNING,
68             'msg': DROPPEDMSG,
69             'args': {
70                 'exception': exception,
71                 'item': item,
72             }
73         }
74 
75     @classmethod
76     def from_crawler(cls, crawler):
77         return cls()
78
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/scrapy/logformatter.py b/scrapy/logformatter.py
--- a/scrapy/logformatter.py
+++ b/scrapy/logformatter.py
@@ -12,26 +12,40 @@
 
 class LogFormatter(object):
     """Class for generating log messages for different actions.
-
-    All methods must return a dictionary listing the parameters ``level``,
-    ``msg`` and ``args`` which are going to be used for constructing the log
-    message when calling logging.log.
+    
+    All methods must return a dictionary listing the parameters ``level``, ``msg``
+    and ``args`` which are going to be used for constructing the log message when
+    calling ``logging.log``.
 
     Dictionary keys for the method outputs:
-        * ``level`` should be the log level for that action, you can use those
-        from the python logging library: logging.DEBUG, logging.INFO,
-        logging.WARNING, logging.ERROR and logging.CRITICAL.
 
-        * ``msg`` should be a string that can contain different formatting
-        placeholders. This string, formatted with the provided ``args``, is
-        going to be the log message for that action.
+    *   ``level`` is the log level for that action, you can use those from the
+        `python logging library <https://docs.python.org/3/library/logging.html>`_ :
+        ``logging.DEBUG``, ``logging.INFO``, ``logging.WARNING``, ``logging.ERROR``
+        and ``logging.CRITICAL``.
+    *   ``msg`` should be a string that can contain different formatting placeholders.
+        This string, formatted with the provided ``args``, is going to be the long message
+        for that action.
+    *   ``args`` should be a tuple or dict with the formatting placeholders for ``msg``.
+        The final log message is computed as ``msg % args``.
 
-        * ``args`` should be a tuple or dict with the formatting placeholders
-        for ``msg``.  The final log message is computed as output['msg'] %
-        output['args'].
-    """
+    Here is an example on how to create a custom log formatter to lower the severity level of
+    the log message when an item is dropped from the pipeline::
 
+            class PoliteLogFormatter(logformatter.LogFormatter):
+                def dropped(self, item, exception, response, spider):
+                    return {
+                        'level': logging.INFO, # lowering the level from logging.WARNING
+                        'msg': u"Dropped: %(exception)s" + os.linesep + "%(item)s",
+                        'args': {
+                            'exception': exception,
+                            'item': item,
+                        }
+                    }
+    """
+    
     def crawled(self, request, response, spider):
+        """Logs a message when the crawler finds a webpage."""
         request_flags = ' %s' % str(request.flags) if request.flags else ''
         response_flags = ' %s' % str(response.flags) if response.flags else ''
         return {
@@ -40,7 +54,7 @@
             'args': {
                 'status': response.status,
                 'request': request,
-                'request_flags' : request_flags,
+                'request_flags': request_flags,
                 'referer': referer_str(request),
                 'response_flags': response_flags,
                 # backward compatibility with Scrapy logformatter below 1.4 version
@@ -49,6 +63,7 @@
         }
 
     def scraped(self, item, response, spider):
+        """Logs a message when an item is scraped by a spider."""
         if isinstance(response, Failure):
             src = response.getErrorMessage()
         else:
@@ -63,6 +78,7 @@
         }
 
     def dropped(self, item, exception, response, spider):
+        """Logs a message when an item is dropped while it is passing through the item pipeline."""
         return {
             'level': logging.WARNING,
             'msg': DROPPEDMSG,

{"golden_diff": "diff --git a/scrapy/logformatter.py b/scrapy/logformatter.py\n--- a/scrapy/logformatter.py\n+++ b/scrapy/logformatter.py\n@@ -12,26 +12,40 @@\n \n class LogFormatter(object):\n     \"\"\"Class for generating log messages for different actions.\n-\n-    All methods must return a dictionary listing the parameters ``level``,\n-    ``msg`` and ``args`` which are going to be used for constructing the log\n-    message when calling logging.log.\n+    \n+    All methods must return a dictionary listing the parameters ``level``, ``msg``\n+    and ``args`` which are going to be used for constructing the log message when\n+    calling ``logging.log``.\n \n     Dictionary keys for the method outputs:\n-        * ``level`` should be the log level for that action, you can use those\n-        from the python logging library: logging.DEBUG, logging.INFO,\n-        logging.WARNING, logging.ERROR and logging.CRITICAL.\n \n-        * ``msg`` should be a string that can contain different formatting\n-        placeholders. This string, formatted with the provided ``args``, is\n-        going to be the log message for that action.\n+    *   ``level`` is the log level for that action, you can use those from the\n+        `python logging library <https://docs.python.org/3/library/logging.html>`_ :\n+        ``logging.DEBUG``, ``logging.INFO``, ``logging.WARNING``, ``logging.ERROR``\n+        and ``logging.CRITICAL``.\n+    *   ``msg`` should be a string that can contain different formatting placeholders.\n+        This string, formatted with the provided ``args``, is going to be the long message\n+        for that action.\n+    *   ``args`` should be a tuple or dict with the formatting placeholders for ``msg``.\n+        The final log message is computed as ``msg % args``.\n \n-        * ``args`` should be a tuple or dict with the formatting placeholders\n-        for ``msg``.  The final log message is computed as output['msg'] %\n-        output['args'].\n-    \"\"\"\n+    Here is an example on how to create a custom log formatter to lower the severity level of\n+    the log message when an item is dropped from the pipeline::\n \n+            class PoliteLogFormatter(logformatter.LogFormatter):\n+                def dropped(self, item, exception, response, spider):\n+                    return {\n+                        'level': logging.INFO, # lowering the level from logging.WARNING\n+                        'msg': u\"Dropped: %(exception)s\" + os.linesep + \"%(item)s\",\n+                        'args': {\n+                            'exception': exception,\n+                            'item': item,\n+                        }\n+                    }\n+    \"\"\"\n+    \n     def crawled(self, request, response, spider):\n+        \"\"\"Logs a message when the crawler finds a webpage.\"\"\"\n         request_flags = ' %s' % str(request.flags) if request.flags else ''\n         response_flags = ' %s' % str(response.flags) if response.flags else ''\n         return {\n@@ -40,7 +54,7 @@\n             'args': {\n                 'status': response.status,\n                 'request': request,\n-                'request_flags' : request_flags,\n+                'request_flags': request_flags,\n                 'referer': referer_str(request),\n                 'response_flags': response_flags,\n                 # backward compatibility with Scrapy logformatter below 1.4 version\n@@ -49,6 +63,7 @@\n         }\n \n     def scraped(self, item, response, spider):\n+        \"\"\"Logs a message when an item is scraped by a spider.\"\"\"\n         if isinstance(response, Failure):\n             src = response.getErrorMessage()\n         else:\n@@ -63,6 +78,7 @@\n         }\n \n     def dropped(self, item, exception, response, spider):\n+        \"\"\"Logs a message when an item is dropped while it is passing through the item pipeline.\"\"\"\n         return {\n             'level': logging.WARNING,\n             'msg': DROPPEDMSG,\n", "issue": "Document LogFormatter\nCurrently, the `LogFormatter` class is only mentioned in the [Release notes](https://docs.scrapy.org/en/latest/news.html) page of the documentation. This class should be properly documented, both its API members and a small section introducing it on the documentation page about [Logging](https://docs.scrapy.org/en/latest/topics/logging.html).\r\n\r\nThe responses to [Scrapy - Silently drop an item](https://stackoverflow.com/q/13527921/939364) in StackOverflow would be a good starting point.\n", "before_files": [{"content": "import os\nimport logging\n\nfrom twisted.python.failure import Failure\n\nfrom scrapy.utils.request import referer_str\n\nSCRAPEDMSG = u\"Scraped from %(src)s\" + os.linesep + \"%(item)s\"\nDROPPEDMSG = u\"Dropped: %(exception)s\" + os.linesep + \"%(item)s\"\nCRAWLEDMSG = u\"Crawled (%(status)s) %(request)s%(request_flags)s (referer: %(referer)s)%(response_flags)s\"\n\n\nclass LogFormatter(object):\n    \"\"\"Class for generating log messages for different actions.\n\n    All methods must return a dictionary listing the parameters ``level``,\n    ``msg`` and ``args`` which are going to be used for constructing the log\n    message when calling logging.log.\n\n    Dictionary keys for the method outputs:\n        * ``level`` should be the log level for that action, you can use those\n        from the python logging library: logging.DEBUG, logging.INFO,\n        logging.WARNING, logging.ERROR and logging.CRITICAL.\n\n        * ``msg`` should be a string that can contain different formatting\n        placeholders. This string, formatted with the provided ``args``, is\n        going to be the log message for that action.\n\n        * ``args`` should be a tuple or dict with the formatting placeholders\n        for ``msg``.  The final log message is computed as output['msg'] %\n        output['args'].\n    \"\"\"\n\n    def crawled(self, request, response, spider):\n        request_flags = ' %s' % str(request.flags) if request.flags else ''\n        response_flags = ' %s' % str(response.flags) if response.flags else ''\n        return {\n            'level': logging.DEBUG,\n            'msg': CRAWLEDMSG,\n            'args': {\n                'status': response.status,\n                'request': request,\n                'request_flags' : request_flags,\n                'referer': referer_str(request),\n                'response_flags': response_flags,\n                # backward compatibility with Scrapy logformatter below 1.4 version\n                'flags': response_flags\n            }\n        }\n\n    def scraped(self, item, response, spider):\n        if isinstance(response, Failure):\n            src = response.getErrorMessage()\n        else:\n            src = response\n        return {\n            'level': logging.DEBUG,\n            'msg': SCRAPEDMSG,\n            'args': {\n                'src': src,\n                'item': item,\n            }\n        }\n\n    def dropped(self, item, exception, response, spider):\n        return {\n            'level': logging.WARNING,\n            'msg': DROPPEDMSG,\n            'args': {\n                'exception': exception,\n                'item': item,\n            }\n        }\n\n    @classmethod\n    def from_crawler(cls, crawler):\n        return cls()\n", "path": "scrapy/logformatter.py"}], "after_files": [{"content": "import os\nimport logging\n\nfrom twisted.python.failure import Failure\n\nfrom scrapy.utils.request import referer_str\n\nSCRAPEDMSG = u\"Scraped from %(src)s\" + os.linesep + \"%(item)s\"\nDROPPEDMSG = u\"Dropped: %(exception)s\" + os.linesep + \"%(item)s\"\nCRAWLEDMSG = u\"Crawled (%(status)s) %(request)s%(request_flags)s (referer: %(referer)s)%(response_flags)s\"\n\n\nclass LogFormatter(object):\n    \"\"\"Class for generating log messages for different actions.\n    \n    All methods must return a dictionary listing the parameters ``level``, ``msg``\n    and ``args`` which are going to be used for constructing the log message when\n    calling ``logging.log``.\n\n    Dictionary keys for the method outputs:\n\n    *   ``level`` is the log level for that action, you can use those from the\n        `python logging library <https://docs.python.org/3/library/logging.html>`_ :\n        ``logging.DEBUG``, ``logging.INFO``, ``logging.WARNING``, ``logging.ERROR``\n        and ``logging.CRITICAL``.\n    *   ``msg`` should be a string that can contain different formatting placeholders.\n        This string, formatted with the provided ``args``, is going to be the long message\n        for that action.\n    *   ``args`` should be a tuple or dict with the formatting placeholders for ``msg``.\n        The final log message is computed as ``msg % args``.\n\n    Here is an example on how to create a custom log formatter to lower the severity level of\n    the log message when an item is dropped from the pipeline::\n\n            class PoliteLogFormatter(logformatter.LogFormatter):\n                def dropped(self, item, exception, response, spider):\n                    return {\n                        'level': logging.INFO, # lowering the level from logging.WARNING\n                        'msg': u\"Dropped: %(exception)s\" + os.linesep + \"%(item)s\",\n                        'args': {\n                            'exception': exception,\n                            'item': item,\n                        }\n                    }\n    \"\"\"\n    \n    def crawled(self, request, response, spider):\n        \"\"\"Logs a message when the crawler finds a webpage.\"\"\"\n        request_flags = ' %s' % str(request.flags) if request.flags else ''\n        response_flags = ' %s' % str(response.flags) if response.flags else ''\n        return {\n            'level': logging.DEBUG,\n            'msg': CRAWLEDMSG,\n            'args': {\n                'status': response.status,\n                'request': request,\n                'request_flags': request_flags,\n                'referer': referer_str(request),\n                'response_flags': response_flags,\n                # backward compatibility with Scrapy logformatter below 1.4 version\n                'flags': response_flags\n            }\n        }\n\n    def scraped(self, item, response, spider):\n        \"\"\"Logs a message when an item is scraped by a spider.\"\"\"\n        if isinstance(response, Failure):\n            src = response.getErrorMessage()\n        else:\n            src = response\n        return {\n            'level': logging.DEBUG,\n            'msg': SCRAPEDMSG,\n            'args': {\n                'src': src,\n                'item': item,\n            }\n        }\n\n    def dropped(self, item, exception, response, spider):\n        \"\"\"Logs a message when an item is dropped while it is passing through the item pipeline.\"\"\"\n        return {\n            'level': logging.WARNING,\n            'msg': DROPPEDMSG,\n            'args': {\n                'exception': exception,\n                'item': item,\n            }\n        }\n\n    @classmethod\n    def from_crawler(cls, crawler):\n        return cls()\n", "path": "scrapy/logformatter.py"}]}