diff --git a/docs/installation.rst b/docs/installation.rst
index 88b7922aa..2529e3a05 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -91,3 +91,21 @@ decorator:
         # ...
         path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True))),
     ]
+
+Logging Errors
+--------------
+
+By default, when there is a GraphQL error because of client inputs , Django logs a very simple message
+with 4xx HTTP status code. If you would like to see more details, you can enable
+``ClientErrorLogMiddleware`` as follows:
+
+.. code:: python
+
+    # settings.py
+
+    MIDDLEWARE = [
+        "graphene_django.middlewares.ClientErrorLogMiddleware",
+        # ...
+    ]
+
+This middleware works when your endpoint is ``/graphql``.
diff --git a/graphene_django/middlewares.py b/graphene_django/middlewares.py
new file mode 100644
index 000000000..f914bf6d4
--- /dev/null
+++ b/graphene_django/middlewares.py
@@ -0,0 +1,39 @@
+import json
+import logging
+
+from django.utils.log import log_response
+
+logger = logging.getLogger("django.graphene")
+
+
+class ClientErrorLogMiddleware:
+    """
+    Logs graphql requests 4xx errors. (Except 401, 403)
+    """
+
+    def __init__(self, get_response):
+        self.get_response = get_response
+
+    def __call__(self, request):
+        response = self.get_response(request)
+
+        try:
+            if (
+                400 <= response.status_code < 500
+                and response.status_code not in (401, 403)
+                and "graphql" in request.path.lower()
+            ):
+                response_json = json.loads(response.content)
+
+                if "errors" in response_json:
+                    log_response(
+                        message=(
+                            f"Graphql Error: {response_json['errors']}\n"
+                            f"The Query is: {json.loads(request.body)}"
+                        ),
+                        response=response,
+                    )
+        except Exception:
+            logger.error(f"Error logging graphql error.", exc_info=True)
+
+        return response
diff --git a/graphene_django/tests/test_middlewares.py b/graphene_django/tests/test_middlewares.py
new file mode 100644
index 000000000..fb254a8cb
--- /dev/null
+++ b/graphene_django/tests/test_middlewares.py
@@ -0,0 +1,107 @@
+import json
+import logging
+import graphene
+import mock
+from django.http.response import HttpResponse
+from django.test import RequestFactory
+from graphene.test import Client
+
+from .models import Reporter
+from .. import DjangoObjectType
+from ..middlewares import ClientErrorLogMiddleware
+
+
+class ReporterType(DjangoObjectType):
+    class Meta:
+        model = Reporter
+        fields = "__all__"
+
+
+class Query(graphene.ObjectType):
+    reporter = graphene.Field(ReporterType)
+
+    def resolve_reporter(self, info, **args):
+        return Reporter.objects.first()
+
+
+def test_should_log_error(caplog):
+    Reporter.objects.create(last_name="ABA")
+
+    invalid_query = """
+        query ReporterQuery {
+          reporter {
+            invalidAttrName 
+          }
+        }
+    """
+
+    schema = graphene.Schema(query=Query)
+    client = Client(schema)
+    response = client.execute(invalid_query)
+
+    factory = RequestFactory()
+    request = factory.post(
+        "/graphql", data=json.dumps(invalid_query), content_type="application/json"
+    )
+
+    http_res = HttpResponse(json.dumps(response).encode(), status=400)
+
+    get_response = mock.MagicMock()
+    get_response.return_value = http_res
+
+    middleware = ClientErrorLogMiddleware(get_response)
+    middleware(request)
+
+    assert len(caplog.records) == 1
+    assert caplog.records[0] != "WARNING"
+    assert str(response["errors"]) in caplog.text
+    assert invalid_query in caplog.text
+
+
+def test_should_not_log_success(caplog):
+    Reporter.objects.create(last_name="ABA")
+
+    valid_query = """
+        query ReporterQuery {
+          reporter {
+            lastName
+          }
+        }
+    """
+
+    schema = graphene.Schema(query=Query)
+    client = Client(schema)
+    response = client.execute(valid_query)
+
+    factory = RequestFactory()
+    request = factory.post(
+        "/graphql", data=json.dumps(valid_query), content_type="application/json"
+    )
+
+    http_res = HttpResponse(json.dumps(response).encode(), status=200)
+
+    get_response = mock.MagicMock()
+    get_response.return_value = http_res
+
+    middleware = ClientErrorLogMiddleware(get_response)
+    middleware(request)
+
+    assert len(caplog.records) == 0
+
+
+def test_should_not_log_non_graphql_error(caplog):
+    factory = RequestFactory()
+    request = factory.post(
+        "/users", data=json.dumps({"name": "Mario"}), content_type="application/json"
+    )
+    http_res = HttpResponse(
+        json.dumps({"errors": ["Got to be Luigi"]}).encode(), status=400
+    )
+
+    get_response = mock.MagicMock()
+    get_response.return_value = http_res
+
+    middleware = ClientErrorLogMiddleware(get_response)
+    middleware(request)
+
+    assert len(caplog.records) == 0