Repository: scrapy/scrapy

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.


Discussion:
@Gallaecio I would like to work on this. I am new to Scrapy, and not sure if it is necessary to be assigned the issue to work on it? Can you assign this to me?

Resolving patch:
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 @@ def crawled(self, request, response, spider):
             '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 crawled(self, request, response, spider):
         }
 
     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 scraped(self, item, response, spider):
         }
 
     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,


Test patch: