Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Commit a293c92

Browse files
authored
Override sampling decision (#639)
Pass span context to samplers to allow them override the "enabled" flag.
1 parent e2fa221 commit a293c92

36 files changed

Lines changed: 299 additions & 274 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
## Unreleased
44
- Refactored PeriodicTask
55
([#632](https://github.com/census-instrumentation/opencensus-python/pull/632))
6+
- Make ProbabilitySampler default, change default sampling rate
7+
- Pass span context to samplers, allow samplers to override parent sampling
8+
decision
69

710
## 0.5.0
811
Released 2019-04-24

README.rst

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ Installation & basic usage
4141

4242
.. code:: python
4343
44-
from opencensus.trace import tracer as tracer_module
44+
from opencensus.trace.tracer import Tracer
45+
from opencensus.trace.samplers import AlwaysOnSampler
4546
46-
tracer = tracer_module.Tracer()
47+
tracer = Tracer(sampler=AlwaysOnSampler())
4748
4849
.. _pip: https://pip.pypa.io
4950
.. _pipenv: https://docs.pipenv.org/
@@ -66,10 +67,11 @@ You can collect traces using the ``Tracer`` `context manager`_:
6667

6768
.. code:: python
6869
69-
from opencensus.trace import tracer as tracer_module
70+
from opencensus.trace.tracer import Tracer
71+
from opencensus.trace.samplers import AlwaysOnSampler
7072
7173
# Initialize a tracer, by default using the `PrintExporter`
72-
tracer = tracer_module.Tracer()
74+
tracer = Tracer(sampler=AlwaysOnSampler())
7375
7476
# Example for creating nested spans
7577
with tracer.span(name='span1') as span1:
@@ -87,10 +89,11 @@ Alternatively, you can explicitly start and end a span:
8789

8890
.. code:: python
8991
90-
from opencensus.trace import tracer as tracer_module
92+
from opencensus.trace.tracer import Tracer
93+
from opencensus.trace.samplers import AlwaysOnSampler
9194
9295
# Initialize a tracer, by default using the `PrintExporter`
93-
tracer = tracer_module.Tracer()
96+
tracer = Tracer(sampler=AlwaysOnSampler())
9497
9598
tracer.start_span(name='span1')
9699
do_something_to_trace()
@@ -116,8 +119,11 @@ There are several things you can customize in OpenCensus:
116119
other exporters are provided as `extensions <#trace-exporter>`__.
117120

118121
* **Sampler**, which determines how traces are sampled.
119-
The default sampler is ``AlwaysOnSampler``, other samplers include the
120-
``AlwaysOffSampler`` and ``ProbabilitySampler``.
122+
The default sampler is the ``ProbabilitySampler``, which samples (i.e.
123+
enables tracing for) a percentage of all requests. Sampling is deterministic
124+
according to the trace ID. To force sampling for all requests, or to prevent
125+
any request from being sampled, see ``AlwaysOnSampler`` and
126+
``AlwaysOffSampler``.
121127

122128
* **Propagator**, which serializes and deserializes the
123129
``SpanContext`` and its headers. The default propagator is

contrib/opencensus-ext-django/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
## Unreleased
4+
- Make ProbabilitySampler default
45

56
## 0.3.0
67
Released 2019-04-24

contrib/opencensus-ext-django/opencensus/ext/django/middleware.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
from opencensus.trace import attributes_helper
2323
from opencensus.trace import execution_context
2424
from opencensus.trace import print_exporter
25+
from opencensus.trace import samplers
2526
from opencensus.trace import span as span_module
2627
from opencensus.trace import tracer as tracer_module
2728
from opencensus.trace import utils
2829
from opencensus.trace.propagation import trace_context_http_header_format
29-
from opencensus.trace.samplers import always_on
3030

3131
try:
3232
from django.utils.deprecation import MiddlewareMixin
@@ -113,8 +113,8 @@ def __init__(self, get_response=None):
113113
settings = getattr(django.conf.settings, 'OPENCENSUS', {})
114114
settings = settings.get('TRACE', {})
115115

116-
self.sampler = settings.get('SAMPLER', None) or \
117-
always_on.AlwaysOnSampler()
116+
self.sampler = (settings.get('SAMPLER', None)
117+
or samplers.ProbabilitySampler())
118118
if isinstance(self.sampler, six.string_types):
119119
self.sampler = configuration.load(self.sampler)
120120

contrib/opencensus-ext-django/tests/test_django_middleware.py

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020

2121
from opencensus.trace import execution_context
2222
from opencensus.trace import print_exporter
23+
from opencensus.trace import samplers
2324
from opencensus.trace import span as span_module
2425
from opencensus.trace import utils
2526
from opencensus.trace.blank_span import BlankSpan
2627
from opencensus.trace.propagation import trace_context_http_header_format
27-
from opencensus.trace.samplers import always_on
2828

2929

3030
class TestOpencensusMiddleware(unittest.TestCase):
@@ -46,7 +46,7 @@ def test_constructor_default(self):
4646

4747
middleware = middleware.OpencensusMiddleware()
4848

49-
assert isinstance(middleware.sampler, always_on.AlwaysOnSampler)
49+
assert isinstance(middleware.sampler, samplers.ProbabilitySampler)
5050
assert isinstance(middleware.exporter, print_exporter.PrintExporter)
5151
assert isinstance(
5252
middleware.propagator,
@@ -59,7 +59,7 @@ def test_configuration(self):
5959
settings = type('Test', (object,), {})
6060
settings.OPENCENSUS = {
6161
'TRACE': {
62-
'SAMPLER': 'opencensus.trace.samplers.always_on.AlwaysOnSampler()', # noqa
62+
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
6363
'EXPORTER': 'opencensus.trace.print_exporter.PrintExporter()', # noqa
6464
'PROPAGATOR': 'opencensus.trace.propagation.trace_context_http_header_format.TraceContextPropagator()', # noqa
6565
}
@@ -71,7 +71,7 @@ def test_configuration(self):
7171
with patch_settings:
7272
middleware = middleware.OpencensusMiddleware()
7373

74-
assert isinstance(middleware.sampler, always_on.AlwaysOnSampler)
74+
assert isinstance(middleware.sampler, samplers.AlwaysOnSampler)
7575
assert isinstance(middleware.exporter, print_exporter.PrintExporter)
7676
assert isinstance(
7777
middleware.propagator,
@@ -88,7 +88,19 @@ def test_process_request(self):
8888
django_request = RequestFactory().get('/', **{
8989
'HTTP_TRACEPARENT': django_trace_id})
9090

91-
middleware_obj = middleware.OpencensusMiddleware()
91+
# Force the test request to be sampled
92+
settings = type('Test', (object,), {})
93+
settings.OPENCENSUS = {
94+
'TRACE': {
95+
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
96+
}
97+
}
98+
patch_settings = mock.patch(
99+
'django.conf.settings',
100+
settings)
101+
102+
with patch_settings:
103+
middleware_obj = middleware.OpencensusMiddleware()
92104

93105
# test process_request
94106
middleware_obj.process_request(django_request)
@@ -123,6 +135,7 @@ def test_blacklist_path(self):
123135
settings = type('Test', (object,), {})
124136
settings.OPENCENSUS = {
125137
'TRACE': {
138+
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
126139
'BLACKLIST_PATHS': blacklist_paths,
127140
'EXPORTER': mock.Mock(),
128141
}
@@ -176,7 +189,19 @@ def test_process_response(self):
176189
'traceparent': django_trace_id,
177190
})
178191

179-
middleware_obj = middleware.OpencensusMiddleware()
192+
# Force the test request to be sampled
193+
settings = type('Test', (object,), {})
194+
settings.OPENCENSUS = {
195+
'TRACE': {
196+
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
197+
}
198+
}
199+
patch_settings = mock.patch(
200+
'django.conf.settings',
201+
settings)
202+
203+
with patch_settings:
204+
middleware_obj = middleware.OpencensusMiddleware()
180205

181206
middleware_obj.process_request(django_request)
182207
tracer = middleware._get_current_tracer()
@@ -216,7 +241,19 @@ def test_process_response_no_get_username(self):
216241
'traceparent': django_trace_id,
217242
})
218243

219-
middleware_obj = middleware.OpencensusMiddleware()
244+
# Force the test request to be sampled
245+
settings = type('Test', (object,), {})
246+
settings.OPENCENSUS = {
247+
'TRACE': {
248+
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
249+
}
250+
}
251+
patch_settings = mock.patch(
252+
'django.conf.settings',
253+
settings)
254+
255+
with patch_settings:
256+
middleware_obj = middleware.OpencensusMiddleware()
220257

221258
middleware_obj.process_request(django_request)
222259
tracer = middleware._get_current_tracer()
@@ -254,7 +291,19 @@ def test_process_response_unfinished_child_span(self):
254291
'traceparent': django_trace_id,
255292
})
256293

257-
middleware_obj = middleware.OpencensusMiddleware()
294+
# Force the test request to be sampled
295+
settings = type('Test', (object,), {})
296+
settings.OPENCENSUS = {
297+
'TRACE': {
298+
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
299+
}
300+
}
301+
patch_settings = mock.patch(
302+
'django.conf.settings',
303+
settings)
304+
305+
with patch_settings:
306+
middleware_obj = middleware.OpencensusMiddleware()
258307

259308
middleware_obj.process_request(django_request)
260309
tracer = middleware._get_current_tracer()

contrib/opencensus-ext-flask/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
## Unreleased
4+
- Make ProbabilitySampler default
45

56
## 0.3.0
67
Released 2019-04-24

contrib/opencensus-ext-flask/examples/custom.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
import requests
2222
import sqlalchemy
2323

24-
import hello_world_pb2
25-
import hello_world_pb2_grpc
2624
from opencensus.ext.flask.flask_middleware import FlaskMiddleware
2725
from opencensus.ext.grpc import client_interceptor
2826
from opencensus.ext.stackdriver import trace_exporter as stackdriver_exporter
2927
from opencensus.trace import config_integration
30-
from opencensus.trace.samplers import probability
28+
from opencensus.trace import samplers
29+
import hello_world_pb2
30+
import hello_world_pb2_grpc
3131

3232
INTEGRATIONS = ['mysql', 'postgresql', 'sqlalchemy', 'requests']
3333

@@ -48,7 +48,7 @@
4848

4949
# Enable tracing, configure the trace params, send traces to Stackdriver Trace
5050
exporter = stackdriver_exporter.StackdriverExporter()
51-
sampler = probability.ProbabilitySampler(rate=1)
51+
sampler = samplers.ProbabilitySampler(rate=1)
5252
middleware = FlaskMiddleware(app, exporter=exporter, sampler=sampler)
5353
config_integration.trace_integrations(INTEGRATIONS)
5454

contrib/opencensus-ext-flask/opencensus/ext/flask/flask_middleware.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
from opencensus.trace import attributes_helper
2424
from opencensus.trace import execution_context
2525
from opencensus.trace import print_exporter
26+
from opencensus.trace import samplers
2627
from opencensus.trace import span as span_module
2728
from opencensus.trace import stack_trace
2829
from opencensus.trace import status
2930
from opencensus.trace import tracer as tracer_module
3031
from opencensus.trace import utils
3132
from opencensus.trace.propagation import trace_context_http_header_format
32-
from opencensus.trace.samplers import always_on
3333

3434
HTTP_METHOD = attributes_helper.COMMON_ATTRIBUTES['HTTP_METHOD']
3535
HTTP_URL = attributes_helper.COMMON_ATTRIBUTES['HTTP_URL']
@@ -54,8 +54,8 @@ class FlaskMiddleware(object):
5454
:param sampler: A sampler. It should extend from the base
5555
:class:`.Sampler` type and implement
5656
:meth:`.Sampler.should_sample`. Defaults to
57-
:class:`.AlwaysOnSampler`. The rest options are
58-
:class:`.AlwaysOffSampler`, :class:`.FixedRateSampler`.
57+
:class:`.ProbabilitySampler`. Other options include
58+
:class:`.AlwaysOnSampler` and :class:`.AlwaysOffSampler`.
5959
6060
:type exporter: :class:`~opencensus.trace.base_exporter.exporter`
6161
:param exporter: An exporter. Default to
@@ -90,8 +90,8 @@ def init_app(self, app):
9090
settings = settings.get('TRACE', {})
9191

9292
if self.sampler is None:
93-
self.sampler = settings.get('SAMPLER', None) or \
94-
always_on.AlwaysOnSampler()
93+
self.sampler = (settings.get('SAMPLER', None)
94+
or samplers.ProbabilitySampler())
9595
if isinstance(self.sampler, six.string_types):
9696
self.sampler = configuration.load(self.sampler)
9797

0 commit comments

Comments
 (0)