Repository: elastic/apm-agent-python

Issue:
Dropped spans that match configuration
**Describe the bug**: ...

**To Reproduce**

1. Switch from 6.7.2 to 6.8.0
2. Try to capture some async span with discardable property and EXIT_SPAN_MIN_DURATION != -1
3. any span goes to discarded

**Environment (please complete the following information)**
- APM Server version: 8.0.1
- Agent version: 6.8.0



The root of issue in 
```
    def report(self) -> None:
        if self.discardable and self.duration < self.transaction.config_exit_span_min_duration:
            self.transaction.track_dropped_span(self)
            self.transaction.dropped_spans += 1
        else:
            self.tracer.queue_func(SPAN, self.to_dict())
```

For span with duration 1ms
self.duration would be 0.01
self.transaction.config_exit_span_min_duration (default value 1ms) equals 1
So...


Discussion:

Resolving patch:
diff --git a/elasticapm/conf/__init__.py b/elasticapm/conf/__init__.py
--- a/elasticapm/conf/__init__.py
+++ b/elasticapm/conf/__init__.py
@@ -598,7 +598,7 @@ class Config(_ConfigBase):
     )
     exit_span_min_duration = _ConfigValue(
         "EXIT_SPAN_MIN_DURATION",
-        default=1,
+        default=0,
         validators=[duration_validator],
         type=float,
     )
diff --git a/elasticapm/traces.py b/elasticapm/traces.py
--- a/elasticapm/traces.py
+++ b/elasticapm/traces.py
@@ -657,7 +657,7 @@ def end(self, skip_frames: int = 0, duration: Optional[float] = None):
         p.child_ended(self)
 
     def report(self) -> None:
-        if self.discardable and self.duration < self.transaction.config_exit_span_min_duration:
+        if self.discardable and (self.duration * 1000) < self.transaction.config_exit_span_min_duration:
             self.transaction.track_dropped_span(self)
             self.transaction.dropped_spans += 1
         else:


Test patch:
diff --git a/tests/client/dropped_spans_tests.py b/tests/client/dropped_spans_tests.py
--- a/tests/client/dropped_spans_tests.py
+++ b/tests/client/dropped_spans_tests.py
@@ -124,11 +124,11 @@ def test_transaction_max_span_dropped_statistics_not_collected_for_incompatible_
 @pytest.mark.parametrize("elasticapm_client", [{"exit_span_min_duration": "1ms"}], indirect=True)
 def test_transaction_fast_exit_span(elasticapm_client):
     elasticapm_client.begin_transaction("test_type")
-    with elasticapm.capture_span(span_type="x", name="x", leaf=True, duration=2):  # not dropped, too long
+    with elasticapm.capture_span(span_type="x", name="x", leaf=True, duration=0.002):  # not dropped, too long
         pass
-    with elasticapm.capture_span(span_type="y", name="y", leaf=True, duration=0.1):  # dropped
+    with elasticapm.capture_span(span_type="y", name="y", leaf=True, duration=0.0001):  # dropped
         pass
-    with elasticapm.capture_span(span_type="z", name="z", leaf=False, duration=0.1):  # not dropped, not exit
+    with elasticapm.capture_span(span_type="z", name="z", leaf=False, duration=0.0001):  # not dropped, not exit
         pass
     elasticapm_client.end_transaction("foo", duration=2.2)
     transaction = elasticapm_client.events[constants.TRANSACTION][0]
@@ -139,6 +139,6 @@ def test_transaction_fast_exit_span(elasticapm_client):
     assert transaction["span_count"]["started"] == 3
     assert transaction["span_count"]["dropped"] == 1
     assert metrics[0]["span"]["type"] == "x"
-    assert metrics[0]["samples"]["span.self_time.sum.us"]["value"] == 2000000
+    assert metrics[0]["samples"]["span.self_time.sum.us"]["value"] == 2000
     assert metrics[1]["span"]["type"] == "y"
-    assert metrics[1]["samples"]["span.self_time.sum.us"]["value"] == 100000
+    assert metrics[1]["samples"]["span.self_time.sum.us"]["value"] == 100
diff --git a/tests/config/config_snapshotting_tests.py b/tests/config/config_snapshotting_tests.py
--- a/tests/config/config_snapshotting_tests.py
+++ b/tests/config/config_snapshotting_tests.py
@@ -115,7 +115,7 @@ def test_config_snapshotting_span_compression_drop_exit_span(elasticapm_client):
         span_subtype="b",
         span_action="c",
         extra={"destination": {"service": {"resource": "x"}}},
-        duration=5,
+        duration=0.005,
     ):
         pass
     elasticapm_client.end_transaction()