diff --git a/eliot/_action.py b/eliot/_action.py
index b15c050..9549ca2 100644
--- a/eliot/_action.py
+++ b/eliot/_action.py
@@ -23,7 +23,7 @@ from pyrsistent import (
     pvector_field,
     pvector, )
 from boltons.funcutils import wraps
-from six import text_type as unicode, integer_types
+from six import text_type as unicode, integer_types, PY3
 
 from ._message import (
     Message,
@@ -896,12 +896,29 @@ def log_call(
                        include_result=include_result)
 
     if action_type is None:
-        action_type = wrapped_function.__name__
+        if PY3:
+            action_type = "{}.{}".format(wrapped_function.__module__,
+                                         wrapped_function.__qualname__)
+        else:
+            action_type = wrapped_function.__name__
+
+    if PY3 and include_args is not None:
+        from inspect import signature
+        sig = signature(wrapped_function)
+        if set(include_args) - set(sig.parameters):
+            raise ValueError(
+                ("include_args ({}) lists arguments not in the "
+                 "wrapped function").format(include_args)
+            )
 
     @wraps(wrapped_function)
     def logging_wrapper(*args, **kwargs):
         callargs = getcallargs(wrapped_function, *args, **kwargs)
 
+        # Remove self is it's included:
+        if "self" in callargs:
+            callargs.pop("self")
+
         # Filter arguments to log, if necessary:
         if include_args is not None:
             callargs = {k: callargs[k] for k in include_args}

Further improvements to log_call
* [x] Don't log `self` for now (or maybe just blow up when added to methods/classmethods?)
* [x] Log full path (__module__ + __qualname__?) on Python 3 at least
* [x] Construction-time error if include_args doesn't match actual args.
diff --git a/eliot/tests/test_action.py b/eliot/tests/test_action.py
index 86eb5e1..699a75e 100644
--- a/eliot/tests/test_action.py
+++ b/eliot/tests/test_action.py
@@ -5,7 +5,7 @@ Tests for L{eliot._action}.
 from __future__ import unicode_literals
 
 import pickle
-from unittest import TestCase
+from unittest import TestCase, skipIf
 from threading import Thread
 from warnings import catch_warnings, simplefilter
 
@@ -1655,6 +1655,9 @@ class LogCallTests(TestCase):
 
     def assert_logged(self, logger, action_type, expected_params, expected_result):
         """Assert that an action of given structure was logged."""
+        if six.PY2:
+            # On Python 2 we don't include the module or class:
+            action_type = action_type.split(".")[-1]
         [tree] = Parser.parse_stream(logger.messages)
         root = tree.root()
         self.assertEqual(root.action_type, action_type)
@@ -1676,7 +1679,7 @@ class LogCallTests(TestCase):
             return 4
 
         myfunc(2, 3)
-        self.assert_logged(logger, u"myfunc",
+        self.assert_logged(logger, self.id() + ".<locals>.myfunc",
                            {u"x": 2, u"y": 3}, 4)
 
     @capture_logging(None)
@@ -1712,7 +1715,7 @@ class LogCallTests(TestCase):
             return 4
 
         myfunc(2, y=5)
-        self.assert_logged(logger, u"myfunc",
+        self.assert_logged(logger, self.id() + ".<locals>.myfunc",
                            {u"x": 2, u"y": 5}, 4)
 
     @capture_logging(None)
@@ -1723,7 +1726,7 @@ class LogCallTests(TestCase):
             return 6
 
         myfunc(2)
-        self.assert_logged(logger, u"myfunc",
+        self.assert_logged(logger, self.id() + ".<locals>.myfunc",
                            {u"x": 2, u"y": 1}, 6)
 
     @capture_logging(None)
@@ -1734,7 +1737,7 @@ class LogCallTests(TestCase):
             return 6
 
         myfunc(2, 3, 4, a=1, b=2)
-        self.assert_logged(logger, u"myfunc",
+        self.assert_logged(logger, self.id() + ".<locals>.myfunc",
                            {u"x": 2, u"y": (3, 4), u"z": {u"a": 1, u"b": 2}},
                            6)
 
@@ -1746,7 +1749,16 @@ class LogCallTests(TestCase):
             return 6
 
         myfunc(2, 3, 4)
-        self.assert_logged(logger, u"myfunc", {u"x": 2, u"z": 4}, 6)
+        self.assert_logged(logger, self.id() + ".<locals>.myfunc",
+                           {u"x": 2, u"z": 4}, 6)
+
+    @skipIf(six.PY2, "Didn't bother implementing safety check on Python 2")
+    def test_wrong_whitelist_args(self):
+        """If C{include_args} doesn't match function, raise an exception."""
+        with self.assertRaises(ValueError):
+            @log_call(include_args=["a", "x", "y"])
+            def f(x, y):
+                pass
 
     @capture_logging(None)
     def test_no_result(self, logger):
@@ -1771,3 +1783,16 @@ class LogCallTests(TestCase):
             for_pickling,
             pickle.loads(pickle.dumps(for_pickling))
         )
+
+    @capture_logging(None)
+    def test_methods(self, logger):
+        """self is not logged."""
+        class C(object):
+            @log_call
+            def f(self, x):
+                pass
+
+        C().f(2)
+        self.assert_logged(logger, self.id() + u".<locals>.C.f", {u"x": 2}, None)
+
+

pip install -e .[dev]
parse_log_pytest
pytest
pytest
apt-get update apt-get install -y daemontools
3.7
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
attrs @ file:///croot/attrs_1668696182826/work
Babel==2.14.0
bleach==6.0.0
boltons==25.0.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
cffi==1.15.1
charset-normalizer==3.4.1
coverage==7.2.7
cryptography==44.0.2
docutils==0.17.1
-e git+https://github.com/itamarst/eliot.git@97cc338d97b26da5c79e06f795f9e933a1b63d4a#egg=eliot
exceptiongroup==1.2.2
flake8==5.0.4
flit_core @ file:///opt/conda/conda-bld/flit-core_1644941570762/work/source/flit_core
hypothesis==6.79.4
idna==3.10
imagesize==1.4.1
importlib-metadata==4.2.0
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
jaraco.classes==3.2.3
jeepney==0.9.0
Jinja2==3.1.6
keyring==23.9.3
markdown-it-py==2.2.0
MarkupSafe==2.1.5
mccabe==0.7.0
mdurl==0.1.2
more-itertools==9.1.0
packaging @ file:///croot/packaging_1671697413597/work
pkginfo==1.10.0
platformdirs==4.0.0
pluggy @ file:///tmp/build/80754af9/pluggy_1648042572264/work
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pycodestyle==2.9.1
pycparser==2.21
pyflakes==2.5.0
Pygments==2.17.2
pyrsistent==0.19.3
pytest==7.1.2
pytz==2025.2
readme-renderer==37.3
requests==2.31.0
requests-toolbelt==1.0.0
rfc3986==2.0.0
rich==13.8.1
SecretStorage==3.3.3
six==1.17.0
snowballstemmer==2.2.0
sortedcontainers==2.4.0
Sphinx==4.3.2
sphinx-rtd-theme==1.3.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
testtools==2.7.1
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
twine==4.0.2
typing_extensions==4.7.1
urllib3==2.0.7
webencodings==0.5.1
yapf==0.43.0
zipp @ file:///croot/zipp_1672387121353/work
zope.interface==6.4.post2

name: eliot
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=22.1.0=py37h06a4308_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - flit-core=3.6.0=pyhd3eb1b0_0
  - importlib_metadata=4.11.3=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=22.0=py37h06a4308_0
  - pip=22.3.1=py37h06a4308_0
  - pluggy=1.0.0=py37h06a4308_1
  - py=1.11.0=pyhd3eb1b0_0
  - pytest=7.1.2=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py37h06a4308_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.11.0=py37h06a4308_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - babel==2.14.0
      - bleach==6.0.0
      - boltons==25.0.0
      - cffi==1.15.1
      - charset-normalizer==3.4.1
      - coverage==7.2.7
      - cryptography==44.0.2
      - docutils==0.17.1
      - exceptiongroup==1.2.2
      - flake8==5.0.4
      - hypothesis==6.79.4
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.2.0
      - jaraco-classes==3.2.3
      - jeepney==0.9.0
      - jinja2==3.1.6
      - keyring==23.9.3
      - markdown-it-py==2.2.0
      - markupsafe==2.1.5
      - mccabe==0.7.0
      - mdurl==0.1.2
      - more-itertools==9.1.0
      - pkginfo==1.10.0
      - platformdirs==4.0.0
      - pycodestyle==2.9.1
      - pycparser==2.21
      - pyflakes==2.5.0
      - pygments==2.17.2
      - pyrsistent==0.19.3
      - pytz==2025.2
      - readme-renderer==37.3
      - requests==2.31.0
      - requests-toolbelt==1.0.0
      - rfc3986==2.0.0
      - rich==13.8.1
      - secretstorage==3.3.3
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sortedcontainers==2.4.0
      - sphinx==4.3.2
      - sphinx-rtd-theme==1.3.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - testtools==2.7.1
      - twine==4.0.2
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - webencodings==0.5.1
      - yapf==0.43.0
      - zope-interface==6.4.post2
prefix: /opt/conda/envs/eliot

eliot/tests/test_action.py::LogCallTests::test_default_argument_given eliot/tests/test_action.py::LogCallTests::test_default_argument_missing eliot/tests/test_action.py::LogCallTests::test_methods eliot/tests/test_action.py::LogCallTests::test_no_args_return eliot/tests/test_action.py::LogCallTests::test_star_args_kwargs eliot/tests/test_action.py::LogCallTests::test_whitelist_args eliot/tests/test_action.py::LogCallTests::test_wrong_whitelist_args
eliot/tests/test_action.py::ExecutionContextTests::test_globalInstance eliot/tests/test_action.py::ExecutionContextTests::test_multipleCurrent eliot/tests/test_action.py::ExecutionContextTests::test_nothingPushed eliot/tests/test_action.py::ExecutionContextTests::test_popMultiple eliot/tests/test_action.py::ExecutionContextTests::test_popSingle eliot/tests/test_action.py::ExecutionContextTests::test_pushMultiple eliot/tests/test_action.py::ExecutionContextTests::test_pushSingle eliot/tests/test_action.py::ExecutionContextTests::test_threadSafety eliot/tests/test_action.py::ExecutionContextTests::test_threadStart eliot/tests/test_action.py::ActionTests::test_addSuccessFields eliot/tests/test_action.py::ActionTests::test_child eliot/tests/test_action.py::ActionTests::test_childLevel eliot/tests/test_action.py::ActionTests::test_childSerializers eliot/tests/test_action.py::ActionTests::test_failureFinishSerializer eliot/tests/test_action.py::ActionTests::test_finish eliot/tests/test_action.py::ActionTests::test_finishWithBadException eliot/tests/test_action.py::ActionTests::test_multipleFinishCalls eliot/tests/test_action.py::ActionTests::test_nextTaskLevel eliot/tests/test_action.py::ActionTests::test_run eliot/tests/test_action.py::ActionTests::test_runContext eliot/tests/test_action.py::ActionTests::test_runContextUnsetOnRaise eliot/tests/test_action.py::ActionTests::test_runContextUnsetOnReturn eliot/tests/test_action.py::ActionTests::test_start eliot/tests/test_action.py::ActionTests::test_startFieldsNotInFinish eliot/tests/test_action.py::ActionTests::test_startMessageSerialization eliot/tests/test_action.py::ActionTests::test_stringActionCompatibility eliot/tests/test_action.py::ActionTests::test_stringActionCompatibilityWarning eliot/tests/test_action.py::ActionTests::test_successfulFinishSerializer eliot/tests/test_action.py::ActionTests::test_task_uuid eliot/tests/test_action.py::ActionTests::test_withContextNoLogging eliot/tests/test_action.py::ActionTests::test_withContextReturnsaction eliot/tests/test_action.py::ActionTests::test_withContextSetsContext eliot/tests/test_action.py::ActionTests::test_withContextUnsetOnRaise eliot/tests/test_action.py::ActionTests::test_withContextUnsetOnReturn eliot/tests/test_action.py::ActionTests::test_withLogsExceptionMessage eliot/tests/test_action.py::ActionTests::test_withLogsSuccessfulFinishMessage eliot/tests/test_action.py::ActionTests::test_withReturnValue eliot/tests/test_action.py::ActionTests::test_withSetsContext eliot/tests/test_action.py::ActionTests::test_withUnsetOnRaise eliot/tests/test_action.py::ActionTests::test_withUnsetOnReturn eliot/tests/test_action.py::StartActionAndTaskTests::test_startActionNoLogger eliot/tests/test_action.py::StartActionAndTaskTests::test_startActionNoParent eliot/tests/test_action.py::StartActionAndTaskTests::test_startActionNoParentLogStart eliot/tests/test_action.py::StartActionAndTaskTests::test_startActionSerializers eliot/tests/test_action.py::StartActionAndTaskTests::test_startActionWithParent eliot/tests/test_action.py::StartActionAndTaskTests::test_startActionWithParentLogStart eliot/tests/test_action.py::StartActionAndTaskTests::test_startTaskLogsStart eliot/tests/test_action.py::StartActionAndTaskTests::test_startTaskNewAction eliot/tests/test_action.py::StartActionAndTaskTests::test_startTaskNewUUID eliot/tests/test_action.py::StartActionAndTaskTests::test_startTaskNoLogger eliot/tests/test_action.py::StartActionAndTaskTests::test_startTaskSerializers eliot/tests/test_action.py::StartActionAndTaskTests::test_start_action_default_action_type eliot/tests/test_action.py::StartActionAndTaskTests::test_start_task_default_action_type eliot/tests/test_action.py::PEP8Tests::test_add_success_fields eliot/tests/test_action.py::PEP8Tests::test_continue_task eliot/tests/test_action.py::PEP8Tests::test_serialize_task_id eliot/tests/test_action.py::SerializationTests::test_continueTaskNoLogger eliot/tests/test_action.py::SerializationTests::test_continueTaskRequiredTaskId eliot/tests/test_action.py::SerializationTests::test_continueTaskReturnsAction eliot/tests/test_action.py::SerializationTests::test_continueTaskStartsAction eliot/tests/test_action.py::SerializationTests::test_continueTaskUnicode eliot/tests/test_action.py::SerializationTests::test_serializeTaskId eliot/tests/test_action.py::TaskLevelTests::test_child_greater_than_parent eliot/tests/test_action.py::TaskLevelTests::test_fromString eliot/tests/test_action.py::TaskLevelTests::test_from_string eliot/tests/test_action.py::TaskLevelTests::test_next_sibling eliot/tests/test_action.py::TaskLevelTests::test_next_sibling_greater eliot/tests/test_action.py::TaskLevelTests::test_parent_of_child eliot/tests/test_action.py::TaskLevelTests::test_parent_of_root eliot/tests/test_action.py::TaskLevelTests::test_toString eliot/tests/test_action.py::TaskLevelTests::test_to_string eliot/tests/test_action.py::WrittenActionTests::test_action_type_mismatch eliot/tests/test_action.py::WrittenActionTests::test_children eliot/tests/test_action.py::WrittenActionTests::test_different_task_uuid eliot/tests/test_action.py::WrittenActionTests::test_duplicate_task_level eliot/tests/test_action.py::WrittenActionTests::test_end_has_no_status eliot/tests/test_action.py::WrittenActionTests::test_failed_end eliot/tests/test_action.py::WrittenActionTests::test_from_single_child_message eliot/tests/test_action.py::WrittenActionTests::test_from_single_end_message eliot/tests/test_action.py::WrittenActionTests::test_from_single_start_message eliot/tests/test_action.py::WrittenActionTests::test_invalid_start_message_missing_status eliot/tests/test_action.py::WrittenActionTests::test_invalid_start_message_wrong_status eliot/tests/test_action.py::WrittenActionTests::test_invalid_task_level_in_start_message eliot/tests/test_action.py::WrittenActionTests::test_successful_end eliot/tests/test_action.py::WrittenActionTests::test_wrong_task_level eliot/tests/test_action.py::WrittenActionTests::test_wrong_task_uuid eliot/tests/test_action.py::FailedActionExtractionTests::test_environmenterror eliot/tests/test_action.py::FailedActionExtractionTests::test_error_in_extracter eliot/tests/test_action.py::FailedActionExtractionTests::test_matching_class eliot/tests/test_action.py::FailedActionExtractionTests::test_regular_fields eliot/tests/test_action.py::FailedActionExtractionTests::test_subclass_falls_back_to_parent eliot/tests/test_action.py::FailedActionExtractionTests::test_subclass_matches_first eliot/tests/test_action.py::PreserveContextTests::test_callable_only_once eliot/tests/test_action.py::PreserveContextTests::test_no_context eliot/tests/test_action.py::PreserveContextTests::test_with_context_calls_underlying eliot/tests/test_action.py::PreserveContextTests::test_with_context_preserves_context eliot/tests/test_action.py::LogCallTests::test_action_type eliot/tests/test_action.py::LogCallTests::test_exception eliot/tests/test_action.py::LogCallTests::test_no_result eliot/tests/test_action.py::LogCallTests::test_pickleable
eliot/_action.py
eliot/_action.py